You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
447 lines
11 KiB
447 lines
11 KiB
/*
|
|
This file is part of the KDE games library
|
|
Copyright (C) 2001 Martin Heni (martin@heni-online.de)
|
|
Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
|
|
|
|
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 <tqbuffer.h>
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
#define KPLAYER_LOAD_COOKIE 7285
|
|
|
|
class KPlayerPrivate
|
|
{
|
|
public:
|
|
KPlayerPrivate()
|
|
{
|
|
mNetworkPlayer = 0;
|
|
}
|
|
|
|
TQ_UINT32 mId;
|
|
bool mVirtual; // virtual player
|
|
int mPriority; // tag for replacement
|
|
|
|
KPlayer* mNetworkPlayer; // replacement player
|
|
|
|
KGamePropertyHandler mProperties;
|
|
|
|
// Playerdata
|
|
KGamePropertyTQString mName;
|
|
KGamePropertyTQString mGroup;
|
|
};
|
|
|
|
KPlayer::KPlayer() : TQObject(0,0)
|
|
{
|
|
init();
|
|
}
|
|
|
|
KPlayer::KPlayer(KGame* game) : TQObject(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,TQT_SLOT(sendProperty(int, TQDataStream&, bool*)),
|
|
TQT_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(TQDataStream &msg,int msgid,TQ_UINT32 receiver,TQ_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(TQDataStream &msg,bool transmit,TQ_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(TQ_UINT32 newid)
|
|
{
|
|
// Needs to be after the sendProcess
|
|
d->mId=newid;
|
|
}
|
|
|
|
|
|
void KPlayer::setGroup(const TQString& group)
|
|
{ d->mGroup = group; }
|
|
|
|
const TQString& KPlayer::group() const
|
|
{ return d->mGroup.value(); }
|
|
|
|
void KPlayer::setName(const TQString& name)
|
|
{ d->mName = name; }
|
|
|
|
const TQString& KPlayer::name() const
|
|
{ return d->mName.value(); }
|
|
|
|
TQ_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
|
|
{
|
|
TQPtrListIterator<KGameIO> it(mInputList);
|
|
while (it.current())
|
|
{
|
|
if (it.current()->rtti() == rtti)
|
|
{
|
|
return it.current();
|
|
}
|
|
++it;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KPlayer::calcIOValue()
|
|
{
|
|
int value=0;
|
|
TQPtrListIterator<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(TQDataStream &stream)
|
|
{
|
|
TQ_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);
|
|
|
|
TQ_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(TQDataStream &stream)
|
|
{
|
|
stream << (TQ_INT32)id() << (TQ_INT32)networkPriority();
|
|
|
|
d->mProperties.save(stream);
|
|
|
|
stream << (TQ_INT16)KPLAYER_LOAD_COOKIE;
|
|
|
|
//emit signalSave(stream);
|
|
return true;
|
|
}
|
|
|
|
|
|
void KPlayer::networkTransmission(TQDataStream &stream,int msgid,TQ_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,
|
|
((TQBuffer*)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, TQDataStream& 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;
|
|
TQPtrListIterator<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"
|