Building units now uses orders 😃

This commit is contained in:
2021-01-01 14:25:44 -06:00
parent 74458dbfd0
commit 5f301337b4
35 changed files with 171 additions and 100 deletions

Binary file not shown.

View File

@@ -0,0 +1,2 @@
# Music Source
* EmptyCity - CC0 - yd - https://opengameart.org/content/emptycity-background-music

View File

@@ -70,9 +70,9 @@ class IMICRTS
def visible?(object)
if object.is_a?(Map::Tile)
object.position.x - object.size >= @viewport.min.x - @position.x &&
object.position.y - object.size >= @viewport.min.y - @position.y &&
object.position.x <= @viewport.max.x - @position.x &&
object.position.y <= @viewport.max.y - @position.y
object.position.y - object.size >= @viewport.min.y - @position.y &&
object.position.x <= @viewport.max.x - @position.x &&
object.position.y <= @viewport.max.y - @position.y
else
pp object.class
exit

View File

@@ -1,5 +1,7 @@
class IMICRTS
class Component
include CyberarmEngine::Common
@@components = {}
def self.get(name)

View File

@@ -2,13 +2,13 @@ class IMICRTS
class BuildQueue < Component
attr_reader :queue
Item = Struct.new(:entity, :progress)
Item = Struct.new(:entity, :progress, :completed)
def setup
@queue = []
end
def add(type)
@queue << Item.new(Entity.get(type), 0.0)
@queue << Item.new(Entity.get(type), 0.0, false)
end
end
end

View File

@@ -2,7 +2,7 @@ class IMICRTS
class Building < Component
def setup
data.construction_progress ||= 0
data.construction_goal ||= 100
data.construction_goal ||= Entity.get(@parent.name).build_steps
@text = CyberarmEngine::Text.new("", y: @parent.position.y, z: Float::INFINITY, size: 12)
data.state = :construct # deconstruct, building, idle
@@ -48,8 +48,8 @@ class IMICRTS
end
def draw_construction
@fencing ||= Gosu::Image.new(IMICRTS::ASSETS_PATH + "/fencing/fencing.png")
@fencing_edge ||= Gosu::Image.new(IMICRTS::ASSETS_PATH + "/fencing/fencing_edge.png")
@fencing ||= get_image(IMICRTS::ASSETS_PATH + "/fencing/fencing.png")
@fencing_edge ||= get_image(IMICRTS::ASSETS_PATH + "/fencing/fencing_edge.png")
tiles = []
each_tile(@parent.position / @parent.director.map.tile_size) do |tile, data, x, y|

View File

@@ -16,12 +16,12 @@ class IMICRTS
end
def rotate_towards(vector)
_angle = Gosu.angle(@parent.position.x, @parent.position.y, vector.x, vector.y)
a = (360.0 + (_angle - @parent.angle)) % 360.0
angle = Gosu.angle(@parent.position.x, @parent.position.y, vector.x, vector.y)
a = (360.0 + (angle - @parent.angle)) % 360.0
# FIXME: Fails if vector is directly behind entity
if a.round == 180
@parent.angle = (_angle + 180.0) % 360.0
@parent.angle = (angle + 180.0) % 360.0
elsif a < 180
@parent.angle -= 1.0
else

View File

@@ -17,7 +17,9 @@ class IMICRTS
action.label = ent.name.to_s.split("_").map{ |s| s.capitalize }.join(" ")
action.description = "Cost: #{ent.cost}\n#{ent.description}"
action.block = proc { @parent.component(:build_queue).add(data[:entity]) }
action.block = proc do
@parent.director.schedule_order(IMICRTS::Order::BUILD_UNIT, @parent.player.id, @parent.id, data[:entity])
end
when :set_tool
ent = IMICRTS::Entity.get(data[:entity])

View File

@@ -1,21 +1,17 @@
class IMICRTS
class Spawner < Component
def tick(tick_id)
# TODO: Ensure that a build order is created before working on entity
item = @parent.component(:build_queue).queue.first
if item
item.progress += 1
return unless item
if item.progress >= 100 # TODO: Define work units required for construction
@parent.component(:build_queue).queue.shift
item.progress += 1
spawn_point = @parent.position.clone
spawn_point.y += 96 # TODO: Use one of entity's reserved tiles for spawning
if item.progress >= item.entity.build_steps
unless item.completed
item.completed = true
ent = @parent.director.spawn_entity(player_id: @parent.player.id, name: item.entity.name, position: spawn_point)
ent.target = @parent.component(:waypoint).waypoint if @parent.component(:waypoint)
@parent.director.schedule_order(IMICRTS::Order::BUILD_UNIT_COMPLETE, @parent.player.id, @parent.id)
end
end
end

