mirror of
https://github.com/cyberarm/i-mic-rts.git
synced 2025-12-15 07:42:34 +00:00
added on_order handler to entities and components, added visibility map
This commit is contained in:
@@ -39,12 +39,14 @@ require_relative "lib/particle_emitter"
|
|||||||
require_relative "lib/entity"
|
require_relative "lib/entity"
|
||||||
require_relative "lib/map"
|
require_relative "lib/map"
|
||||||
require_relative "lib/tiled_map"
|
require_relative "lib/tiled_map"
|
||||||
|
require_relative "lib/visiblity_map"
|
||||||
require_relative "lib/pathfinder"
|
require_relative "lib/pathfinder"
|
||||||
|
|
||||||
require_relative "lib/order"
|
require_relative "lib/order"
|
||||||
require_relative "lib/friendly_hash"
|
require_relative "lib/friendly_hash"
|
||||||
require_relative "lib/director"
|
require_relative "lib/director"
|
||||||
require_relative "lib/player"
|
require_relative "lib/player"
|
||||||
|
require_relative "lib/ai/ai_player"
|
||||||
require_relative "lib/tool"
|
require_relative "lib/tool"
|
||||||
require_relative "lib/connection"
|
require_relative "lib/connection"
|
||||||
|
|
||||||
|
|||||||
15
lib/ai/ai_player.rb
Normal file
15
lib/ai/ai_player.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class IMICRTS
|
||||||
|
class AIPlayer < Player
|
||||||
|
def tick(tick_id)
|
||||||
|
super
|
||||||
|
|
||||||
|
think
|
||||||
|
end
|
||||||
|
|
||||||
|
def think
|
||||||
|
# build base
|
||||||
|
# construct army
|
||||||
|
# attack
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Camera
|
class Camera
|
||||||
attr_reader :viewport, :position, :velocity, :zoom, :drag
|
attr_reader :viewport, :position, :velocity, :zoom, :drag
|
||||||
|
|
||||||
def initialize(viewport:, scroll_speed: 10, position: CyberarmEngine::Vector.new(0.0, 0.0))
|
def initialize(viewport:, scroll_speed: 10, position: CyberarmEngine::Vector.new(0.0, 0.0))
|
||||||
@viewport = CyberarmEngine::BoundingBox.new(viewport[0], viewport[1], viewport[2], viewport[3])
|
@viewport = CyberarmEngine::BoundingBox.new(viewport[0], viewport[1], viewport[2], viewport[3])
|
||||||
@scroll_speed = scroll_speed
|
@scroll_speed = scroll_speed
|
||||||
@@ -15,7 +16,9 @@ class IMICRTS
|
|||||||
@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
|
||||||
end
|
end
|
||||||
|
|
||||||
def window; $window; end
|
def window;
|
||||||
|
$window;
|
||||||
|
end
|
||||||
|
|
||||||
def draw(&block)
|
def draw(&block)
|
||||||
if block
|
if block
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ class IMICRTS
|
|||||||
|
|
||||||
def tick(tick_id)
|
def tick(tick_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def on_order(type, order)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,16 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def on_order(type, order)
|
||||||
|
case type
|
||||||
|
when IMICRTS::Order::MOVE
|
||||||
|
@parent.target = order.vector
|
||||||
|
when IMICRTS::Order::STOP
|
||||||
|
@parent.target = nil
|
||||||
|
@pathfinder = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def rotate_towards(vector)
|
def rotate_towards(vector)
|
||||||
angle = Gosu.angle(@parent.position.x, @parent.position.y, vector.x, vector.y)
|
angle = Gosu.angle(@parent.position.x, @parent.position.y, vector.x, vector.y)
|
||||||
a = (360.0 + (angle - @parent.angle)) % 360.0
|
a = (360.0 + (angle - @parent.angle)) % 360.0
|
||||||
@@ -34,7 +44,7 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def follow_path
|
def follow_path
|
||||||
if @pathfinder && node = @pathfinder.path_current_node
|
if @pathfinder && (node = @pathfinder.path_current_node)
|
||||||
@pathfinder.path_next_node if @pathfinder.at_current_path_node?(@parent)
|
@pathfinder.path_next_node if @pathfinder.at_current_path_node?(@parent)
|
||||||
@parent.position -= (@parent.position.xy - (node.tile.position + @parent.director.map.tile_size / 2).xy).normalized * @parent.speed
|
@parent.position -= (@parent.position.xy - (node.tile.position + @parent.director.map.tile_size / 2).xy).normalized * @parent.speed
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Spawner < Component
|
class Spawner < Component
|
||||||
|
attr_accessor :spawnpoint
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@spawnpoint = @parent.position.clone
|
||||||
|
@spawnpoint.y += 64
|
||||||
|
end
|
||||||
|
|
||||||
def tick(tick_id)
|
def tick(tick_id)
|
||||||
item = @parent.component(:build_queue).queue.first
|
item = @parent.component(:build_queue).queue.first
|
||||||
|
|
||||||
@@ -12,5 +19,15 @@ class IMICRTS
|
|||||||
item.completed = true
|
item.completed = true
|
||||||
@parent.director.schedule_order(IMICRTS::Order::BUILD_UNIT_COMPLETE, @parent.player.id, @parent.id)
|
@parent.director.schedule_order(IMICRTS::Order::BUILD_UNIT_COMPLETE, @parent.player.id, @parent.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def on_order(type, order)
|
||||||
|
case type
|
||||||
|
when IMICRTS::Order::BUILD_UNIT_COMPLETE
|
||||||
|
item = @parent.component(:build_queue).queue.shift
|
||||||
|
|
||||||
|
ent = @parent.director.spawn_entity(player_id: @parent.player.id, name: item.entity.name, position: @spawnpoint)
|
||||||
|
ent.target = @parent.component(:waypoint).waypoint if @parent.component(:waypoint)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -33,6 +33,13 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def on_order(type, order)
|
||||||
|
case type
|
||||||
|
when IMICRTS::Order::CONSTRUCTION_COMPLETE
|
||||||
|
data.construction_complete = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def construction_complete?
|
def construction_complete?
|
||||||
data.construction_progress >= data.construction_goal && data.construction_complete
|
data.construction_progress >= data.construction_goal && data.construction_complete
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class IMICRTS
|
|||||||
class Waypoint < Component
|
class Waypoint < Component
|
||||||
def setup
|
def setup
|
||||||
@waypoint = @parent.position.clone
|
@waypoint = @parent.position.clone
|
||||||
@waypoint.y += @parent.director.map.tile_size
|
@waypoint.y += @parent.director.map.tile_size * 2
|
||||||
@waypoint_color = 0xffffff00
|
@waypoint_color = 0xffffff00
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ IMICRTS::Entity.define_entity(:helipad, :structure, 1_000, 100, "Builds and rear
|
|||||||
entity.has(:spawner)
|
entity.has(:spawner)
|
||||||
entity.has(:build_queue)
|
entity.has(:build_queue)
|
||||||
entity.has(:sidebar_actions)
|
entity.has(:sidebar_actions)
|
||||||
|
|
||||||
|
entity.component(:spawner).spawnpoint = entity.position.clone
|
||||||
entity.component(:sidebar_actions).add(:add_to_build_queue, { entity: :helicopter })
|
entity.component(:sidebar_actions).add(:add_to_build_queue, { entity: :helicopter })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -35,4 +35,15 @@ IMICRTS::Entity.define_entity(:refinery, :structure, 1_400, 200, "Generates cred
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
entity.on_order do |type, order|
|
||||||
|
case type
|
||||||
|
when IMICRTS::Order::CONSTRUCTION_COMPLETE
|
||||||
|
pos = entity.position.clone
|
||||||
|
pos.x += 32
|
||||||
|
pos.y += 64
|
||||||
|
|
||||||
|
entity.director.spawn_entity(player_id: entity.player.id, name: :harvester, position: pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ IMICRTS::Entity.define_entity(:helicopter, :unit, 400, 40, "Attacks ground targe
|
|||||||
entity.radius = 14
|
entity.radius = 14
|
||||||
entity.movement = :air
|
entity.movement = :air
|
||||||
entity.max_health = 100.0
|
entity.max_health = 100.0
|
||||||
|
entity.position.z = IMICRTS::ZOrder::AIR_VEHICLE
|
||||||
|
|
||||||
entity.body_image = "vehicles/helicopter/helicopter.png"
|
entity.body_image = "vehicles/helicopter/helicopter.png"
|
||||||
entity.shell_image = "vehicles/helicopter/helicopter_shell.png"
|
entity.shell_image = "vehicles/helicopter/helicopter_shell.png"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :director, :player, :id, :name, :type, :data, :proto_entity
|
attr_reader :director, :player, :id, :name, :type, :data, :proto_entity
|
||||||
attr_accessor :position, :angle, :radius, :target, :state, :movement, :health, :max_health,
|
attr_accessor :position, :angle, :sight_radius, :range_radius, :radius, :target, :state, :movement, :health, :max_health,
|
||||||
:speed, :turret, :center, :scale, :particle_emitters, :color
|
:speed, :turret, :center, :scale, :particle_emitters, :color
|
||||||
|
|
||||||
def initialize(name:, player:, id:, position:, angle:, director:, proto_entity: false)
|
def initialize(name:, player:, id:, position:, angle:, director:, proto_entity: false)
|
||||||
@@ -169,6 +169,18 @@ class IMICRTS
|
|||||||
@on_tick = block
|
@on_tick = block
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def on_order(&block)
|
||||||
|
@on_order = block
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_order(type, order)
|
||||||
|
@components.each do |key, comp|
|
||||||
|
comp.on_order(type, order)
|
||||||
|
end
|
||||||
|
|
||||||
|
@on_order&.call(type, order)
|
||||||
|
end
|
||||||
|
|
||||||
def selected_draw
|
def selected_draw
|
||||||
draw_radius
|
draw_radius
|
||||||
draw_gizmos
|
draw_gizmos
|
||||||
|
|||||||
36
lib/map.rb
36
lib/map.rb
@@ -1,6 +1,7 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Map
|
class Map
|
||||||
attr_reader :tile_size, :tiles, :ores, :spawnpoints, :width, :height
|
attr_reader :tile_size, :tiles, :ores, :spawnpoints, :width, :height
|
||||||
|
|
||||||
def initialize(map_file:)
|
def initialize(map_file:)
|
||||||
@tiled_map = TiledMap.new(map_file)
|
@tiled_map = TiledMap.new(map_file)
|
||||||
|
|
||||||
@@ -26,11 +27,10 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_terrain(x, y, tile_id)
|
def add_terrain(x, y, tile_id)
|
||||||
if tile = @tiled_map.get_tile(tile_id - 1)
|
if (tile = @tiled_map.get_tile(tile_id - 1))
|
||||||
_tile = Tile.new(
|
_tile = Tile.new(
|
||||||
position: CyberarmEngine::Vector.new(x * @tile_size, y * @tile_size, ZOrder::TILE),
|
position: CyberarmEngine::Vector.new(x * @tile_size, y * @tile_size, ZOrder::TILE),
|
||||||
image: tile.image,
|
image: tile.image,
|
||||||
visible: true,
|
|
||||||
type: tile.data.type.to_sym,
|
type: tile.data.type.to_sym,
|
||||||
tile_size: @tile_size
|
tile_size: @tile_size
|
||||||
)
|
)
|
||||||
@@ -43,11 +43,10 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_ore(x, y, tile_id)
|
def add_ore(x, y, tile_id)
|
||||||
if tile = @tiled_map.get_tile(tile_id - 1)
|
if (tile = @tiled_map.get_tile(tile_id - 1))
|
||||||
_ore = Tile.new(
|
_ore = Tile.new(
|
||||||
position: CyberarmEngine::Vector.new(x * @tile_size, y * @tile_size, ZOrder::ORE),
|
position: CyberarmEngine::Vector.new(x * @tile_size, y * @tile_size, ZOrder::ORE),
|
||||||
image: tile.image,
|
image: tile.image,
|
||||||
visible: true,
|
|
||||||
type: nil,
|
type: nil,
|
||||||
tile_size: @tile_size
|
tile_size: @tile_size
|
||||||
)
|
)
|
||||||
@@ -57,8 +56,8 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw(camera)
|
def draw(observer)
|
||||||
visible_tiles(camera).each do |tile|
|
visible_tiles(observer).each do |tile|
|
||||||
tile.image.draw(tile.position.x, tile.position.y, tile.position.z)
|
tile.image.draw(tile.position.x, tile.position.y, tile.position.z)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -84,10 +83,11 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible_tiles(camera)
|
def visible_tiles(observer)
|
||||||
_tiles = []
|
_tiles = []
|
||||||
|
visiblity_map = observer.visiblity_map
|
||||||
|
|
||||||
top_left = (camera.center - camera.position) - CyberarmEngine::Vector.new($window.width / 2, $window.height / 2) / camera.zoom
|
top_left = (observer.camera.center - observer.camera.position) - CyberarmEngine::Vector.new($window.width / 2, $window.height / 2) / observer.camera.zoom
|
||||||
top_left /= @tile_size
|
top_left /= @tile_size
|
||||||
|
|
||||||
top_left.x = top_left.x.floor
|
top_left.x = top_left.x.floor
|
||||||
@@ -95,8 +95,8 @@ class IMICRTS
|
|||||||
|
|
||||||
|
|
||||||
# +1 to overdraw a bit to hide pop-in
|
# +1 to overdraw a bit to hide pop-in
|
||||||
_width = ((($window.width / @tile_size) + 2) / camera.zoom).ceil
|
_width = ((($window.width / @tile_size) + 2) / observer.camera.zoom).ceil
|
||||||
_height = ((($window.height / @tile_size) + 2) / camera.zoom).ceil
|
_height = ((($window.height / @tile_size) + 2) / observer.camera.zoom).ceil
|
||||||
|
|
||||||
_height.times do |y|
|
_height.times do |y|
|
||||||
_width.times do |x|
|
_width.times do |x|
|
||||||
@@ -104,12 +104,14 @@ class IMICRTS
|
|||||||
next if _x < 0 || _x > @width
|
next if _x < 0 || _x > @width
|
||||||
next if _y < 0 || _y > @height
|
next if _y < 0 || _y > @height
|
||||||
|
|
||||||
if tile = tile_at(_x, _y)
|
visible = visiblity_map.visible?(_x, _y)
|
||||||
_tiles.push(tile) if tile.visible
|
|
||||||
|
if (tile = tile_at(_x, _y))
|
||||||
|
_tiles.push(tile) if visible
|
||||||
end
|
end
|
||||||
|
|
||||||
if ore = ore_at(_x, _y)
|
if (ore = ore_at(_x, _y))
|
||||||
_tiles.push(ore) if ore.visible
|
_tiles.push(ore) if visible
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -130,15 +132,15 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
class Tile
|
class Tile
|
||||||
attr_accessor :position, :grid_position, :image, :visible, :entity, :reserved, :type
|
attr_accessor :position, :grid_position, :image, :entity, :reserved, :type
|
||||||
def initialize(position:, image:, visible:, type:, tile_size:)
|
|
||||||
|
def initialize(position:, image:, type:, tile_size:)
|
||||||
@position = position
|
@position = position
|
||||||
@grid_position = position.clone
|
@grid_position = position.clone
|
||||||
@grid_position /= tile_size
|
@grid_position /= tile_size
|
||||||
@grid_position.x, @grid_position.y = @grid_position.x.floor, @grid_position.y.floor
|
@grid_position.x, @grid_position.y = @grid_position.x.floor, @grid_position.y.floor
|
||||||
|
|
||||||
@image = image
|
@image = image
|
||||||
@visible = visible
|
|
||||||
@entity = nil
|
@entity = nil
|
||||||
@reserved = nil
|
@reserved = nil
|
||||||
@type = type
|
@type = type
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
IMICRTS::Order.define_handler(IMICRTS::Order::BUILD_UNIT_COMPLETE, arguments: [:player_id, :entity_id]) do |order, director|
|
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)
|
entity = director.player(order.player_id).entity(order.entity_id)
|
||||||
item = entity.component(:build_queue).queue.shift
|
|
||||||
|
|
||||||
spawn_point = entity.position.clone
|
entity.handle_order(IMICRTS::Order::BUILD_UNIT_COMPLETE, order)
|
||||||
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
|
end
|
||||||
|
|
||||||
IMICRTS::Order.define_serializer(IMICRTS::Order::BUILD_UNIT_COMPLETE) do |order, director|
|
IMICRTS::Order.define_serializer(IMICRTS::Order::BUILD_UNIT_COMPLETE) do |order, director|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
IMICRTS::Order.define_handler(IMICRTS::Order::CONSTRUCTION_COMPLETE, arguments: [:player_id, :entity_id]) do |order, director|
|
IMICRTS::Order.define_handler(IMICRTS::Order::CONSTRUCTION_COMPLETE, arguments: [:player_id, :entity_id]) do |order, director|
|
||||||
entity = director.player(order.player_id).entity(order.entity_id)
|
entity = director.player(order.player_id).entity(order.entity_id)
|
||||||
|
|
||||||
entity.component(:structure).data.construction_complete = true
|
entity.handle_order(IMICRTS::Order::CONSTRUCTION_COMPLETE, order)
|
||||||
end
|
end
|
||||||
|
|
||||||
IMICRTS::Order.define_serializer(IMICRTS::Order::CONSTRUCTION_COMPLETE) do |order, director|
|
IMICRTS::Order.define_serializer(IMICRTS::Order::CONSTRUCTION_COMPLETE) do |order, director|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
IMICRTS::Order.define_handler(IMICRTS::Order::MOVE, arguments: [:player_id, :vector]) do |order, director|
|
IMICRTS::Order.define_handler(IMICRTS::Order::MOVE, arguments: [:player_id, :vector]) do |order, director|
|
||||||
director.player(order.player_id).selected_entities.each do |entity|
|
director.player(order.player_id).selected_entities.each do |entity|
|
||||||
entity.target = order.vector
|
entity.handle_order(IMICRTS::Order::MOVE, order)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
IMICRTS::Order.define_handler(IMICRTS::Order::STOP, arguments: [:player_id]) do |order, director|
|
IMICRTS::Order.define_handler(IMICRTS::Order::STOP, arguments: [:player_id]) do |order, director|
|
||||||
director.player(order.player_id).selected_entities.each do |entity|
|
director.player(order.player_id).selected_entities.each do |entity|
|
||||||
entity.target = nil
|
entity.handle_order(IMICRTS::Order::STOP, order)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Player
|
class Player
|
||||||
attr_reader :id, :name, :color, :team, :entities, :orders, :camera, :spawnpoint
|
attr_reader :id, :name, :color, :team, :bot, :visiblity_map, :entities, :orders, :camera, :spawnpoint
|
||||||
attr_reader :selected_entities
|
attr_reader :selected_entities
|
||||||
def initialize(id:, spawnpoint:, name: nil, color: IMICRTS::TeamColors.values.sample, team: nil)
|
|
||||||
|
def initialize(id:, spawnpoint:, name: nil, color: IMICRTS::TeamColors.values.sample, team: nil, bot: false, visiblity_map:)
|
||||||
@id = id
|
@id = id
|
||||||
@spawnpoint = spawnpoint
|
@spawnpoint = spawnpoint
|
||||||
@name = name ? name : "Novice-#{id}"
|
@name = name ? name : "Novice-#{id}"
|
||||||
@color = color
|
@color = color
|
||||||
@team = team
|
@team = team
|
||||||
|
@bot = bot
|
||||||
|
@visiblity_map = visiblity_map
|
||||||
|
|
||||||
@entities = []
|
@entities = []
|
||||||
@orders = []
|
@orders = []
|
||||||
@@ -24,7 +27,7 @@ class IMICRTS
|
|||||||
@camera_moved = (@last_camera_position - @camera.position.clone).sum > @camera_move_threshold
|
@camera_moved = (@last_camera_position - @camera.position.clone).sum > @camera_move_threshold
|
||||||
@last_camera_position = @camera.position.clone
|
@last_camera_position = @camera.position.clone
|
||||||
|
|
||||||
@entities.each { |ent| ent.tick(tick_id) }
|
@entities.each { |ent| ent.tick(tick_id); @visiblity_map.update(ent) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@@ -45,6 +48,7 @@ class IMICRTS
|
|||||||
|
|
||||||
class ScheduledOrder
|
class ScheduledOrder
|
||||||
attr_reader :order_id, :tick_id, :serialized_order
|
attr_reader :order_id, :tick_id, :serialized_order
|
||||||
|
|
||||||
def initialize(order_id, tick_id, serialized_order)
|
def initialize(order_id, tick_id, serialized_order)
|
||||||
@order_id = order_id
|
@order_id = order_id
|
||||||
@tick_id, @serialized_order = tick_id, serialized_order
|
@tick_id, @serialized_order = tick_id, serialized_order
|
||||||
|
|||||||
@@ -13,12 +13,18 @@ class IMICRTS
|
|||||||
|
|
||||||
@director = Director.new(game: self, map: @options[:map], networking_mode: @options[:networking_mode])
|
@director = Director.new(game: self, map: @options[:map], networking_mode: @options[:networking_mode])
|
||||||
@options[:players] ||= [
|
@options[:players] ||= [
|
||||||
{ id: 0, team: 1, spawnpoint: @director.map.spawnpoints.last, color: :orange },
|
{ id: 0, team: 1, spawnpoint: @director.map.spawnpoints.last, color: :orange, bot: false },
|
||||||
{ id: 1, team: 2, spawnpoint: @director.map.spawnpoints.first, color: :lightblue }
|
{ id: 1, team: 2, spawnpoint: @director.map.spawnpoints.first, color: :lightblue, bot: :brutal }
|
||||||
]
|
]
|
||||||
|
|
||||||
@options[:players].each do |pl|
|
@options[:players].each do |pl|
|
||||||
player = Player.new(id: pl[:id], spawnpoint: pl[:spawnpoint], team: pl[:team], color: TeamColors[pl[:color]])
|
player = nil
|
||||||
|
visiblity_map = VisibilityMap.new(width: @director.map.width, height: @director.map.height, tile_size: @director.map.tile_size)
|
||||||
|
unless pl[:bot]
|
||||||
|
player = Player.new(id: pl[:id], spawnpoint: pl[:spawnpoint], team: pl[:team], color: TeamColors[pl[:color]], visiblity_map: visiblity_map)
|
||||||
|
else
|
||||||
|
player = AIPlayer.new(id: pl[:id], spawnpoint: pl[:spawnpoint], team: pl[:team], color: TeamColors[pl[:color]], bot: pl[:bot], visiblity_map: visiblity_map)
|
||||||
|
end
|
||||||
@player = player if player.id == @options[:local_player_id]
|
@player = player if player.id == @options[:local_player_id]
|
||||||
@director.add_player(player)
|
@director.add_player(player)
|
||||||
end
|
end
|
||||||
@@ -82,7 +88,7 @@ class IMICRTS
|
|||||||
super
|
super
|
||||||
|
|
||||||
@player.camera.draw do
|
@player.camera.draw do
|
||||||
@director.map.draw(@player.camera)
|
@director.map.draw(@player)
|
||||||
@director.entities.each(&:draw)
|
@director.entities.each(&:draw)
|
||||||
@selected_entities.each(&:selected_draw)
|
@selected_entities.each(&:selected_draw)
|
||||||
|
|
||||||
|
|||||||
@@ -48,25 +48,12 @@ class IMICRTS
|
|||||||
return if @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
|
return if @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
|
||||||
|
|
||||||
tile = @director.map.tile_at(vector.x, vector.y)
|
tile = @director.map.tile_at(vector.x, vector.y)
|
||||||
pp vector
|
|
||||||
return unless tile
|
return unless tile
|
||||||
position = tile.position + @director.map.tile_size / 2
|
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)
|
|
||||||
# )
|
|
||||||
|
|
||||||
@director.schedule_order(Order::CONSTRUCT, @player.id, vector, @entity)
|
@director.schedule_order(Order::CONSTRUCT, @player.id, vector, @entity)
|
||||||
|
|
||||||
# each_tile(vector) do |tile, space_required|
|
|
||||||
# if space_required == true
|
|
||||||
# tile.entity = ent
|
|
||||||
# else
|
|
||||||
# tile.reserved = ent
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
cancel_tool
|
cancel_tool
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
36
lib/visiblity_map.rb
Normal file
36
lib/visiblity_map.rb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
class IMICRTS
|
||||||
|
class VisibilityMap
|
||||||
|
attr_reader :width, :height, :tile_size
|
||||||
|
|
||||||
|
def initialize(width:, height:, tile_size:)
|
||||||
|
@width = width
|
||||||
|
@height = height
|
||||||
|
@tile_size = tile_size
|
||||||
|
|
||||||
|
@map = Array.new(width * height, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
def visible?(x, y)
|
||||||
|
@map.dig(index_at(x, y))
|
||||||
|
end
|
||||||
|
|
||||||
|
def index_at(x, y)
|
||||||
|
((y.clamp(0, @height - 1) * @width) + x.clamp(0, @width - 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
def update(entity)
|
||||||
|
range = entity.sight_radius
|
||||||
|
pos = entity.position.clone / @tile_size
|
||||||
|
pos.x = pos.x.ceil - range
|
||||||
|
pos.y = pos.y.ceil - range
|
||||||
|
|
||||||
|
(range * 2).times do |y|
|
||||||
|
(range * 2).times do |x|
|
||||||
|
if not visible?(pos.x + x, pos.y + y).nil?
|
||||||
|
@map[index_at(pos.x + x, pos.y + y)] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
BIN
screenshots/screenshot-game.png
Normal file
BIN
screenshots/screenshot-game.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 532 KiB |
Reference in New Issue
Block a user