/*
* minigamemanager.h - Author: Enar Vaikene
*
* Copyright (C) 2006 Atomic Blue (info@planeshift.it, http://www.atomicblue.org)
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation (version 2 of the License)
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __MINIGAMEMANAGER_H
#define __MINIGAMEMANAGER_H
#include "net/messages.h" // Message definitions
#include "net/msghandler.h" // Network access
#include "msgmanager.h" // Parent class
#include "gem.h"
class Client;
class psMiniGameManager;
/**
* Wrapper class for the game board layout buffer.
*/
class psMiniGameBoard
{
public:
psMiniGameBoard();
~psMiniGameBoard();
/// Sets up the game board layout.
void Setup(int8_t newCols, int8_t newRows, uint8_t *newLayout, uint8_t newNUmPieces, uint8_t *newPieces);
/// Returns the number of columns.
int8_t GetCols() const { return cols; }
/// Returns the number of rows.
int8_t GetRows() const { return rows; }
/// Returns the packed game board layout.
uint8_t *GetLayout() const { return layout; };
/// Returns the number of available pieces.
uint8_t GetNumPieces() const { return numPieces; }
/// Returns the package list of available pieces.
uint8_t *GetPieces() const { return pieces; }
/// Gets the tile state from the specified column and row.
uint8_t Get(int8_t col, int8_t row) const;
/// Sets the tile state at the specified column and row.
void Set(int8_t col, int8_t row, uint8_t state);
protected:
/// The current game board layout with tiles and pieces.
uint8_t *layout;
/// The number of columns.
int8_t cols;
/// The number of rows.
int8_t rows;
/// The number of available pieces.
uint8_t numPieces;
/// The package list of available gane pieces.
uint8_t *pieces;
};
/**
* Implements one minigame session.
*
* Game sessions are bound to a game board (action location) and identified
* by a unique name. The name of the game board is defined in the action_locations table (name field).
*
* The game itself is defined in the response string. The string is expected to have the
* following format:
*
*
* Description as seen by players
*
*
* The Layout attribute defines the layout of the game board and optionally also preset game
* pieces on it.
*
* The Pieces attribute defines the available game pieces. Clients can use only the pieces that are
* defined in the Pieces attribute.
*
* In the future we will add more attributes like for game options and name of a plugin or
* script for managed games.
* Every session can have 0, 1, 2 or more players attached to it. The first player
* gets white game pieces and the second player black game pieces. All other players
* can just watch the game.
*/
class psMiniGameSession : public iDeleteObjectCallback
{
public:
psMiniGameSession(psMiniGameManager *mng, gemActionLocation *obj, const char *name);
~psMiniGameSession();
/// Returns the game session ID
const uint32_t GetID() const { return id; }
/// Returns the session name.
const csString& GetName() const { return name; }
/// Returns the game options.
uint16_t GetOptions() const { return options; }
/**
* Loads the game.
* @param[in] responseString The string with minigame options and board layout.
* @return Returns true if the game was loaded and false if not.
*
* The Load() function loads the game from the given action location response string.
*/
bool Load(csString &responseString);
/// Restarts the game.
void Restart();
/// Adds a player to the session.
void AddPlayer(Client *client);
/// Removes a player from the session.
void RemovePlayer(Client *client);
/// Returns true if it is valid for this player to update the game board.
bool IsValidToUpdate(Client *client) const;
/// Updates the game board. NB! Call IsValidToUpdate() first to verify that updating is valid.
void Update(Client *client, psMGUpdateMessage &msg);
/**
* Sends the current game board to the given player.
* @param[in] clientID The ID of the client.
* @param[in] modOptions Modifier for game options.
*/
void Send(uint32_t clientID, uint32_t modOptions);
/// Broadcast the current game board layout to all the players/watchers.
void Broadcast();
/// Handles disconnected players.
virtual void DeleteObjectCallback(iDeleteNotificationObject * object);
/// Checks for idle players and players too far away
void Idle();
protected:
/// Game manager.
psMiniGameManager *manager;
/// The game session ID (equals to the action location ID)
uint32_t id;
/// The game session name.
csString name;
/// Action location object
csWeakRef actionObject;
/// Game options
uint16_t options;
/// The player with white game pieces.
uint32_t whitePlayerID;
/// Idle counter for the player with white pieces.
int whiteIdleCounter;
/// The player with black game pieces.
uint32_t blackPlayerID;
/// Idle counter for the player with black pieces.
int blackIdleCounter;
/// Watchers.
csArray watchers;
/// Current message counter for versionin.
uint8_t currentCounter;
/// The current game board.
psMiniGameBoard gameBoard;
};
/**
* This manager handles minigame sessions.
*/
class psMiniGameManager : public MessageManager
{
public:
psMiniGameManager();
~psMiniGameManager();
virtual void HandleMessage(MsgEntry *me, Client *client);
psMiniGameSession *GetSessionByID(uint32_t id);
/// Idle function to check for idle players and players too far away.
void Idle();
protected:
void HandleStartGameRequest(Client *client);
void HandleStopGameRequest(Client *client);
void HandleGameUpdate(Client *client, psMGUpdateMessage &msg);
/// Game sessions.
csPDelArray sessions;
/// Maps players to game sessions for quicker access.
csHash playerSessions;
};
#endif