View File

@@ -7,15 +7,15 @@ class IMICRTS
end
def body_image=(image)
@body_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
@body_image = get_image("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
end
def shell_image=(image)
@shell_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
@shell_image = get_image("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
end
def overlay_image=(image)
@overlay_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
@overlay_image = get_image("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
end
def render
@@ -28,8 +28,11 @@ class IMICRTS
def draw
render unless @render
@angle += 0.1
@render.draw_rot(@parent.position.x, @parent.position.y, @parent.position.z, @angle, @center.x, @center.y)
end
def update
@angle = @parent.angle
end
end
end

View File

@@ -3,6 +3,7 @@ class IMICRTS
def setup
@waypoint = @parent.position.clone
@waypoint.y += @parent.director.map.tile_size
@waypoint_color = 0xffffff00
end
def set(vector)
@@ -17,11 +18,11 @@ class IMICRTS
return unless @parent.player.selected_entities.include?(@parent)
Gosu.draw_line(
@parent.position.x, @parent.position.y, @parent.player.color,
@waypoint.x, @waypoint.y, @parent.player.color, ZOrder::ENTITY_GIZMOS
@parent.position.x, @parent.position.y, @waypoint_color,
@waypoint.x, @waypoint.y, @waypoint_color, ZOrder::ENTITY_GIZMOS
)
Gosu.draw_circle(@waypoint.x, @waypoint.y, 4, 9, @parent.player.color, ZOrder::ENTITY_GIZMOS)
Gosu.draw_circle(@waypoint.x, @waypoint.y, 4, 9, @waypoint_color, ZOrder::ENTITY_GIZMOS)
end
end
end

View File

@@ -6,7 +6,7 @@ tiles = [
[false, :path, :path, :path, false],
]
IMICRTS::Entity.define_entity(:barracks, :building, 400, "Builds and soldiers", tiles) do |entity|
IMICRTS::Entity.define_entity(:barracks, :building, 400, 40, "Builds and soldiers", tiles) do |entity|
entity.has(:building)
entity.has(:waypoint)
entity.has(:spawner)

View File

@@ -6,13 +6,13 @@ tiles = [
[false, :path, :path, :path, false],
]
IMICRTS::Entity.define_entity(:construction_yard, :building, 2_000, "Provides radar and builds construction workers", tiles) do |entity|
IMICRTS::Entity.define_entity(:construction_yard, :building, 2_000, 310, "Provides radar and builds construction workers", tiles) do |entity|
entity.has(:building)
entity.has(:waypoint)
entity.has(:spawner)
entity.has(:build_queue)
entity.has(:sidebar_actions)
entity.component(:sidebar_actions).add(:add_to_build_queue, {entity: :construction_worker})
entity.component(:sidebar_actions).add(:add_to_build_queue, { entity: :construction_worker })
entity.radius = 40
entity.max_health = 100.0

View File

@@ -6,13 +6,13 @@ tiles = [
[false, false, false, false, false],
]
IMICRTS::Entity.define_entity(:helipad, :building, 1_000, "Builds and rearms helicopters", tiles) do |entity|
IMICRTS::Entity.define_entity(:helipad, :building, 1_000, 100, "Builds and rearms helicopters", tiles) do |entity|
entity.has(:building)
entity.has(:waypoint)
entity.has(:spawner)
entity.has(:build_queue)
entity.has(:sidebar_actions)
entity.component(:sidebar_actions).add(:add_to_build_queue, {entity: :helicopter})
entity.component(:sidebar_actions).add(:add_to_build_queue, { entity: :helicopter })
entity.radius = 26
entity.max_health = 100.0

View File

@@ -6,7 +6,7 @@ tiles = [
[false, false, :path, false, false],
]
IMICRTS::Entity.define_entity(:power_plant, :building, 800, "Generates power", tiles) do |entity|
IMICRTS::Entity.define_entity(:power_plant, :building, 800, 45, "Generates power", tiles) do |entity|
entity.has(:building)
entity.radius = 24

View File

@@ -6,7 +6,7 @@ tiles = [
[false, false, :path, :path, false],
]
IMICRTS::Entity.define_entity(:refinery, :building, 1_400, "Generates credits", tiles) do |entity|
IMICRTS::Entity.define_entity(:refinery, :building, 1_400, 200, "Generates credits", tiles) do |entity|
entity.has(:building)
entity.radius = 44

View File

@@ -6,15 +6,15 @@ tiles = [
[false, :path, :path, :path, false],
]
IMICRTS::Entity.define_entity(:war_factory, :building, 2_000, "Builds units", tiles) do |entity|
IMICRTS::Entity.define_entity(:war_factory, :building, 2_000, 310, "Builds units", tiles) do |entity|
entity.has(:building)
entity.has(:waypoint)
entity.has(:spawner)
entity.has(:build_queue)
entity.has(:sidebar_actions)
entity.component(:sidebar_actions).add(:add_to_build_queue, {entity: :jeep})
entity.component(:sidebar_actions).add(:add_to_build_queue, {entity: :tank})
entity.component(:sidebar_actions).add(:add_to_build_queue, {entity: :harvester})
entity.component(:sidebar_actions).add(:add_to_build_queue, { entity: :jeep })
entity.component(:sidebar_actions).add(:add_to_build_queue, { entity: :tank })
entity.component(:sidebar_actions).add(:add_to_build_queue, { entity: :harvester })
entity.radius = 48
entity.max_health = 100.0

View File

@@ -1,9 +1,9 @@
IMICRTS::Entity.define_entity(:construction_worker, :unit, 1000, "Constructs buildings") do |entity|
IMICRTS::Entity.define_entity(:construction_worker, :unit, 1000, 75, "Constructs buildings") do |entity|
entity.has(:movement)
entity.has(:build_queue)
entity.has(:sidebar_actions)
[:power_plant, :refinery, :barracks, :war_factory, :helipad, :construction_yard].each do |ent|
entity.component(:sidebar_actions).add(:set_tool, {tool: :place_entity, entity: ent, construction_worker: entity})
entity.component(:sidebar_actions).add(:set_tool, { tool: :place_entity, entity: ent, construction_worker: entity })
end
entity.radius = 14

View File

@@ -1,4 +1,4 @@
IMICRTS::Entity.define_entity(:harvester, :unit, 1400, "Harvests ore") do |entity, director|
IMICRTS::Entity.define_entity(:harvester, :unit, 1400, 140, "Harvests ore") do |entity, director|
entity.has(:movement)
entity.radius = 10

View File

@@ -1,6 +1,7 @@
IMICRTS::Entity.define_entity(:helicopter, :unit, 400, "Attacks ground targets") do |entity|
IMICRTS::Entity.define_entity(:helicopter, :unit, 400, 40, "Attacks ground targets") do |entity|
entity.has(:movement)
entity.speed = 2.5
entity.radius = 14
entity.movement = :air
entity.max_health = 100.0

View File

@@ -1,7 +1,8 @@
IMICRTS::Entity.define_entity(:jeep, :unit, 400, "Attacks ground targets") do |entity|
IMICRTS::Entity.define_entity(:jeep, :unit, 400, 40, "Attacks ground targets") do |entity|
entity.has(:movement)
entity.has(:turret)
entity.speed = 1.5
entity.radius = 14
entity.movement = :ground
entity.max_health = 100.0
@@ -14,4 +15,8 @@ IMICRTS::Entity.define_entity(:jeep, :unit, 400, "Attacks ground targets") do |e
entity.on_tick do
end
entity.component(:movement).define_singleton_method(:rotate_towards) do |target|
entity.angle = Gosu.angle(target.x, target.y, entity.position.x, entity.position.y)
end
end

View File

@@ -1,4 +1,4 @@
IMICRTS::Entity.define_entity(:tank, :unit, 800, "Attacks ground targets") do |entity|
IMICRTS::Entity.define_entity(:tank, :unit, 800, 80, "Attacks ground targets") do |entity|
entity.has(:movement)
entity.has(:turret)

View File

@@ -1,24 +1,23 @@
class IMICRTS
class Entity
Stub = Struct.new(:name, :type, :cost, :description, :tiles, :setup)
include CyberarmEngine::Common
Stub = Struct.new(:name, :type, :cost, :build_steps, :description, :tiles, :setup)
@entities = {}
def self.get(name)
@entities.dig(name)
end
def self.define_entity(name, type, cost, description, tiles = [[]], &block)
if entity = get(name)
raise "#{name.inspect} is already defined!"
else
@entities[name] = Stub.new(name, type, cost, description, tiles, block)
end
def self.define_entity(name, type, cost, build_steps, description, tiles = [[]], &block)
raise "#{name.inspect} is already defined!" if get(name)
@entities[name] = Stub.new(name, type, cost, build_steps, description, tiles, block)
end
attr_reader :director, :player, :id, :name, :type, :speed, :data
attr_accessor :position, :angle, :radius, :target, :state,
:movement, :health, :max_health,
:turret, :center, :particle_emitters, :color
attr_reader :director, :player, :id, :name, :type, :data
attr_accessor :position, :angle, :radius, :target, :state, :movement, :health, :max_health,
:speed, :turret, :center, :particle_emitters, :color
def initialize(name:, player:, id:, position:, angle:, director:, proto_entity: false)
@player = player
@id = id
@@ -77,11 +76,9 @@ class IMICRTS
def has(symbol)
component = Component.get(symbol)
if component
@components[symbol] = component.new(parent: self)
else
raise "Unknown component: #{symbol.inspect}"
end
raise "Unknown component: #{symbol.inspect}" unless component
@components[symbol] = component.new(parent: self)
end
def component(symbol)
@@ -89,15 +86,15 @@ class IMICRTS
end
def body_image=(image)
@body_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
@body_image = get_image("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
end
def shell_image=(image)
@shell_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
@shell_image = get_image("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
end
def overlay_image=(image)
@overlay_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
@overlay_image = get_image("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
end
def target=(entity)
@@ -153,10 +150,11 @@ class IMICRTS
end
def tick(tick_id)
@components.values.each { |com| com.tick(tick_id) }
@components.each_value { |com| com.tick(tick_id) }
@on_tick.call if @on_tick
data.assigned_construction_workers ||= 4
@on_tick&.call
data.assigned_construction_workers ||= 1
data.construction_speed ||= 1
component(:building).construction_work(data.assigned_construction_workers * data.construction_speed) if component(:building)
end

View File

@@ -29,6 +29,7 @@ class IMICRTS
end
attr_reader :id, :arguments
def initialize(id:, arguments:, &handler)
@id = id
@arguments = arguments
@@ -36,7 +37,7 @@ class IMICRTS
end
def execute(director, *arguments)
pp Order.order_name(self.id)
pp Order.order_name(id)
@handler.call(struct(arguments), director)
end
@@ -48,7 +49,7 @@ class IMICRTS
hash[key] = args[value]
end
return hash
hash
end
def serialize(order, director)
@@ -76,13 +77,18 @@ class IMICRTS
:ATTACK,
:PATROL,
:BUILD_ORDER,
:CANCEL_BUILD_ORDER,
:BUILD_ORDER_COMPLETE,
:CONSTRUCT,
:CANCEL_CONSTRUCTION,
:CONSTRUCTION_COMPLETE,
:BUILD_UNIT,
:CANCEL_BUILD_UNIT,
:BUILD_UNIT_COMPLETE,
:BUILDING_SET_WAYPOINT,
:BUILDING_POWER_STATE,
:BUILDING_REPAIR,
:REPAIR_BUILDING,
:CANCEL_BUILDING_REPAIR,
:BUILDING_SELL,
:MESSAGE_BROADCAST,

18
lib/orders/build_unit.rb Normal file
View File

@@ -0,0 +1,18 @@
IMICRTS::Order.define_handler(IMICRTS::Order::BUILD_UNIT, arguments: [:player_id, :entity_id, :unit_type]) do |order, director|
director.player(order.player_id).entity(order.entity_id).component(:build_queue)&.add(order.unit_type)
end
IMICRTS::Order.define_serializer(IMICRTS::Order::BUILD_UNIT) do |order, director|
# Order ID | Player ID | Entity ID | Unit Type
# char | char | integer | string
[IMICRTS::Order::BUILD_UNIT, order.player_id, order.entity_id, order.unit_type.to_s].pack("CCNA*")
end
IMICRTS::Order.define_deserializer(IMICRTS::Order::BUILD_UNIT) do |string, director|
# String fed into deserializer has Order ID removed
# Player ID |
# char | integer | string
data = string.unpack("CNA*")
[data[0], data[1], data[2].to_sym]
end

View File

@@ -0,0 +1,25 @@
IMICRTS::Order.define_handler(IMICRTS::Order::BUILD_UNIT_COMPLETE, arguments: [:player_id, :entity_id]) do |order, director|
entity = director.player(order.player_id).entity(order.entity_id)
item = entity.component(:build_queue).queue.shift
spawn_point = entity.position.clone
spawn_point.y += 96 # TODO: Use entity defined spawnpoint
ent = entity.director.spawn_entity(player_id: entity.player.id, name: item.entity.name, position: spawn_point)
ent.target = entity.component(:waypoint).waypoint if entity.component(:waypoint)
end
IMICRTS::Order.define_serializer(IMICRTS::Order::BUILD_UNIT_COMPLETE) do |order, director|
# Order ID | Player ID
# char | char
[IMICRTS::Order::BUILD_UNIT_COMPLETE, order.player_id, order.entity_id].pack("CCN")
end
IMICRTS::Order.define_deserializer(IMICRTS::Order::BUILD_UNIT_COMPLETE) do |string, director|
# String fed into deserializer has Order ID removed
# Player ID | Entity ID
# char | integer
data = string.unpack("CN")
[data[0], data[1]]
end

View File

@@ -1,4 +1,4 @@
IMICRTS::Order.define_handler(IMICRTS::Order::BUILD_ORDER, arguments: [:player_id, :vector, :building]) do |order, director|
IMICRTS::Order.define_handler(IMICRTS::Order::CONSTRUCT, arguments: [:player_id, :vector, :building]) do |order, director|
tile = director.map.tile_at(order.vector.x, order.vector.y)
position = tile.position + director.map.tile_size / 2
@@ -20,14 +20,14 @@ IMICRTS::Order.define_handler(IMICRTS::Order::BUILD_ORDER, arguments: [:player_i
end
end
IMICRTS::Order.define_serializer(IMICRTS::Order::BUILD_ORDER) do |order, director|
IMICRTS::Order.define_serializer(IMICRTS::Order::CONSTRUCT) do |order, director|
# Order ID | Player ID | Vector X | Vector Y | Entity Name
# char | char | integer | integer | string
[IMICRTS::Order::BUILD_ORDER, order.player_id, order.vector.x, order.vector.y, order.building.to_s].pack("CCNNA*")
[IMICRTS::Order::CONSTRUCT, order.player_id, order.vector.x, order.vector.y, order.building.to_s].pack("CCNNA*")
end
IMICRTS::Order.define_deserializer(IMICRTS::Order::BUILD_ORDER) do |string, director|
IMICRTS::Order.define_deserializer(IMICRTS::Order::CONSTRUCT) do |string, director|
# String fed into deserializer has Order ID removed
# Player ID | Vector X | Vector Y | Entity Name
# char | integer | integer | string

View File

@@ -147,7 +147,6 @@ class IMICRTS
# DOWN
add_node create_node(@current_node.tile.grid_position.x, @current_node.tile.grid_position.y + 1, @current_node)
# TODO: Add diagonal nodes, if requested
if @allow_diagonal
# LEFT-UP
if node_above? && node_above_left?

View File

@@ -4,7 +4,7 @@ class IMICRTS
@title = Gosu::Font.new(56, name: "Noto Sans Display", bold: true)
@text = Gosu::Font.new(18, name: "Noto Sans Thaana", bold: true)
@name = IMICRTS::NAME
@logo = Gosu::Image.new("#{ASSETS_PATH}/logo.png")
@logo = get_image("#{ASSETS_PATH}/logo.png")
@messages = ["Loading", "Compiling Protons", "Launching Warhead", "git push origin --force"]
@messages_index = 0

View File

@@ -2,7 +2,7 @@ class IMICRTS
class Closing < CyberarmEngine::GuiState
def setup
window.show_cursor = false
@logo = Gosu::Image.new("#{ASSETS_PATH}/logo.png")
@logo = get_image("#{ASSETS_PATH}/logo.png")
@color = Gosu::Color.new(0xffffffff)
@started_at = Gosu.milliseconds

View File

@@ -41,7 +41,7 @@ class IMICRTS
player_id: player.id, name: :construction_yard,
position: CyberarmEngine::Vector.new(player.spawnpoint.x, player.spawnpoint.y, ZOrder::BUILDING)
)
construction_yard.component(:building).data.construction_progress = 100
construction_yard.component(:building).data.construction_progress = Entity.get(construction_yard.name).build_steps
@director.each_tile(@director.map.world_to_grid(construction_yard.position), construction_yard.name) do |tile, space_required|
if space_required == true
tile.entity = construction_yard

View File

@@ -1,5 +1,7 @@
class IMICRTS
class Tool
include CyberarmEngine::Common
@@tools = {}
def self.get(tool)
@@tools.dig(tool)

View File

@@ -3,14 +3,17 @@ class IMICRTS
class EntityController < Tool
def setup
@drag_start = CyberarmEngine::Vector.new
@box_color = 0xaa99ff99
@box_border_size = 2
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
return unless @box
Gosu.draw_rect(@box.min.x, @box.min.y, @box.width, @box_border_size, @box_color, ZOrder::SELECTION_BOX)
Gosu.draw_rect(@box.min.x + @box.width, @box.min.y, @box_border_size, @box.height, @box_color, ZOrder::SELECTION_BOX)
Gosu.draw_rect(@box.min.x, @box.min.y + @box.height, @box.width, @box_border_size, @box_color, ZOrder::SELECTION_BOX)
Gosu.draw_rect(@box.min.x, @box.min.y, @box_border_size, @box.height, @box_color, ZOrder::SELECTION_BOX)
end
def update
@@ -40,16 +43,16 @@ class IMICRTS
@selection_start = @player.camera.transform(@game.window.mouse)
end
when Gosu::MS_RIGHT
if @player.selected_entities.size > 0
unless @player.selected_entities.empty?
if @player.selected_entities.any? { |ent| ent.component(:movement) }
@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 << Game::Overlay.new(get_image("#{IMICRTS::ASSETS_PATH}/cursors/move.png"), @player.camera.transform(@game.window.mouse), 0, 255)
@game.overlays.last.position.z = ZOrder::OVERLAY
elsif @player.selected_entities.size == 1 && @player.selected_entities.first.component(:waypoint)
@director.schedule_order(Order::BUILDING_SET_WAYPOINT, @player.id, @player.selected_entities.first.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 << Game::Overlay.new(get_image("#{IMICRTS::ASSETS_PATH}/cursors/move.png"), @player.camera.transform(@game.window.mouse), 0, 255)
@game.overlays.last.position.z = ZOrder::OVERLAY
end
end
@@ -63,11 +66,13 @@ class IMICRTS
@box = nil
@selection_start = nil
return if @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
diff = (@player.selected_entities - @game.selected_entities)
@game.sidebar_actions.clear
@director.schedule_order(Order::DESELECTED_UNITS, @player.id, diff) if diff.size > 0
if @game.selected_entities.size > 0
@director.schedule_order(Order::DESELECTED_UNITS, @player.id, diff) if diff.size.positive?
if @game.selected_entities.size.positive?
@director.schedule_order(Order::SELECTED_UNITS, @player.id, @game.selected_entities)
else
pick_entity
@@ -79,7 +84,7 @@ class IMICRTS
@game.sidebar_actions.clear do
ent.component(:sidebar_actions).actions.each do |action|
@game.button action.label, tip: action.description, width: 1.0 do
action.block.call if action.block
action.block&.call
end
end
end

View File

@@ -30,11 +30,10 @@ class IMICRTS
end
def update
# TODO: ensure that construction worker is alive
cancel_tool if @construction_worker.die?
cancel_tool unless @construction_worker.player.entity(@construction_worker.id)
vector = vector_to_grid(@game.window.mouse)
if tile = @director.map.tile_at(vector.x, vector.y)
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
@@ -58,7 +57,7 @@ class IMICRTS
# position: CyberarmEngine::Vector.new(position.x, position.y, ZOrder::BUILDING)
# )
@director.schedule_order(Order::BUILD_ORDER, @player.id, vector, @entity)
@director.schedule_order(Order::CONSTRUCT, @player.id, vector, @entity)
# each_tile(vector) do |tile, space_required|
# if space_required == true

View File

@@ -1,10 +1,11 @@
class IMICRTS
class Window < CyberarmEngine::Window
attr_reader :mouse
def setup
@last_update_time = Gosu.milliseconds
@mouse = CyberarmEngine::Vector.new
@cursor = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/cursors/pointer.png")
@cursor = get_image("#{IMICRTS::ASSETS_PATH}/cursors/pointer.png")
self.caption = "#{IMICRTS::NAME} (#{IMICRTS::VERSION} #{IMICRTS::VERSION_NAME})"
if ARGV.join.include?("--debug-game")
@@ -14,6 +15,10 @@ class IMICRTS
else
push_state(Boot)
end
# TODO: Jukebox
s = get_song("#{GAME_ROOT_PATH}/assets/audio/music/EmptyCity.ogg")
s.play(true)
end
def draw
@@ -23,14 +28,16 @@ class IMICRTS
end
def update
@mouse.x, @mouse.y = self.mouse_x, self.mouse_y
@mouse.x = mouse_x
@mouse.y = mouse_y
super
@last_update_time = Gosu.milliseconds
end
def needs_cursor?
return false
false
end
def close