summaryrefslogtreecommitdiffstats
path: root/libkdegames/kgame/kplayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libkdegames/kgame/kplayer.cpp')
-rw-r--r--libkdegames/kgame/kplayer.cpp446
1 files changed, 446 insertions, 0 deletions
diff --git a/libkdegames/kgame/kplayer.cpp b/libkdegames/kgame/kplayer.cpp
new file mode 100644
index 00000000..0f8ea184
--- /dev/null
+++ b/libkdegames/kgame/kplayer.cpp
@@ -0,0 +1,446 @@
+/*
+ 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.
+*/
+/*
+ $Id$
+*/
+
+
+#include "kgame.h"
+#include "kgameio.h"
+#include "kplayer.h"
+#include "kgamemessage.h"
+#include "kgamepropertyhandler.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <qbuffer.h>
+
+#include <stdio.h>
+#include <assert.h>
+
+#define KPLAYER_LOAD_COOKIE 7285
+
+class KPlayerPrivate
+{
+public:
+ KPlayerPrivate()
+ {
+ mNetworkPlayer = 0;
+ }
+
+ Q_UINT32 mId;
+ bool mVirtual; // virtual player
+ int mPriority; // tag for replacement
+
+ KPlayer* mNetworkPlayer; // replacement player
+
+ KGamePropertyHandler mProperties;
+
+// Playerdata
+ KGamePropertyQString mName;
+ KGamePropertyQString mGroup;
+};
+
+KPlayer::KPlayer() : QObject(0,0)
+{
+ init();
+}
+
+KPlayer::KPlayer(KGame* game) : QObject(0, 0)
+{
+ init();
+ game->addPlayer(this);
+}
+
+void KPlayer::init()
+{
+// note that NO KGame object exists here! so we cannot use KGameProperty::send!
+ kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)="<<sizeof(KPlayer) << endl;
+ kdDebug(11001) << "sizeof(m_Group)="<<sizeof(d->mGroup)<<endl;
+ d = new KPlayerPrivate;
+
+ d->mProperties.registerHandler(KGameMessage::IdPlayerProperty,
+ this,SLOT(sendProperty(int, QDataStream&, bool*)),
+ SLOT(emitSignal(KGamePropertyBase *)));
+ d->mVirtual=false;
+ mActive=true;
+ mGame=0;
+ d->mId=0; // "0" is always an invalid ID!
+ d->mPriority=0;
+ // I guess we cannot translate the group otherwise no
+ // international conenctions are possible
+
+ mUserId.registerData(KGamePropertyBase::IdUserId, this, i18n("UserId"));
+ mUserId.setLocal(0);
+ d->mGroup.registerData(KGamePropertyBase::IdGroup, this, i18n("Group"));
+ d->mGroup.setLocal(i18n("default"));
+ d->mName.registerData(KGamePropertyBase::IdName, this, i18n("Name"));
+ d->mName.setLocal(i18n("default"));
+
+ mAsyncInput.registerData(KGamePropertyBase::IdAsyncInput, this, i18n("AsyncInput"));
+ mAsyncInput.setLocal(false);
+ mMyTurn.registerData(KGamePropertyBase::IdTurn, this, i18n("myTurn"));
+ mMyTurn.setLocal(false);
+ mMyTurn.setEmittingSignal(true);
+ mMyTurn.setOptimized(false);
+}
+
+KPlayer::~KPlayer()
+{
+ kdDebug(11001) << k_funcinfo << ": this=" << this <<", id=" << this->id() << endl;
+
+ // Delete IODevices
+ KGameIO *input;
+ while((input=mInputList.first()))
+ {
+ delete input;
+ }
+ if (game())
+ {
+ game()->playerDeleted(this);
+ }
+
+// note: mProperties does not use autoDelete or so - user must delete objects
+// himself
+ d->mProperties.clear();
+ delete d;
+// kdDebug(11001) << k_funcinfo << " done" << endl;
+}
+
+bool KPlayer::forwardMessage(QDataStream &msg,int msgid,Q_UINT32 receiver,Q_UINT32 sender)
+{
+ if (!isActive())
+ {
+ return false;
+ }
+ if (!game())
+ {
+ return false;
+ }
+ kdDebug(11001) << k_funcinfo << ": to game sender="<<sender<<"" << "recv="<<receiver <<"msgid="<<msgid << endl;
+ return game()->sendSystemMessage(msg,msgid,receiver,sender);
+}
+
+bool KPlayer::forwardInput(QDataStream &msg,bool transmit,Q_UINT32 sender)
+{
+ if (!isActive())
+ {
+ return false;
+ }
+ if (!game())
+ {
+ return false;
+ }
+
+ kdDebug(11001) << k_funcinfo << ": to game playerInput(sender="<<sender<<")" << endl;
+ if (!asyncInput() && !myTurn())
+ {
+ kdDebug(11001) << k_funcinfo << ": rejected cause it is not our turn" << endl;
+ return false;
+ }
+
+ // AB: I hope I remember the usage correctly:
+ // this function is called twice (on sender side) - once with transmit = true
+ // where it sends the input to the comserver and once with transmit = false
+ // where it really looks at the input
+ if (transmit)
+ {
+ kdDebug(11001) << "indirect playerInput" << endl;
+ return game()->sendPlayerInput(msg,this,sender);
+ }
+ else
+ {
+ kdDebug(11001) << "direct playerInput" << endl;
+ return game()->systemPlayerInput(msg,this,sender);
+ }
+}
+
+void KPlayer::setId(Q_UINT32 newid)
+{
+ // Needs to be after the sendProcess
+ d->mId=newid;
+}
+
+
+void KPlayer::setGroup(const QString& group)
+{ d->mGroup = group; }
+
+const QString& KPlayer::group() const
+{ return d->mGroup.value(); }
+
+void KPlayer::setName(const QString& name)
+{ d->mName = name; }
+
+const QString& KPlayer::name() const
+{ return d->mName.value(); }
+
+Q_UINT32 KPlayer::id() const
+{ return d->mId; }
+
+KGamePropertyHandler * KPlayer::dataHandler()
+{ return &d->mProperties; }
+
+void KPlayer::setVirtual(bool v)
+{ d->mVirtual = v; }
+
+bool KPlayer::isVirtual() const
+{ return d->mVirtual;}
+
+void KPlayer::setNetworkPlayer(KPlayer* p)
+{ d->mNetworkPlayer = p; }
+
+KPlayer* KPlayer::networkPlayer() const
+{ return d->mNetworkPlayer; }
+
+int KPlayer::networkPriority() const
+{ return d->mPriority; }
+
+void KPlayer::setNetworkPriority(int p)
+{ d->mPriority = p; }
+
+bool KPlayer::addGameIO(KGameIO *input)
+{
+ if (!input)
+ {
+ return false;
+ }
+ mInputList.append(input);
+ input->initIO(this); // set player and init device
+ return true;
+}
+
+// input=0, remove all
+bool KPlayer::removeGameIO(KGameIO *targetinput,bool deleteit)
+{
+ kdDebug(11001) << k_funcinfo << ": " << targetinput << " delete=" << deleteit<< endl;
+ bool result=true;
+ if (!targetinput) // delete all
+ {
+ KGameIO *input;
+ while((input=mInputList.first()))
+ {
+ if (input) removeGameIO(input,deleteit);
+ }
+ }
+ else
+ {
+// kdDebug(11001) << "remove IO " << targetinput << endl;
+ if (deleteit)
+ {
+ delete targetinput;
+ }
+ else
+ {
+ targetinput->setPlayer(0);
+ result=mInputList.remove(targetinput);
+ }
+ }
+ return result;
+}
+
+KGameIO * KPlayer::findRttiIO(int rtti) const
+{
+ QPtrListIterator<KGameIO> it(mInputList);
+ while (it.current())
+ {
+ if (it.current()->rtti() == rtti)
+ {
+ return it.current();
+ }
+ ++it;
+ }
+ return 0;
+}
+
+int KPlayer::calcIOValue()
+{
+ int value=0;
+ QPtrListIterator<KGameIO> it(mInputList);
+ while (it.current())
+ {
+ value|=it.current()->rtti();
+ ++it;
+ }
+ return value;
+}
+
+bool KPlayer::setTurn(bool b, bool exclusive)
+{
+ kdDebug(11001) << k_funcinfo << ": " << id() << " (" << this << ") to " << b << endl;
+ if (!isActive())
+ {
+ return false;
+ }
+
+ // if we get to do an exclusive turn all other players are disallowed
+ if (exclusive && b && game())
+ {
+ KPlayer *player;
+ KGame::KGamePlayerList *list=game()->playerList();
+ for ( player=list->first(); player != 0; player=list->next() )
+ {
+ if (player==this)
+ {
+ continue;
+ }
+ player->setTurn(false,false);
+ }
+ }
+
+ // Return if nothing changed
+ mMyTurn = b;
+
+ return true;
+}
+
+bool KPlayer::load(QDataStream &stream)
+{
+ Q_INT32 id,priority;
+ stream >> id >> priority;
+ setId(id);
+ setNetworkPriority(priority);
+
+ // Load Player Data
+ //FIXME: maybe set all properties setEmitSignal(false) before?
+ d->mProperties.load(stream);
+
+ Q_INT16 cookie;
+ stream >> cookie;
+ if (cookie==KPLAYER_LOAD_COOKIE)
+ {
+ kdDebug(11001) << " Player loaded propertly"<<endl;
+ }
+ else
+ {
+ kdError(11001) << " Player loading error. probably format error"<<endl;
+ }
+
+ // emit signalLoad(stream);
+ return true;
+}
+
+bool KPlayer::save(QDataStream &stream)
+{
+ stream << (Q_INT32)id() << (Q_INT32)networkPriority();
+
+ d->mProperties.save(stream);
+
+ stream << (Q_INT16)KPLAYER_LOAD_COOKIE;
+
+ //emit signalSave(stream);
+ return true;
+}
+
+
+void KPlayer::networkTransmission(QDataStream &stream,int msgid,Q_UINT32 sender)
+{
+ //kdDebug(11001) << k_funcinfo ": msgid=" << msgid << " sender=" << sender << " we are=" << id() << endl;
+ // PlayerProperties processed
+ bool issender;
+ if (game())
+ {
+ issender=sender==game()->gameId();
+ }
+ else
+ {
+ issender=true;
+ }
+ if (d->mProperties.processMessage(stream,msgid,issender))
+ {
+ return ;
+ }
+ switch(msgid)
+ {
+ case KGameMessage::IdPlayerInput:
+ {
+ kdDebug(11001) << k_funcinfo << ": Got player move "
+ << "KPlayer (virtual) forwards it to the game object" << endl;
+ forwardInput(stream,false);
+ }
+ break;
+ default:
+ emit signalNetworkData(msgid - KGameMessage::IdUser,
+ ((QBuffer*)stream.device())->readAll(),sender,this);
+ kdDebug(11001) << k_funcinfo << ": "
+ << "User data msgid " << msgid << endl;
+ break;
+ }
+
+}
+
+KGamePropertyBase* KPlayer::findProperty(int id) const
+{
+ return d->mProperties.find(id);
+}
+
+bool KPlayer::addProperty(KGamePropertyBase* data)
+{
+ return d->mProperties.addProperty(data);
+}
+
+void KPlayer::sendProperty(int msgid, QDataStream& stream, bool* sent)
+{
+ if (game())
+ {
+ bool s = game()->sendPlayerProperty(msgid, stream, id());
+ if (s)
+ {
+ *sent = true;
+ }
+ }
+}
+
+void KPlayer::emitSignal(KGamePropertyBase *me)
+{
+ // Notify KGameIO (Process) for a new turn
+ if (me->id()==KGamePropertyBase::IdTurn)
+ {
+ //kdDebug(11001) << k_funcinfo << ": for KGamePropertyBase::IdTurn " << endl;
+ QPtrListIterator<KGameIO> it(mInputList);
+ while (it.current())
+ {
+ it.current()->notifyTurn(mMyTurn.value());
+ ++it;
+ }
+ }
+ emit signalPropertyChanged(me,this);
+}
+
+// --------------------- DEBUG --------------------
+void KPlayer::Debug()
+{
+ kdDebug(11001) << "------------------- KPLAYER -----------------------" << endl;
+ kdDebug(11001) << "this: " << this << endl;
+ kdDebug(11001) << "rtti: " << rtti() << endl;
+ kdDebug(11001) << "id : " << id() << endl;
+ kdDebug(11001) << "Name : " << name() << endl;
+ kdDebug(11001) << "Group: " << group() << endl;
+ kdDebug(11001) << "Async: " << asyncInput() << endl;
+ kdDebug(11001) << "myTurn: " << myTurn() << endl;
+ kdDebug(11001) << "Virtual: " << isVirtual() << endl;
+ kdDebug(11001) << "Active: " << isActive() << endl;
+ kdDebug(11001) << "Priority:" << networkPriority() << endl;
+ kdDebug(11001) << "Game : " << game() << endl;
+ kdDebug(11001) << "#IOs: " << mInputList.count() << endl;
+ kdDebug(11001) << "---------------------------------------------------" << endl;
+}
+
+#include "kplayer.moc"