summaryrefslogtreecommitdiffstats
path: root/libkdegames/kgame/kplayer.h
diff options
context:
space:
mode:
Diffstat (limited to 'libkdegames/kgame/kplayer.h')
-rw-r--r--libkdegames/kgame/kplayer.h471
1 files changed, 471 insertions, 0 deletions
diff --git a/libkdegames/kgame/kplayer.h b/libkdegames/kgame/kplayer.h
new file mode 100644
index 00000000..0e511ac3
--- /dev/null
+++ b/libkdegames/kgame/kplayer.h
@@ -0,0 +1,471 @@
+/*
+ This file is part of the KDE games library
+ Copyright (C) 2001 Martin Heni ([email protected])
+ Copyright (C) 2001 Andreas Beckermann ([email protected])
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KPLAYER_H_
+#define __KPLAYER_H_
+
+#include <qstring.h>
+#include <qobject.h>
+#include <qptrlist.h>
+
+#include "kgameproperty.h"
+#include <kdemacros.h>
+
+class KGame;
+class KGameIO;
+class KGamePropertyBase;
+class KGamePropertyHandler;
+
+class KPlayerPrivate;
+
+/**
+ * @short Base class for a game player
+ *
+ * The KPlayer class is the central player object. It holds
+ * information about the player and is responsible for any
+ * input the player does. For this arbitrary many KGameIO
+ * modules can be plugged into it. Main features are:
+ * - Handling of IO devices
+ * - load/save (mostly handled by KGamePropertyHandler)
+ * - Turn handling (turn based, asynchronous)
+ *
+ * A KPlayer depends on a KGame object. Call KGame::addPlayer() to plug
+ * a KPlayer into a KGame object. Note that you cannot do much with a
+ * KPlayer object before it has been plugged into a KGame. This is because
+ * most properties of KPlayer are KGameProperty which need to send messages
+ * through a KGame object to be changed.
+ *
+ * A KGameIO represents the input methods of a player and you should make all
+ * player inputs through it. So call something like playerInput->move(4);
+ * instead which should call KGameIO::sendInput() to actually move. This way
+ * you gain a *very* big advantage: you can exchange a KGameIO whenever you
+ * want! You can e.g. remove the KGameIO of a local (human) player and just
+ * replace it by a computerIO on the fly! So from that point on all playerInputs
+ * are done by the computerIO instead of the human player. You also can replace
+ * all network players by computer players when the network connection is broken
+ * or a player wants to quit.
+ * So remember: use KGameIO whenever possible! A KPlayer should just
+ * contain all data of the player (KGameIO must not!) and several common
+ * functions which are shared by all of your KGameIOs.
+ *
+ */
+class KDE_EXPORT KPlayer : public QObject
+{
+ Q_OBJECT
+
+public:
+ typedef QPtrList<KGameIO> KGameIOList;
+
+ // KPlayer(KGame *,KGameIO * input=0);
+ /**
+ * Create a new player object. It will be automatically
+ * deleted if the game it belongs to is deleted.
+ */
+ KPlayer();
+
+ /**
+ * Create a new player object. It will be automatically
+ * deleted if the game it belongs to is deleted. This constructor
+ * automatically adds the player to the game using KGame::addPlayer()
+ */
+ KPlayer(KGame* game);
+
+ virtual ~KPlayer();
+
+ /**
+ * The idendification of the player. Overwrite this in
+ * classes inherting KPlayer to run time identify them.
+ *
+ * @return 0 for default KPlayer.
+ */
+ virtual int rtti() const {return 0;}
+
+ /**
+ * Gives debug output of the game status
+ */
+ void Debug();
+
+ // properties
+ /**
+ * Returns a list of input devices
+ *
+ * @return list of devices
+ */
+ KGameIOList *ioList() {return &mInputList;}
+
+ /**
+ * sets the game the player belongs to. This
+ * is usually automatically done when adding a
+ * player
+ *
+ * @param game the game
+ */
+ void setGame(KGame *game) {mGame=game;}
+
+ /**
+ * Query to which game the player belongs to
+ *
+ * @return the game
+ */
+ KGame *game() const {return mGame;}
+
+ /**
+ * Set whether this player can make turns/input
+ * all the time (true) or only when it is its
+ * turn (false) as it is used in turn based games
+ *
+ * @param a async=true turn based=false
+ */
+ void setAsyncInput(bool a) {mAsyncInput = a;}
+
+ /**
+ * Query whether this player does asynchronous
+ * input
+ *
+ * @return true/false
+ */
+ bool asyncInput() const {return mAsyncInput.value();}
+
+ /**
+ * Is this player a virtual player, ie is it
+ * created by mirroring a real player from another
+ * network game. This mirroring is done autmatically
+ * as soon as a network connection is build and it affects
+ * all players regardless what type
+ *
+ * @return true/false
+ */
+ bool isVirtual() const;
+
+ /**
+ * @internal
+ * Sets whether this player is virtual. This is internally
+ * called
+ *
+ * @param v virtual true/false
+ */
+ void setVirtual(bool v);
+
+ /**
+ * Is this player an active player. An player is usually
+ * inactivated if it is replaced by a network connection.
+ * But this could also be called manually
+ *
+ * @return true/false
+ */
+ bool isActive() const {return mActive;}
+
+ /**
+ * Set an player as active (true) or inactive (false)
+ *
+ * @param v true=active, false=inactive
+ */
+ void setActive(bool v) {mActive=v;}
+
+ /**
+ * Returns the id of the player
+ *
+ * @return the player id
+ */
+ Q_UINT32 id() const;
+
+ /* Set the players id. This is done automatically by
+ * the game object when adding a new player!
+ *
+ * @param i the player id
+ */
+ void setId(Q_UINT32 i);
+
+ /**
+ * Returns the user defined id of the player
+ * This value can be used arbitrary by you to
+ * have some user idendification for your player,
+ * e.g. 0 for a white chess player, 1 for a black
+ * one. This value is more reliable than the player
+ * id whcih can even change when you make a network
+ * connection.
+ *
+ * @return the user defined player id
+ */
+ int userId() const {return mUserId.value();}
+
+ /* Set the user defined players id.
+ *
+ * @param i the user defined player id
+ */
+ void setUserId(int i) {mUserId = i;}
+
+ /**
+ * Returns whether this player can be replaced by a network
+ * connection player. The name of this function can be
+ * improved ;-) If you do not overwrite the function to
+ * select what players shall play in a network the KGame
+ * does an automatic selection based on the networkPriority
+ * This is not a terrible important function at the moment.
+ *
+ * @return true/false
+ */
+ int networkPriority() const;
+
+ /**
+ * Set whether this player can be replaced by a network
+ * player. There are to possible games. The first type
+ * of game has arbitrary many players. As soon as a network
+ * players connects the game runs with more players (not tagged
+ * situation). The other type is e.g. games like chess which
+ * require a constant player number. In a network game situation
+ * you would tag one or both players of all participants. As
+ * soon as the connect the tagged player will then be replaced
+ * by the network partner and it is then controlled over the network.
+ * On connection loss the old situation is automatically restored.
+ *
+ * The name of this function can be improved;-)
+ *
+ * @param b should this player be tagged
+ */
+ void setNetworkPriority(int b);
+
+ /**
+ * Returns the player which got inactivated to allow
+ * this player to be set up via network. Mostly internal
+ * function
+ */
+ KPlayer *networkPlayer() const;
+
+ /**
+ * Sets this network player replacement. Internal stuff
+ */
+ void setNetworkPlayer(KPlayer *p);
+
+ // A name and group the player belongs to
+ /**
+ * A group the player belongs to. This
+ * Can be set arbitrary by you.
+ */
+ void setGroup(const QString& group);
+
+ /**
+ * Query the group the player belongs to.
+ */
+ virtual const QString& group() const;
+
+ /**
+ * Sets the name of the player.
+ * This can be chosen arbitrary.
+ * @param name The player's name
+ */
+ void setName(const QString& name);
+
+ /**
+ * @return The name of the player.
+ */
+ virtual const QString& name() const;
+
+
+ // set devices
+ /**
+ * Adds an IO device for the player. Possible KGameIO devices
+ * can either be taken from the existing ones or be self written.
+ * Existing are e.g. Keyboard, Mouse, Computerplayer
+ *
+ * @param input the inut device
+ * @return true if ok
+ */
+ bool addGameIO(KGameIO *input);
+
+ /**
+ * remove (and delete) a game IO device
+ *
+ * The remove IO(s) is/are deleted by default. If
+ * you do not want this set the parameter deleteit to false
+ *
+ * @param input the device to be removed or 0 for all devices
+ * @param deleteit true (default) to delete the device otherwisse just remove it
+ * @return true on ok
+ */
+ bool removeGameIO(KGameIO *input=0,bool deleteit=true);
+
+ /**
+ * Finds the KGameIO devies with the given rtti code.
+ * E.g. find the mouse or network device
+ *
+ * @param rtti the rtti code to be searched for
+ * @return the KGameIO device
+ */
+ KGameIO *findRttiIO(int rtti) const;
+
+ /**
+ * Checks whether this player has a IO device of the
+ * given rtti type
+ *
+ * @param rtti the rtti typed to be checked for
+ * @return true if it exists
+ */
+ bool hasRtti(int rtti) const {return findRttiIO(rtti)!=0;}
+
+ // Message exchange
+ /**
+ * Forwards input to the game object..internal use only
+ *
+ * This method is used by KGameIO::sendInput(). Use that function
+ * instead to send player inputs!
+ *
+ * This function forwards a player input (see KGameIO classes) to the
+ * game object, see KGame, either to KGame::sendPlayerInput() (if
+ * transmit=true, ie the message has just been created) or to
+ * KGame::playerInput() (if player=false, ie the message *was* sent through
+ * KGame::sendPlayerInput).
+ */
+ virtual bool forwardInput(QDataStream &msg,bool transmit=true, Q_UINT32 sender=0);
+
+ /**
+ * Forwards Message to the game object..internal use only
+ */
+ virtual bool forwardMessage(QDataStream &msg,int msgid,Q_UINT32 receiver=0,Q_UINT32 sender=0);
+
+ // Game logic
+ /**
+ * is it my turn to go
+ *
+ * @return true/false
+ */
+ bool myTurn() const {return mMyTurn.value();}
+
+ /**
+ * Sets whether this player is the next to turn.
+ * If exclusive is given all other players are set
+ * to setTurn(false) and only this player can move
+ *
+ * @param b true/false
+ * @param exclusive true (default)/ false
+ * @return should be void
+ */
+ bool setTurn(bool b,bool exclusive=true);
+
+
+ // load/save
+ /**
+ * Load a saved player, from file OR network. By default all
+ * KGameProperty objects in the dataHandler of this player are loaded
+ * and saved when using load or save. If you need to save/load more
+ * you have to replace this function (and save). You will probably
+ * still want to call the default implementation additionally!
+ *
+ * @param stream a data stream where you can stream the player from
+ *
+ * @return true?
+ */
+ virtual bool load(QDataStream &stream);
+
+ /**
+ * Save a player to a file OR to network. See also load
+ *
+ * @param stream a data stream to load the player from
+ *
+ * @return true?
+ */
+ virtual bool save(QDataStream &stream);
+
+ /**
+ * Receives a message
+ * @param msgid The kind of the message. See messages.txt for further
+ * information
+ * @param stream The message itself
+ * @param sender
+ **/
+ void networkTransmission(QDataStream &stream,int msgid,Q_UINT32 sender);
+
+ /**
+ * Searches for a property of the player given its id.
+ * @param id The id of the property
+ * @return The property with the specified id
+ **/
+ KGamePropertyBase* findProperty(int id) const;
+
+ /**
+ * Adds a property to a player. You would add all
+ * your player specific game data as KGameProperty and
+ * they are automatically saved and exchanged over network.
+ *
+ * @param data The property to be added. Must have an unique id!
+ * @return false if the given id is not valid (ie another property owns
+ * the id) or true if the property could be added successfully
+ **/
+ bool addProperty(KGamePropertyBase* data);
+
+ /**
+ * Calculates a checksum over the IO devices. Can be used to
+ * restore the IO handlers. The value returned is the 'or'ed
+ * value of the KGameIO rtti's.
+ * this is itnernally used for saving and restorign a player.
+ */
+ int calcIOValue();
+
+ /**
+ * @return the property handler
+ */
+ KGamePropertyHandler* dataHandler();
+
+signals:
+ /**
+ * The player object got a message which was targeted
+ * at it but has no default method to process it. This
+ * means probably a user message. Connecting to this signal
+ * allowed to process it.
+ */
+ void signalNetworkData(int msgid, const QByteArray& buffer, Q_UINT32 sender, KPlayer *me);
+
+ /**
+ * This signal is emmited if a player property changes its value and
+ * the property is set to notify this change. This is an
+ * important signal as you should base the actions on a reaction
+ * to this property changes.
+ */
+ void signalPropertyChanged(KGamePropertyBase *property,KPlayer *me);
+
+protected slots:
+ /**
+ * Called by KGameProperty only! Internal function!
+ **/
+ void sendProperty(int msgid, QDataStream& stream, bool* sent);
+ /**
+ * Called by KGameProperty only! Internal function!
+ **/
+ void emitSignal(KGamePropertyBase *me);
+
+
+private:
+ void init();
+
+private:
+ KGame *mGame;
+ bool mActive; // active player
+ KGameIOList mInputList;
+
+ // GameProperty // AB: I think we can't move them to KPlayerPrivate - inline
+ // makes sense here
+ KGamePropertyBool mAsyncInput; // async input allowed
+ KGamePropertyBool mMyTurn; // Is it my turn to play (only useful if not async)?
+ KGamePropertyInt mUserId; // a user defined id
+
+ KPlayerPrivate* d;
+};
+
+#endif