mirror of
https://github.com/cyberarm/i-mic-rts.git
synced 2025-12-13 14:52:35 +00:00
Orders are now de/serializable, and scheduleable, Entities now show a circle around themselves when selected and draw a line to their target
This commit is contained in:
@@ -5,6 +5,7 @@ rescue LoadError
|
|||||||
end
|
end
|
||||||
|
|
||||||
require_relative "lib/version"
|
require_relative "lib/version"
|
||||||
|
require_relative "lib/errors"
|
||||||
require_relative "lib/window"
|
require_relative "lib/window"
|
||||||
require_relative "lib/camera"
|
require_relative "lib/camera"
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ class IMICRTS
|
|||||||
@velocity = CyberarmEngine::Vector.new(0.0, 0.0)
|
@velocity = CyberarmEngine::Vector.new(0.0, 0.0)
|
||||||
|
|
||||||
@zoom = 1.0
|
@zoom = 1.0
|
||||||
@min_zoom = 0.25
|
@min_zoom = 0.50
|
||||||
@max_zoom = 4.0
|
@max_zoom = 5.0
|
||||||
|
|
||||||
@drag = 0.8 # Used to arrest velocity
|
@drag = 0.8 # Used to arrest velocity
|
||||||
@grab_drag = 0.5 # Used when camera is panned using middle mouse button
|
@grab_drag = 0.5 # Used when camera is panned using middle mouse button
|
||||||
@@ -22,8 +22,6 @@ class IMICRTS
|
|||||||
Gosu.clip_to(@viewport.min.x, @viewport.min.y, @viewport.max.x, @viewport.max.y) do
|
Gosu.clip_to(@viewport.min.x, @viewport.min.y, @viewport.max.x, @viewport.max.y) do
|
||||||
Gosu.transform(*worldspace.elements) do
|
Gosu.transform(*worldspace.elements) do
|
||||||
block.call
|
block.call
|
||||||
|
|
||||||
Gosu.draw_line(@drag_start.x, @drag_start.y, Gosu::Color::RED, window.mouse.x, window.mouse_x, Gosu::Color::RED, Float::INFINITY) if @drag_start
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -98,6 +96,11 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def move_to(x, y, zoom)
|
||||||
|
@position.x, @position.y = x, y
|
||||||
|
@zoom = zoom
|
||||||
|
end
|
||||||
|
|
||||||
def button_down(id)
|
def button_down(id)
|
||||||
case id
|
case id
|
||||||
when Gosu::KB_H
|
when Gosu::KB_H
|
||||||
@@ -118,5 +121,9 @@ class IMICRTS
|
|||||||
@drag_start = nil
|
@drag_start = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_a
|
||||||
|
[@position.x, @position.y, @zoom]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -20,10 +20,35 @@ class IMICRTS
|
|||||||
tick
|
tick
|
||||||
@connection.update
|
@connection.update
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@players.each { |player| player.update }
|
||||||
end
|
end
|
||||||
|
|
||||||
def tick
|
def tick
|
||||||
@players.each { |player| player.tick(@current_tick) }
|
@players.each do |player|
|
||||||
|
player.tick(@current_tick)
|
||||||
|
|
||||||
|
# Records where player is looking at tick
|
||||||
|
# record_order(Order::CAMERA_MOVE, player.id, *player.camera.to_a)# if player.camera_moved?
|
||||||
|
|
||||||
|
player.orders.sort_by {|order| order.tick_id }.each do |order|
|
||||||
|
raise DesyncError, "Have orders from an already processed tick! (#{order.tick_id} < #{current_tick})" if order.tick_id < @current_tick
|
||||||
|
|
||||||
|
if _order = Order.get(Integer(order.serialized_order.unpack("C").first))
|
||||||
|
# Chop off Order ID
|
||||||
|
_order_data = order.serialized_order
|
||||||
|
_order_args = _order.deserialize(_order_data[1.._order_data.length - 1], self)
|
||||||
|
|
||||||
|
execute_order(_order.id, *_order_args)
|
||||||
|
|
||||||
|
player.orders.delete(order)
|
||||||
|
else
|
||||||
|
raise UndefinedOrderError
|
||||||
|
end
|
||||||
|
|
||||||
|
break if order.tick_id > @current_tick
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@current_tick += 1
|
@current_tick += 1
|
||||||
end
|
end
|
||||||
@@ -32,7 +57,29 @@ class IMICRTS
|
|||||||
@players.find { |player| player.id == id }
|
@players.find { |player| player.id == id }
|
||||||
end
|
end
|
||||||
|
|
||||||
def issue_order(order_id, *args)
|
def record_order(order_id, *args)
|
||||||
|
if order = Order.get(order_id)
|
||||||
|
struct = order.struct(args)
|
||||||
|
|
||||||
|
player(struct.player_id).orders.push(Player::ScheduledOrder.new( order_id, @current_tick + 1, order.serialize(struct, self) ))
|
||||||
|
else
|
||||||
|
raise "Undefined order: #{Order.order_name(order_id)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def schedule_order(order_id, *args)
|
||||||
|
if order = Order.get(order_id)
|
||||||
|
struct = order.struct(args)
|
||||||
|
|
||||||
|
pp Order.order_name(order_id)
|
||||||
|
|
||||||
|
player(struct.player_id).orders.push(Player::ScheduledOrder.new( order_id, @current_tick + 2, order.serialize(struct, self) ))
|
||||||
|
else
|
||||||
|
raise "Undefined order: #{Order.order_name(order_id)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_order(order_id, *args)
|
||||||
if order = Order.get(order_id)
|
if order = Order.get(order_id)
|
||||||
order.execute(self, *args)
|
order.execute(self, *args)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Entity
|
class Entity
|
||||||
attr_reader :id, :position, :angle, :radius
|
attr_reader :player, :id, :position, :angle, :radius, :target, :state
|
||||||
def initialize(id:, manifest: nil, images:, position:, angle:)
|
def initialize(player:, id:, manifest: nil, images:, position:, angle:)
|
||||||
|
@player = player
|
||||||
@id = id
|
@id = id
|
||||||
@manifest = manifest
|
@manifest = manifest
|
||||||
@images = images
|
@images = images
|
||||||
@@ -9,6 +10,23 @@ class IMICRTS
|
|||||||
@angle = angle
|
@angle = angle
|
||||||
|
|
||||||
@radius = 32 / 2
|
@radius = 32 / 2
|
||||||
|
@target = nil
|
||||||
|
@state = :idle
|
||||||
|
|
||||||
|
# process_manifest
|
||||||
|
|
||||||
|
@goal_color = Gosu::Color.argb(175, 25, 200, 25)
|
||||||
|
@target_color = Gosu::Color.argb(175, 200, 25, 25)
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialize
|
||||||
|
end
|
||||||
|
|
||||||
|
def deserialize
|
||||||
|
end
|
||||||
|
|
||||||
|
def target=(entity)
|
||||||
|
@target = entity
|
||||||
end
|
end
|
||||||
|
|
||||||
def hit?(x_or_vector, y = nil)
|
def hit?(x_or_vector, y = nil)
|
||||||
@@ -27,16 +45,27 @@ class IMICRTS
|
|||||||
@images.draw_rot(@position.x, @position.y, @position.z, @angle)
|
@images.draw_rot(@position.x, @position.y, @position.z, @angle)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
rotate_towards(@target) if @target
|
||||||
|
end
|
||||||
|
|
||||||
def selected_draw
|
def selected_draw
|
||||||
draw_bounding_box
|
draw_radius
|
||||||
draw_gizmos
|
draw_gizmos
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_bounding_box
|
def draw_radius
|
||||||
|
Gosu.draw_circle(@position.x, @position.y, @radius, ZOrder::ENTITY_RADIUS, @player.color)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_gizmos
|
def draw_gizmos
|
||||||
Gosu.draw_rect(@position.x - @radius, @position.y - (@radius + 2), @radius * 2, 2, Gosu::Color::GREEN, ZOrder::ENTITY_GIZMOS)
|
Gosu.draw_rect(@position.x - @radius, @position.y - (@radius + 2), @radius * 2, 2, Gosu::Color::GREEN, ZOrder::ENTITY_GIZMOS)
|
||||||
|
|
||||||
|
if @target.is_a?(IMICRTS::Entity)
|
||||||
|
Gosu.draw_line(@position.x, @position.y, @target_color, @target.position.x, @target.position.y, @target_color, ZOrder::ENTITY_GIZMOS) if @target
|
||||||
|
else
|
||||||
|
Gosu.draw_line(@position.x, @position.y, @goal_color, @target.x, @target.y, @goal_color, ZOrder::ENTITY_GIZMOS) if @target
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def rotate_towards(vector)
|
def rotate_towards(vector)
|
||||||
|
|||||||
6
lib/errors.rb
Normal file
6
lib/errors.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class IMICRTS
|
||||||
|
class DesyncError < Exception
|
||||||
|
end
|
||||||
|
class UndefinedOrderError < Exception
|
||||||
|
end
|
||||||
|
end
|
||||||
26
lib/order.rb
26
lib/order.rb
@@ -16,7 +16,19 @@ class IMICRTS
|
|||||||
@@orders[order_id] = IMICRTS::Order.new(id: order_id, arguments: arguments, &handler)
|
@@orders[order_id] = IMICRTS::Order.new(id: order_id, arguments: arguments, &handler)
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :id
|
def self.define_serializer(order_id, &handler)
|
||||||
|
get(order_id).define_singleton_method(:serialize) do |order, director|
|
||||||
|
handler.call(order, director)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.define_deserializer(order_id, &handler)
|
||||||
|
get(order_id).define_singleton_method(:deserialize) do |string, director|
|
||||||
|
handler.call(string, director)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :id, :arguments
|
||||||
def initialize(id:, arguments:, &handler)
|
def initialize(id:, arguments:, &handler)
|
||||||
@id = id
|
@id = id
|
||||||
@arguments = arguments
|
@arguments = arguments
|
||||||
@@ -24,10 +36,11 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def execute(director, *arguments)
|
def execute(director, *arguments)
|
||||||
@handler.call(arguments(arguments), director)
|
pp Order.order_name(self.id)
|
||||||
|
@handler.call(struct(arguments), director)
|
||||||
end
|
end
|
||||||
|
|
||||||
def arguments(args)
|
def struct(args)
|
||||||
raise "Did not receive correct number of arguments: got #{args.size} expected #{@arguments.size}." unless @arguments.size == args.size
|
raise "Did not receive correct number of arguments: got #{args.size} expected #{@arguments.size}." unless @arguments.size == args.size
|
||||||
|
|
||||||
hash = FriendlyHash.new
|
hash = FriendlyHash.new
|
||||||
@@ -38,16 +51,15 @@ class IMICRTS
|
|||||||
return hash
|
return hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialize
|
def serialize(order, director)
|
||||||
end
|
end
|
||||||
|
|
||||||
def deserialize
|
def deserialize(string, director)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
orders = [
|
orders = [
|
||||||
:CAMERA_MOVED,
|
:CAMERA_MOVE,
|
||||||
:CAMERA_ZOOMED,
|
|
||||||
|
|
||||||
:ENTITY_SELECTED,
|
:ENTITY_SELECTED,
|
||||||
:ENTITY_DESELECTED,
|
:ENTITY_DESELECTED,
|
||||||
|
|||||||
18
lib/orders/camera_move.rb
Normal file
18
lib/orders/camera_move.rb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
IMICRTS::Order.define_handler(IMICRTS::Order::CAMERA_MOVE, arguments: [:player_id, :x, :y, :zoom]) do |order, director|
|
||||||
|
director.player(order.player_id).camera.move_to(order.x, order.y, order.zoom)
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_serializer(IMICRTS::Order::CAMERA_MOVE) do |order, director|
|
||||||
|
# Order ID: char as C
|
||||||
|
# Player ID: char as C
|
||||||
|
# Position X/Y: Double as G
|
||||||
|
# Zoom: Double as G
|
||||||
|
|
||||||
|
[IMICRTS::Order::CAMERA_MOVE, order.player_id, order.x, order.y, order.zoom].pack("CCGGG")
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_deserializer(IMICRTS::Order::CAMERA_MOVE) do |string, director|
|
||||||
|
# Player ID | Camera X | Camera Y | Camera Zoom
|
||||||
|
# char | double | double | double
|
||||||
|
string.unpack("CGGG")
|
||||||
|
end
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
IMICRTS::Order.define_handler(IMICRTS::Order::CAMERA_MOVED, arguments: [:player_id, :x, :y]) do |order, director|
|
|
||||||
director.player(order.player_id).move_camera(order.x, order.y)
|
|
||||||
end
|
|
||||||
|
|
||||||
21
lib/orders/deselected_units.rb
Normal file
21
lib/orders/deselected_units.rb
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
IMICRTS::Order.define_handler(IMICRTS::Order::DESELECTED_UNITS, arguments: [:player_id, :entities]) do |order, director|
|
||||||
|
selected_entities = director.player(order.player_id).selected_entities
|
||||||
|
selected_entities.select { |ent| order.entities.include?(ent)}.each { |ent| selected_entities.delete(ent) }
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_serializer(IMICRTS::Order::DESELECTED_UNITS) do |order, director|
|
||||||
|
# Order ID | Player ID | Entity IDs
|
||||||
|
# char | char | integers
|
||||||
|
|
||||||
|
[IMICRTS::Order::DESELECTED_UNITS, order.player_id].pack("CC") + order.entities.map { |ent| ent.id }.pack("N*")
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_deserializer(IMICRTS::Order::DESELECTED_UNITS) do |string, director|
|
||||||
|
# String fed into deserializer has Order ID removed
|
||||||
|
# Player ID | Entity IDs
|
||||||
|
# char | integers
|
||||||
|
player_id = string.unpack("C").first
|
||||||
|
entities = string[1..string.length - 1].unpack("N*").map { |ent_id| director.player(player_id).entity(ent_id) }
|
||||||
|
|
||||||
|
[player_id, entities]
|
||||||
|
end
|
||||||
20
lib/orders/move.rb
Normal file
20
lib/orders/move.rb
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
IMICRTS::Order.define_handler(IMICRTS::Order::MOVE, arguments: [:player_id, :vector]) do |order, director|
|
||||||
|
director.player(order.player_id).selected_entities.each do |entity|
|
||||||
|
entity.target = order.vector
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_serializer(IMICRTS::Order::MOVE) do |order, director|
|
||||||
|
# Order ID | Player ID | Target X | Target Y
|
||||||
|
# char | char | double | double
|
||||||
|
|
||||||
|
[IMICRTS::Order::MOVE, order.player_id, order.vector.x, order.vector.y].pack("CCGG")
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_deserializer(IMICRTS::Order::MOVE) do |string, director|
|
||||||
|
# String fed into deserializer has Order ID removed
|
||||||
|
# Player ID | Target X | Target Y
|
||||||
|
# char | double | double
|
||||||
|
data = string.unpack("CGG")
|
||||||
|
[data[0], CyberarmEngine::Vector.new(data[1], data[2])]
|
||||||
|
end
|
||||||
@@ -1,5 +1,21 @@
|
|||||||
IMICRTS::Order.define_handler(IMICRTS::Order::SELECTED_UNITS, arguments: [:player_id, :ids]) do |order, director|
|
IMICRTS::Order.define_handler(IMICRTS::Order::SELECTED_UNITS, arguments: [:player_id, :entities]) do |order, director|
|
||||||
director.player(order.player_id).selected_entities.clear
|
director.player(order.player_id).selected_entities.clear
|
||||||
director.player(order.player_id).selected_entities.push(*order.ids)
|
director.player(order.player_id).selected_entities.push(*order.entities)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_serializer(IMICRTS::Order::SELECTED_UNITS) do |order, director|
|
||||||
|
# Order ID | Player ID | Entity IDs
|
||||||
|
# char | char | integers
|
||||||
|
|
||||||
|
[IMICRTS::Order::SELECTED_UNITS, order.player_id].pack("CC") + order.entities.map { |ent| ent.id }.pack("N*")
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_deserializer(IMICRTS::Order::SELECTED_UNITS) do |string, director|
|
||||||
|
# String fed into deserializer has Order ID removed
|
||||||
|
# Player ID | Entity IDs
|
||||||
|
# char | integers
|
||||||
|
player_id = string.unpack("C").first
|
||||||
|
entities = string[1..string.length - 1].unpack("N*").map { |ent_id| director.player(player_id).entity(ent_id) }
|
||||||
|
|
||||||
|
[player_id, entities]
|
||||||
|
end
|
||||||
|
|||||||
19
lib/orders/stop.rb
Normal file
19
lib/orders/stop.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
IMICRTS::Order.define_handler(IMICRTS::Order::STOP, arguments: [:player_id]) do |order, director|
|
||||||
|
director.player(order.player_id).selected_entities.each do |entity|
|
||||||
|
entity.target = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_serializer(IMICRTS::Order::STOP) do |order, director|
|
||||||
|
# Order ID | Player ID
|
||||||
|
# char | char
|
||||||
|
|
||||||
|
[IMICRTS::Order::STOP, order.player_id].pack("CC")
|
||||||
|
end
|
||||||
|
|
||||||
|
IMICRTS::Order.define_deserializer(IMICRTS::Order::STOP) do |string, director|
|
||||||
|
# String fed into deserializer has Order ID removed
|
||||||
|
# Player ID
|
||||||
|
# char
|
||||||
|
string.unpack("C")
|
||||||
|
end
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Player
|
class Player
|
||||||
attr_reader :id, :name, :entities, :orders, :camera
|
attr_reader :id, :name, :color, :team, :entities, :orders, :camera
|
||||||
attr_reader :selected_entities
|
attr_reader :selected_entities
|
||||||
def initialize(id:, name: nil)
|
def initialize(id:, name: nil, color: Gosu::Color.rgb(rand(150..200), rand(100..200), rand(150..200)), team: nil)
|
||||||
@id = id
|
@id = id
|
||||||
@name = name ? name : "Novice-#{id}"
|
@name = name ? name : "Novice-#{id}"
|
||||||
|
@color = color
|
||||||
|
@team = team
|
||||||
|
|
||||||
@entities = []
|
@entities = []
|
||||||
@orders = []
|
@orders = []
|
||||||
@@ -17,6 +19,10 @@ class IMICRTS
|
|||||||
def tick(tick_id)
|
def tick(tick_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@entities.each(&:update)
|
||||||
|
end
|
||||||
|
|
||||||
def entity(id)
|
def entity(id)
|
||||||
@entities.find { |ent| ent.id == id }
|
@entities.find { |ent| ent.id == id }
|
||||||
end
|
end
|
||||||
@@ -24,5 +30,16 @@ class IMICRTS
|
|||||||
def next_entity_id
|
def next_entity_id
|
||||||
@current_entity_id += 1
|
@current_entity_id += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ScheduledOrder
|
||||||
|
attr_reader :tick_id, :serialized_order
|
||||||
|
def initialize(order_id, tick_id, serialized_order)
|
||||||
|
@order_id = order_id
|
||||||
|
@tick_id, @serialized_order = tick_id, serialized_order
|
||||||
|
|
||||||
|
raise ArgumentError, "Tick ID is nil!" unless @tick_id
|
||||||
|
raise ArgumentError, "Serialized order for #{Order.order_name(order_id)} is nil!" unless @serialized_order
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -19,6 +19,7 @@ class IMICRTS
|
|||||||
@buttons = stack(width: 75) do
|
@buttons = stack(width: 75) do
|
||||||
@h = button("Harvester", width: 1.0) do
|
@h = button("Harvester", width: 1.0) do
|
||||||
@player.entities << Entity.new(
|
@player.entities << Entity.new(
|
||||||
|
player: @player,
|
||||||
id: @player.next_entity_id,
|
id: @player.next_entity_id,
|
||||||
images: Gosu::Image.new("#{ASSETS_PATH}/vehicles/harvester/images/harvester.png", retro: true),
|
images: Gosu::Image.new("#{ASSETS_PATH}/vehicles/harvester/images/harvester.png", retro: true),
|
||||||
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
||||||
@@ -27,6 +28,7 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
@c = button("Construction Worker", width: 1.0) do
|
@c = button("Construction Worker", width: 1.0) do
|
||||||
@player.entities << Entity.new(
|
@player.entities << Entity.new(
|
||||||
|
player: @player,
|
||||||
id: @player.next_entity_id,
|
id: @player.next_entity_id,
|
||||||
images: Gosu::Image.new("#{ASSETS_PATH}/vehicles/construction_worker/images/construction_worker.png", retro: true),
|
images: Gosu::Image.new("#{ASSETS_PATH}/vehicles/construction_worker/images/construction_worker.png", retro: true),
|
||||||
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
||||||
@@ -81,10 +83,6 @@ class IMICRTS
|
|||||||
@director.update
|
@director.update
|
||||||
@player.camera.update
|
@player.camera.update
|
||||||
|
|
||||||
@player.selected_entities.each do |ent|
|
|
||||||
ent.rotate_towards(@goal) if @goal
|
|
||||||
end
|
|
||||||
|
|
||||||
if @selection_start
|
if @selection_start
|
||||||
select_entities
|
select_entities
|
||||||
end
|
end
|
||||||
@@ -113,13 +111,17 @@ class IMICRTS
|
|||||||
super
|
super
|
||||||
|
|
||||||
case id
|
case id
|
||||||
|
when Gosu::KB_S
|
||||||
|
@director.schedule_order(Order::STOP, @player.id)
|
||||||
|
|
||||||
when Gosu::MS_LEFT
|
when Gosu::MS_LEFT
|
||||||
unless @sidebar.hit?(window.mouse_x, window.mouse_y)
|
unless @sidebar.hit?(window.mouse_x, window.mouse_y)
|
||||||
@selection_start = @player.camera.transform(window.mouse)
|
@selection_start = @player.camera.transform(window.mouse)
|
||||||
end
|
end
|
||||||
when Gosu::MS_RIGHT
|
when Gosu::MS_RIGHT
|
||||||
@anchor = nil
|
@director.schedule_order(Order::MOVE, @player.id, @player.camera.transform(window.mouse))
|
||||||
end
|
end
|
||||||
|
|
||||||
@player.camera.button_down(id) unless @sidebar.hit?(window.mouse_x, window.mouse_y)
|
@player.camera.button_down(id) unless @sidebar.hit?(window.mouse_x, window.mouse_y)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -128,12 +130,14 @@ class IMICRTS
|
|||||||
|
|
||||||
case id
|
case id
|
||||||
when Gosu::MS_RIGHT
|
when Gosu::MS_RIGHT
|
||||||
@goal = @player.camera.transform(window.mouse)
|
|
||||||
when Gosu::MS_LEFT
|
when Gosu::MS_LEFT
|
||||||
@box = nil
|
@box = nil
|
||||||
@selection_start = nil
|
@selection_start = nil
|
||||||
|
|
||||||
@director.issue_order(Order::SELECTED_UNITS, @player.id, @selected_entities)
|
diff = (@player.selected_entities - @selected_entities)
|
||||||
|
|
||||||
|
@director.schedule_order(Order::DESELECTED_UNITS, @player.id, diff)
|
||||||
|
@director.schedule_order(Order::SELECTED_UNITS, @player.id, @selected_entities)
|
||||||
end
|
end
|
||||||
|
|
||||||
@player.camera.button_up(id)
|
@player.camera.button_up(id)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class IMICRTS
|
|||||||
:BUILDING,
|
:BUILDING,
|
||||||
:AIR_VEHICLE,
|
:AIR_VEHICLE,
|
||||||
|
|
||||||
:ENTITY_BOUNDING_BOX,
|
:ENTITY_RADIUS,
|
||||||
:ENTITY_GIZMOS, # Health bar and the like
|
:ENTITY_GIZMOS, # Health bar and the like
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user