Inital work on gamesaves/replays

This commit is contained in:
2021-01-15 21:25:55 -06:00
parent f6f2de1433
commit 37bab6ae3d
6 changed files with 80 additions and 16 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,5 @@
data/settings.json
data/replays/*.replay
data/saves/*.save
data/replays/*.dat
data/saves/*.dat
doc/
.yardoc/

View File

@@ -8,6 +8,7 @@ end
require "json"
require "socket"
require "digest/sha2"
require "nokogiri"
@@ -20,6 +21,7 @@ require_relative "lib/camera"
require_relative "lib/setting"
require_relative "lib/team_colors"
require_relative "lib/constants"
require_relative "lib/game_save"
require_relative "lib/states/boot"
require_relative "lib/states/game"

View File

@@ -2,7 +2,7 @@ class IMICRTS
class Director
attr_reader :current_tick, :map, :game, :players
def initialize(game:, map:, players: [], networking_mode:, tick_rate: 10, local_game: true, replay: false)
def initialize(game:, map:, players:, networking_mode:, tick_rate: 15, local_game: true, replay: false, game_save: false, gamesave_file: nil)
@game = game
@map = map
@players = players
@@ -11,6 +11,10 @@ class IMICRTS
@tick_rate = tick_rate
@local_game = local_game
@replay = replay
@game_save = game_save
@gamesave_file = gamesave_file ? gamesave_file : "#{IMICRTS::GAME_ROOT_PATH}/data/saves/savegame_#{Time.now.to_i}.dat"
@game_save_host = GameSave.new(mode: :write, gamesave_file: @gamesave_file, players: players, map_file: @map.map_file, gamesave: true)
@game_save_host.write_header
@last_tick_at = Gosu.milliseconds
@tick_time = 1000.0 / @tick_rate
@@ -25,8 +29,8 @@ class IMICRTS
@replay
end
def add_player(player)
@players << player
def game_save?
@game_save
end
def update
@@ -35,6 +39,7 @@ class IMICRTS
tick
@connection.update
@game_save_host&.feed_tick(@current_tick) if @replay
end
@players.each { |player| player.update }
@@ -58,6 +63,7 @@ class IMICRTS
order_args = o.deserialize(order_data[1..order_data.length - 1], self)
execute_order(o.id, *order_args)
@game_save_host&.write_order(order_data) unless @replay
player.orders.delete(order)
@@ -140,6 +146,7 @@ class IMICRTS
def finalize
@server&.stop
@connection&.finalize
@game_save_host&.finalize
end
end
end

50
lib/game_save.rb Normal file
View File

@@ -0,0 +1,50 @@
class IMICRTS
class GameSave
def initialize(mode:, gamesave_file:, map_file: nil, players: nil, gamesave: false, player_id: nil)
@mode = mode
@gamesave_file = File.open(gamesave_file, "#{@mode == :write ? 'w' : 'r'}")
@map_file = map_file
@players = players
@gamesave = gamesave
@player_id = player_id
@version = IMICRTS::VERSION
end
def parse
#
end
def feed_tick(tick_id)
end
def write_header
player_data = @players.map do |player|
{
id: player.id,
name: player.name,
team: player.team,
spawnpoint: player.spawnpoint,
color: player.color&.gl,
bot: player.bot
}
end
s = %{#{@version}
#{@map_file}?#{Digest::SHA256.digest(File.read("#{IMICRTS::GAME_ROOT_PATH}/assets/#{@map_file}"))}
#{@gamesave ? "GAMESAVE?#{@player_id}" : "REPLAY"}
#{JSON.dump(player_data)}}
@gamesave_file.puts(s)
end
def write_order(raw_order)
@gamesave_file.puts(raw_order)
end
def finalize
@gamesave_file&.close
end
end
end

View File

@@ -1,8 +1,9 @@
class IMICRTS
class Map
attr_reader :tile_size, :tiles, :ores, :spawnpoints, :width, :height
attr_reader :tile_size, :tiles, :ores, :spawnpoints, :width, :height, :map_file
def initialize(map_file:)
@map_file = map_file
@tiled_map = TiledMap.new(map_file)
@width = @tiled_map.width

View File

@@ -11,24 +11,26 @@ class IMICRTS
@options[:map] ||= Map.new(map_file: "maps/test_map.tmx")
@options[:local_player_id] ||= 0
@director = Director.new(game: self, map: @options[:map], networking_mode: @options[:networking_mode])
@options[:players] ||= [
{ id: 0, team: 1, spawnpoint: @director.map.spawnpoints.last, color: :orange, bot: false },
{ id: 1, team: 2, spawnpoint: @director.map.spawnpoints.first, color: :lightblue, bot: :brutal }
{ id: 0, name: "0xdeadbeef", team: 1, spawnpoint: "B", color: :orange, bot: false },
{ id: 1, name: "BrutalAI", team: 2, spawnpoint: "A", color: :lightblue, bot: :brutal }
]
@options[:players].each do |pl|
players = @options[:players].map do |pl|
player = nil
visiblity_map = VisibilityMap.new(width: @director.map.width, height: @director.map.height, tile_size: @director.map.tile_size)
visiblity_map = VisibilityMap.new(width: @options[:map].width, height: @options[:map].height, tile_size: @options[: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)
player = Player.new(id: pl[:id], name: pl[:name], 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)
player = AIPlayer.new(id: pl[:id], name: pl[:name], 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]
@director.add_player(player)
player
end
@director = Director.new(game: self, players: players, map: @options[:map], networking_mode: @options[:networking_mode])
@selected_entities = []
@tool = set_tool(:entity_controller)
@overlays = []
@@ -61,9 +63,11 @@ class IMICRTS
end
@director.players.each do |player|
spawnpoint = @director.map.spawnpoints[player.spawnpoint.bytes.first - 65]
construction_yard = @director.spawn_entity(
player_id: player.id, name: :construction_yard,
position: CyberarmEngine::Vector.new(player.spawnpoint.x, player.spawnpoint.y, ZOrder::BUILDING)
position: CyberarmEngine::Vector.new(spawnpoint.x, spawnpoint.y, ZOrder::BUILDING)
)
construction_yard.component(:structure).data.construction_progress = Entity.get(construction_yard.name).build_steps
construction_yard.component(:structure).data.construction_complete = true
@@ -77,7 +81,7 @@ class IMICRTS
@director.spawn_entity(
player_id: player.id, name: :construction_worker,
position: CyberarmEngine::Vector.new(player.spawnpoint.x - 64, player.spawnpoint.y + 64, ZOrder::GROUND_VEHICLE)
position: CyberarmEngine::Vector.new(construction_yard.position.x - 64, construction_yard.position.y + 64, ZOrder::GROUND_VEHICLE)
)
end