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.
623 lines
13 KiB
623 lines
13 KiB
/* Yo Emacs, this -*- C++ -*-
|
|
|
|
Copyright (C) 1999-2001 Jens Hoefkens
|
|
jens@hoefkens.com
|
|
|
|
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; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
$Id$
|
|
|
|
*/
|
|
|
|
#include "kbgng.moc"
|
|
#include "kbgng.h"
|
|
|
|
#include <kapplication.h>
|
|
#include <kmessagebox.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <tqlayout.h>
|
|
#include <kiconloader.h>
|
|
#include <kstdaction.h>
|
|
#include <tqbuttongroup.h>
|
|
#include <tqcheckbox.h>
|
|
#include <kconfig.h>
|
|
#include <klocale.h>
|
|
#include <kmainwindow.h>
|
|
#include <klineeditdlg.h>
|
|
#include <krandomsequence.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqcstring.h>
|
|
#include <tqtextstream.h>
|
|
|
|
#include <version.h>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
/*
|
|
* Constructor
|
|
*/
|
|
KBgEngineNg::KBgEngineNg(TQWidget *parent, TQString *name, TQPopupMenu *pmenu)
|
|
: KBgEngine(parent, name, pmenu)
|
|
{
|
|
// get a new game
|
|
initGame();
|
|
|
|
// create actions and menus
|
|
TQString label[MaxTypes];
|
|
|
|
label[Local ] = i18n("Local Games");
|
|
label[NetServer] = i18n("Offer Network Games");
|
|
label[NetClient] = i18n("Join Network Games");
|
|
|
|
TQStringList list;
|
|
for (int i = 0; i < MaxTypes; i++)
|
|
list.append(label[i]);
|
|
|
|
_gameSelect = new KSelectAction(i18n("&Types"), 0, this, TQT_SLOT(setGame()), this);
|
|
_gameSelect->setItems(list);
|
|
_gameSelect->plug(menu);
|
|
|
|
menu->insertSeparator();
|
|
|
|
_connectAction = new KAction(i18n("&Names..."), 0, this, TQT_SLOT(changeName()), this);
|
|
_connectAction->plug(menu);
|
|
|
|
// Restore last settings
|
|
readConfig();
|
|
|
|
// initialize to local games
|
|
_player[0] = _player[1] = 0;
|
|
_currGame = None;
|
|
_gameSelect->setCurrentItem(Local);
|
|
setGame();
|
|
}
|
|
|
|
|
|
/*
|
|
* Switch the local game type. This is called by the menu...
|
|
*
|
|
* TODO: lots of work and testing needed...
|
|
*/
|
|
void KBgEngineNg::setGame()
|
|
{
|
|
// shutdown old game
|
|
switch (_currGame) {
|
|
|
|
case Local:
|
|
// nothing to do...
|
|
break;
|
|
|
|
case NetServer:
|
|
_game->stopServerConnection();
|
|
break;
|
|
|
|
case NetClient:
|
|
_game->disconnect();
|
|
break;
|
|
|
|
default:
|
|
// ignore
|
|
break;
|
|
}
|
|
|
|
// reset the game and delete the players
|
|
delete _game;
|
|
initGame();
|
|
|
|
emit infoText("<br/>");
|
|
|
|
// initialize a new game
|
|
bool ret = false;
|
|
TQString label, port_s, host_s;
|
|
TQ_UINT16 port;
|
|
|
|
switch (_currGame = _gameSelect->currentItem()) {
|
|
|
|
case Local:
|
|
|
|
_game->addPlayer(createPlayer(0, _name[0]));
|
|
_game->addPlayer(createPlayer(1, _name[1]));
|
|
break;
|
|
|
|
case NetServer:
|
|
label = i18n("Type the port number on which you want to listen to "
|
|
"connections.\nThe number should be between 1024 and "
|
|
"65535.");
|
|
port_s.setNum(_port);
|
|
do {
|
|
port_s = KLineEditDlg::getText(label, port_s, &ret, (TQWidget *)parent());
|
|
if (!ret)
|
|
return;
|
|
port = port_s.toUShort(&ret);
|
|
} while (port_s.isEmpty() && !ret);
|
|
|
|
if (_game->offerConnections(port))
|
|
emit infoText(i18n("Now waiting for incoming connections on port %1.").
|
|
arg(_port = port));
|
|
else
|
|
emit infoText(i18n("Failed to offer connections on port %1.").arg(port));
|
|
|
|
_game->addPlayer(createPlayer(0, _name[0]));
|
|
break;
|
|
|
|
case NetClient:
|
|
label = i18n("Type the name of the server you want to connect to:");
|
|
host_s = _host;
|
|
do {
|
|
host_s = KLineEditDlg::getText(label, host_s, &ret, (TQWidget *)parent());
|
|
if (!ret)
|
|
return;
|
|
} while (host_s.isEmpty());
|
|
|
|
label = i18n("Type the port number on %1 you want to connect to.\nThe "
|
|
"number should be between 1024 and 65535.").arg(host_s);
|
|
port_s.setNum(_port);
|
|
do {
|
|
port_s = KLineEditDlg::getText(label, port_s, &ret, (TQWidget *)parent());
|
|
if (!ret)
|
|
return;
|
|
port = port_s.toUShort(&ret);
|
|
} while (port_s.isEmpty() && !ret);
|
|
|
|
/*
|
|
* Hi Martin: another thing you night want to try is to move this to the
|
|
* place marked by <HERE> (about 10 lines further down. If you do that, the
|
|
* players are created properly on the server, but a total of three players
|
|
* is created on the client.
|
|
*/
|
|
_game->addPlayer(createPlayer(0, _name[0]));
|
|
|
|
if (_game->connectToServer(host_s, port))
|
|
emit infoText(i18n("Now connected to %1:%2.").arg(_host = host_s).
|
|
arg(_port = port));
|
|
else
|
|
emit infoText(i18n("Failed to connect to %1:%2.").arg(_host = host_s).
|
|
arg(_port = port));
|
|
|
|
// <HERE>
|
|
|
|
break;
|
|
|
|
default:
|
|
kdDebug(true, PROG_COOKIE) << "setGame parameter invalid: "
|
|
<< _currGame << endl;
|
|
_currGame = None;
|
|
return;
|
|
}
|
|
|
|
// we are still having problems with player creation...
|
|
|
|
// FIXME - which status _game->setGameStatus(KGame::End);
|
|
}
|
|
|
|
void KBgEngineNg::slotPlayerJoinedGame(KPlayer *p)
|
|
{
|
|
emit infoText(i18n("Player %1 (%2) has joined the game.").arg(p->name()).arg(p->id()));
|
|
cerr << i18n("Player %1 (%2) has joined the game.").arg(p->name()).arg(p->id()).latin1() << endl;
|
|
}
|
|
|
|
void KBgEngineNg::slotCreatePlayer(KPlayer *&p, int rtti, int io, bool v, KGame *g)
|
|
{
|
|
Q_UNUSED(rtti)
|
|
Q_UNUSED(g)
|
|
Q_UNUSED(io)
|
|
emit infoText(i18n("creating player. virtual=%1").arg(v));
|
|
p = createPlayer(1);
|
|
}
|
|
|
|
void KBgEngineNg::slotClientConnected(TQ_UINT32)
|
|
{
|
|
cerr << "client has joint the game..." << endl;
|
|
}
|
|
|
|
void KBgEngineNg::slotClientDisconnected(TQ_UINT32, bool)
|
|
{
|
|
cerr << "KBgEngineNg::slotClientDisconnected" << endl;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// == start and init games =====================================================
|
|
|
|
/*
|
|
* Start a new game. ...
|
|
*/
|
|
void KBgEngineNg::newGame()
|
|
{
|
|
// TODO
|
|
cerr << "games are not yet working..." << endl;
|
|
}
|
|
|
|
/*
|
|
* Finish the last move - called by the timer and directly by the used
|
|
*/
|
|
void KBgEngineNg::done()
|
|
{
|
|
// empty
|
|
}
|
|
|
|
/*
|
|
* Undo the last move
|
|
*/
|
|
void KBgEngineNg::undo()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
/*
|
|
* Redo the last move
|
|
*/
|
|
void KBgEngineNg::redo()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
/*
|
|
* Take the move string and make the changes on the working copy
|
|
* of the state.
|
|
*/
|
|
void KBgEngineNg::handleMove(TQString *s)
|
|
{
|
|
Q_UNUSED(s)
|
|
// TODO
|
|
}
|
|
|
|
/*
|
|
* Roll random dice for the player whose turn it is
|
|
*/
|
|
void KBgEngineNg::roll()
|
|
{
|
|
// empty
|
|
}
|
|
|
|
/*
|
|
* If possible, roll random dice for player w
|
|
*/
|
|
void KBgEngineNg::rollDice(const int w)
|
|
{
|
|
Q_UNUSED(w)
|
|
// empty
|
|
}
|
|
|
|
/*
|
|
* Double the cube for the player that can double - asks player
|
|
*/
|
|
void KBgEngineNg::cube()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
/*
|
|
* Double the cube for player w
|
|
*/
|
|
void KBgEngineNg::doubleCube(const int)
|
|
{
|
|
cube();
|
|
}
|
|
|
|
/*
|
|
* Put the engine specific details in the setup dialog
|
|
*/
|
|
void KBgEngineNg::getSetupPages(KDialogBase *)
|
|
{
|
|
// FIXME: do nothing...
|
|
}
|
|
|
|
/*
|
|
* Called when the setup dialog is positively closed
|
|
*/
|
|
void KBgEngineNg::setupOk()
|
|
{
|
|
// FIXME: do nothing...
|
|
}
|
|
void KBgEngineNg::setupDefault()
|
|
{
|
|
// FIXME: do nothing...
|
|
}
|
|
void KBgEngineNg::setupCancel()
|
|
{
|
|
// FIXME: do nothing...
|
|
}
|
|
|
|
|
|
// == various slots & functions ================================================
|
|
|
|
/*
|
|
* Check with the user if we should really quit in the middle of a
|
|
* game.
|
|
*/
|
|
bool KBgEngineNg::queryClose()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Quitting is fine at any time
|
|
*/
|
|
bool KBgEngineNg::queryExit()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Load the last known sane state of the board
|
|
*/
|
|
void KBgEngineNg::load()
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
/*
|
|
* Store if cmd is allowed or not
|
|
*/
|
|
void KBgEngineNg::setAllowed(int cmd, bool f)
|
|
{
|
|
switch (cmd) {
|
|
case Roll:
|
|
rollingAllowed = f;
|
|
return;
|
|
case Undo:
|
|
undoPossible = f;
|
|
return;
|
|
case Cube:
|
|
doublePossible = f;
|
|
return;
|
|
case Done:
|
|
donePossible = f;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
// ********************************************************************************
|
|
// ********************************************************************************
|
|
|
|
// DONE
|
|
|
|
// ********************************************************************************
|
|
// ********************************************************************************
|
|
|
|
|
|
/*
|
|
* Destructor.
|
|
*/
|
|
KBgEngineNg::~KBgEngineNg()
|
|
{
|
|
saveConfig();
|
|
delete _game;
|
|
}
|
|
|
|
/*
|
|
* Restore settings
|
|
*/
|
|
void KBgEngineNg::readConfig()
|
|
{
|
|
TDEConfig* config = kapp->config();
|
|
config->setGroup("next generation engine");
|
|
|
|
_port = config->readNumEntry("port", PROG_COOKIE);
|
|
_host = config->readEntry("host", "localhost");
|
|
|
|
_name[0] = config->readEntry("name_0", i18n("one"));
|
|
_name[1] = config->readEntry("name_1", i18n("two"));
|
|
}
|
|
|
|
/*
|
|
* Save the engine specific settings
|
|
*/
|
|
void KBgEngineNg::saveConfig()
|
|
{
|
|
TDEConfig* config = kapp->config();
|
|
config->setGroup("next generation engine");
|
|
|
|
config->writeEntry("port", _port);
|
|
config->writeEntry("host", _host);
|
|
|
|
config->writeEntry("name_0", _name[0]);
|
|
config->writeEntry("name_1", _name[1]);
|
|
}
|
|
|
|
/*
|
|
* Read the users input from the command line and send it to all
|
|
* players. Although the message gets the Cmd ID, it is currently
|
|
* handled as a regular text message.
|
|
*/
|
|
void KBgEngineNg::handleCommand(const TQString& text)
|
|
{
|
|
TQByteArray msg;
|
|
TQTextStream ts(msg, IO_WriteOnly);
|
|
ts << text;
|
|
if (!_game->sendMessage(msg, KBgGame::Cmd))
|
|
kdDebug(true, PROG_COOKIE) << "couldn't send message: "
|
|
<< text.latin1() << endl;
|
|
}
|
|
|
|
/*
|
|
* Return a random integer between 1 and 6. Use the KGame random
|
|
* number generator.
|
|
*/
|
|
int KBgEngineNg::getRandom()
|
|
{
|
|
return 1+_game->random()->getLong(6);
|
|
}
|
|
|
|
/*
|
|
* A player propert has changed - check if we care
|
|
*/
|
|
void KBgEngineNg::slotPropertyChanged(KGamePropertyBase *p, KPlayer *me)
|
|
{
|
|
int player = (me->id() == _player[1]->id());
|
|
|
|
switch (p->id()) {
|
|
|
|
case KGamePropertyBase::IdName:
|
|
emit infoText(i18n("Player %1 has changed the name to %2.")
|
|
.arg(_name[player]).arg(me->name()));
|
|
_name[player] = me->name();
|
|
break;
|
|
|
|
default:
|
|
kdDebug(true, PROG_COOKIE) << "KBgPlayer (" << me << ") property change ("
|
|
<< p->id() << ") ignored" << endl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* A game property has changed
|
|
*/
|
|
void KBgEngineNg::slotPropertyChanged(KGamePropertyBase *p, KGame *me)
|
|
{
|
|
Q_UNUSED(me)
|
|
switch (p->id()) {
|
|
|
|
default:
|
|
kdDebug(true, PROG_COOKIE) << "Change in GameProperty " << p->id()
|
|
<< " has been ignored." << endl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Change the names of all local players
|
|
*/
|
|
void KBgEngineNg::changeName()
|
|
{
|
|
bool ok = false;
|
|
TQString name;
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
name = TQString();
|
|
while (!_player[i]->isVirtual() && name.isEmpty()) {
|
|
if (i == 0)
|
|
name = KLineEditDlg::getText(i18n("Type the name of the first player:"),
|
|
_name[i], &ok, (TQWidget *)parent());
|
|
else
|
|
name = KLineEditDlg::getText(i18n("Type the name of the second player:"),
|
|
_name[i], &ok, (TQWidget *)parent());
|
|
if (!ok) return;
|
|
_player[i]->setName(name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Receive data sent via KBgGame::sendMessage(...)
|
|
*/
|
|
void KBgEngineNg::slotNetworkData(int msgid, const TQByteArray &msg, TQ_UINT32 r, TQ_UINT32 s)
|
|
{
|
|
Q_UNUSED(r);
|
|
Q_UNUSED(s);
|
|
switch (msgid) {
|
|
|
|
case KBgGame::Cmd:
|
|
emit infoText(msg);
|
|
emit infoText(i18n("Players are %1 and %2").arg(_player[0]->name())
|
|
.arg(_player[1]->name()));
|
|
break;
|
|
|
|
default:
|
|
kdDebug(true, PROG_COOKIE) << "Ignored message ID: " << msgid << endl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Create the i-th player
|
|
*/
|
|
KBgPlayer * KBgEngineNg::createPlayer(int i, TQString name)
|
|
{
|
|
KBgPlayer *p = new KBgPlayer();
|
|
|
|
if (!name.isNull())
|
|
p->setName(name);
|
|
|
|
p->findProperty(KGamePropertyBase::IdName)->setEmittingSignal(true);
|
|
|
|
connect(p, TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase *, KPlayer *)),
|
|
this, TQT_SLOT(slotPropertyChanged(KGamePropertyBase *, KPlayer *)));
|
|
|
|
return (_player[i] = p);
|
|
}
|
|
|
|
/*
|
|
* Create and connect the game object
|
|
*/
|
|
void KBgEngineNg::initGame()
|
|
{
|
|
_game = new KBgGame(PROG_COOKIE);
|
|
_game->random()->setSeed(getpid()*time(NULL));
|
|
|
|
connect(_game, TQT_SIGNAL(signalPlayerJoinedGame(KPlayer *)),
|
|
this, TQT_SLOT(slotPlayerJoinedGame(KPlayer *)));
|
|
connect(_game, TQT_SIGNAL(signalCreatePlayer(KPlayer *&, int, int, bool, KGame *)),
|
|
this, TQT_SLOT(slotCreatePlayer(KPlayer *&, int, int, bool, KGame *)));
|
|
|
|
connect(_game, TQT_SIGNAL(signalClientConnected(TQ_UINT32)),
|
|
this, TQT_SLOT(slotClientConnected(TQ_UINT32)));
|
|
connect(_game, TQT_SIGNAL(signalClientDisconnected(TQ_UINT32, bool)),
|
|
this, TQT_SLOT(slotClientDisconnected(TQ_UINT32, bool)));
|
|
|
|
connect(_game, TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase *, KGame *)),
|
|
this, TQT_SLOT(slotPropertyChanged(KGamePropertyBase *, KGame *)));
|
|
connect(_game, TQT_SIGNAL(signalNetworkData(int,const TQByteArray &, TQ_UINT32, TQ_UINT32)),
|
|
this, TQT_SLOT(slotNetworkData(int,const TQByteArray &, TQ_UINT32, TQ_UINT32)));
|
|
}
|
|
|
|
// EOF
|