# Represents a player in the game. # Tracks resources, owned planets, ships, and researched technology. require 'securerandom' require 'yaml' # A player object for the class Game class Player attr_accessor :player_resources, :player_id, :player_planets, :player_ships, :faction, :researched_tech, :buildings, :ship_build_power, :research_tech_build_power, :military_tech_build_power # Create a new player. Default values are stored in the game_config.yaml file. # @param player_id [String] An ID used to validate the player. # @param faction [String] The faction that the player should start as. Should be \`good\` or \`evil\` def initialize(player_id, faction) @player_id = player_id @player_planets = [] @player_ships = [] @home_planet = nil @researched_tech = [] @buildings = [] @ship_build_power = 0 @research_tech_build_power = 0 @military_tech_build_power = 0 # Validate faction: if !(['good', 'evil'].include? faction) raise PlayerError, 'Faction must be \`good\` or \`evil\`' end @faction = faction end def set_resources(credits, metal, crystals, fuel) @player_resources = { 'credits' => credits, 'metal' => metal, 'crystals' => crystals, 'fuel' => fuel, } end # Connect a player # # @param client [TCPSocket] The socket used to communicate with the player def connect(client) @socket = client end # Returns if the player is connected or not def connected? if @socket.nil? return false elsif @socket.closed? return false end return true end # Allows a player to claim a planet. # # @param planet def claim_planet(planet) if planet.claimable? @player_planets.append(planet) planet.claim(self) end end # Makes a planet the player's home planet # # @param planet def make_home_planet(planet) if planet.owner == self @home_planet = planet else return {'type' => 'error', 'payload' => 'Planet must be owned by the player'} end end # Create an update to send out def update(request_id) planet_data = [] @player_planets.each do |planet| planet_data.append(planet.info_update()) end { 'type' => 'update', 'domain' => 'player', 'request_id' => request_id, 'payload' => { 'resources' => @player_resources, 'planets' => planet_data, 'ships' => @player_ships } } end # Used to send regular updates for the game data. def send_update # Send an update of all of the player data and stuff return if !connected? begin @socket.puts(update(nil).to_json) rescue @socket.close end end # Save a player to a file through marshaling it. def save_to_file File.open("game_data/#{@player_id}_player_.save", 'wb') do |fi| # Load resources for the player: fi.write(Marshal.dump(self)) end return @player_id end # Load a player from a file. Requires the player id to load with as that is # the file name. def self.load_from_save(player_id) File.open("game_data/#{player_id}_player_.save", 'rb') do |fi| # Load resources for the player: Marshal.load(fi.read) end end # Custom funciton to dump marshal data for players. We do not want to try to # dump the socket... def marshal_dump { player_id: @player_id, player_planets: @player_planets, player_ships: @player_ships, home_planet: @home_planet, faction: @faction, player_resources: @player_resources, researched_tech: @researched_tech, buildings: @buildings, ship_build_power: @ship_build_power, research_tech_build_power: @research_tech_build_power, military_tech_build_power: @military_tech_build_power } end # Custom function to load the marshaled data for the player. # # @param data [Hash] A hash containing the data. def marshal_load(data) @player_id = data[:player_id] @player_planets = data[:player_planets] @player_ships = data[:player_ships] @home_planet = data[:home_planet] @faction = data[:faction] @player_resources = data[:player_resources] @researched_tech = data[:researched_tech] || [] @buildings = data[:buildings] || [] @ship_build_power = data[:ship_build_power] || 0 @research_tech_build_power = data[:research_tech_build_power] || 0 @military_tech_build_power = data[:military_tech_build_power] || 0 end # Returns all buildings owned by the player. # @return [Array] list of buildings. def all_buildings @buildings end # Returns all researched technology for the player. # @return [Array] list of researched tech. def all_tech @researched_tech end end # Errors for the player class PlayerError < StandardError end