181 lines
4.8 KiB
Ruby
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
|