Files
space_game_server/lib/game/player.rb
T

181 lines
4.8 KiB
Ruby

# 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<Building>] list of buildings.
def all_buildings
@buildings
end
# Returns all researched technology for the player.
# @return [Array<String>] list of researched tech.
def all_tech
@researched_tech
end
end
# Errors for the player
class PlayerError < StandardError
end