Commit fe131ecf authored by Ian Wadham's avatar Ian Wadham

Fix the starting conditions for hero and enemies. Add some debug code.

svn path=/trunk/KDE/kdegames/kgoldrunner/; revision=965122
parent 0f480f30
......@@ -56,6 +56,8 @@ KGrLevelPlayer::KGrLevelPlayer (QObject * parent, KRandomSequence * pRandomGen)
digKillingTime (2) // Cycle at which enemy/hero gets killed.
{
t.start(); // IDW
dbgLevel = 0;
}
int KGrLevelPlayer::playerCount = 0;
......@@ -71,20 +73,20 @@ KGrLevelPlayer::~KGrLevelPlayer()
int ch = 0;
for (int i = 0; i <= (recIndex + 1); i ++) {
ch = (uchar)(recording->content.at(i));
dbe2 "%03d ", ch);
dbe1 "%03d ", ch);
if (ch == 0)
break;
}
dbe2 "\n%d bytes\n", recIndex + 1);
dbe1 "\n%d bytes\n", recIndex + 1);
int j = 0;
while (j < recording->draws.size()) {
ch = (uchar)(recording->draws.at(j));
dbe2 "%03d ", ch);
dbe1 "%03d ", ch);
if (ch == 0)
break;
j++;
}
dbe2 "\n%d bytes\n", j);
dbe1 "\n%d bytes\n", j);
// TODO - Do we need this delete?
// while (! enemies.isEmpty()) {
......@@ -394,7 +396,7 @@ void KGrLevelPlayer::setTarget (int pointerI, int pointerJ)
// The human player is playing now.
if (! playback) {
if ((pointerI == targetI) && (pointerJ == targetJ) && (recCount < 255)){
dbe3 "T %04d recIndex %03d REC: codes %d %d %d\n",
dbe2 "T %04d recIndex %03d REC: codes %d %d %d\n",
T, recIndex - 2, (uchar)(recording->content.at (recIndex-2)),
(uchar)(recording->content.at (recIndex-1)),
(uchar)(recording->content.at (recIndex)));
......@@ -402,7 +404,7 @@ void KGrLevelPlayer::setTarget (int pointerI, int pointerJ)
recording->content [recIndex] = (uchar) recCount;
}
else {
dbe3 "T %04d recIndex %03d REC: codes %d %d %d\n",
dbe2 "T %04d recIndex %03d REC: codes %d %d %d\n",
T, recIndex - 2, (uchar)(recording->content.at (recIndex-2)),
(uchar)(recording->content.at (recIndex-1)),
(uchar)(recording->content.at (recIndex)));
......@@ -412,7 +414,7 @@ void KGrLevelPlayer::setTarget (int pointerI, int pointerJ)
recording->content [recIndex] = (uchar) 1;
recording->content [recIndex + 1] = (uchar) 0xff;
recCount = 1;
dbe3 "T %04d recIndex %03d REC: codes %d %d %d - NEW TARGET\n",
dbe2 "T %04d recIndex %03d REC: codes %d %d %d - NEW TARGET\n",
T, recIndex - 2, pointerI, pointerJ,
(uchar)(recording->content.at (recIndex)));
}
......@@ -456,7 +458,7 @@ void KGrLevelPlayer::doDig (int button)
// If not the hero's first move, interrupt the previous mouse-move.
recording->content [recIndex] =
recording->content [recIndex] - 1;
dbe3 "T %04d recIndex %03d REC: codes %d %d %d\n",
dbe2 "T %04d recIndex %03d REC: codes %d %d %d\n",
T, recIndex - 2,
(uchar)(recording->content.at (recIndex-2)),
(uchar)(recording->content.at (recIndex-1)),
......@@ -464,7 +466,7 @@ void KGrLevelPlayer::doDig (int button)
recIndex++;
}
// Record the digging code.
dbe3 "T %04d recIndex %03d REC: dig code %d\n",
dbe2 "T %04d recIndex %03d REC: dig code %d\n",
T, recIndex, recordByte);
recording->content [recIndex++] = recordByte;
......@@ -507,7 +509,7 @@ void KGrLevelPlayer::setDirectionByKey (Direction dirn)
Direction KGrLevelPlayer::getDirection (int heroI, int heroJ)
{
int index = (playback) ? recIndex : recIndex - 2;
dbe3 "T %04d recIndex %03d hero at [%02d, %02d] aiming at [%02d, %02d]\n",
dbe2 "T %04d recIndex %03d hero at [%02d, %02d] aiming at [%02d, %02d]\n",
T, index, heroI, heroJ, targetI, targetJ);
if ((controlMode == MOUSE) || (controlMode == LAPTOP)) {
// If using a pointer device, calculate the hero's next direction,
......@@ -673,7 +675,11 @@ void KGrLevelPlayer::tick (bool missed, int scaledTime)
if (playback) { // Replay a recorded move.
if (! doRecordedMove()) {
playback = false;
emit interruptDemo();
// TODO - How to handle this case properly. emit interruptDemo();
// We want to continue the demo if it is the startup demo.
// We also want to continue to next level after a demo level
// that signals endLevel (DEAD) or even endLevel (NORMAL).
emit endLevel (WON_LEVEL);
dbk << "END_OF_RECORDING - emit interruptDemo();";
return; // End of recording.
}
......@@ -696,6 +702,7 @@ void KGrLevelPlayer::tick (bool missed, int scaledTime)
HeroStatus status = hero->run (scaledTime);
if ((status == WON_LEVEL) || (status == DEAD)) {
// TODO - Can this unsolicited timer pause cause problems in KGrGame?
timer->pause();
// TODO ? If caught in a brick, brick-closing animation is unfinished.
// Queued connection ensures KGrGame slot runs AFTER return from here.
......@@ -716,13 +723,13 @@ int KGrLevelPlayer::runnerGotGold (const int spriteId,
const bool hasGold, const bool lost)
{
if (hasGold) {
dbk3 << "GOLD COLLECTED BY" << spriteId << "AT" << i << j;
dbk2 << "GOLD COLLECTED BY" << spriteId << "AT" << i << j;
}
else if (lost) {
dbk3 << "GOLD LOST BY" << spriteId << "AT" << i << j;
dbk2 << "GOLD LOST BY" << spriteId << "AT" << i << j;
}
else {
dbk3 << "GOLD DROPPED BY" << spriteId << "AT" << i << j;
dbk2 << "GOLD DROPPED BY" << spriteId << "AT" << i << j;
}
if (! lost) {
grid->gotGold (i, j, hasGold); // Record pickup/drop on grid.
......@@ -767,7 +774,7 @@ void KGrLevelPlayer::makeReappearanceSequence()
reappearPos [left - 1] = temp;
left--;
}
dbk3 << "Randoms" << reappearPos;
dbk2 << "Randoms" << reappearPos;
reappearIndex = 0;
}
......@@ -811,7 +818,7 @@ void KGrLevelPlayer::enemyReappear (int & gridI, int & gridJ)
}
}
}
dbk3 << "Reappear at" << i << j;
dbk2 << "Reappear at" << i << j;
gridI = i;
gridJ = j;
}
......@@ -821,10 +828,13 @@ uchar KGrLevelPlayer::randomByte (const uchar limit)
if (! playback) {
uchar value = randomGen->getLong ((unsigned long) limit);
// A zero-byte terminates recording->draws, so add 1 when recording ...
dbe2 "Draw %03d, index %04d, limit %02d\n", value, randIndex, limit);
recording->draws [randIndex++] = value + 1;
return value;
}
else {
dbe2 "Draw %03d, index %04d, limit %02d\n",
(recording->draws.at (randIndex) - 1), randIndex, limit);
// and subtract 1 when replaying.
return ((uchar) recording->draws.at (randIndex++) - 1);
}
......@@ -837,6 +847,8 @@ bool KGrLevelPlayer::doRecordedMove()
while (true) {
// Check for end of recording.
if ((code == 0xff) || (code == 0)) {
dbe2 "T %04d recIndex %03d PLAY - END of recording\n",
T, recIndex);
return false;
}
// Check for a key press or mouse button click.
......@@ -844,7 +856,7 @@ bool KGrLevelPlayer::doRecordedMove()
playState = Playing;
code = code - 0x80;
if ((code == DIG_LEFT) || (code == DIG_RIGHT)) {
dbe3 "T %04d recIndex %03d PLAY dig code %d\n",
dbe2 "T %04d recIndex %03d PLAY dig code %d\n",
T, recIndex, code);
startDigging ((Direction)(code));
}
......@@ -862,7 +874,7 @@ bool KGrLevelPlayer::doRecordedMove()
// targetI = code;
// targetJ = (uchar)(recording->content [recIndex + 1]);
recCount = (uchar)(recording->content [recIndex + 2]);
dbe3 "T %04d recIndex %03d PLAY codes %d %d %d - NEW TARGET\n",
dbe2 "T %04d recIndex %03d PLAY codes %d %d %d - NEW TARGET\n",
T, recIndex, i, j, recCount);
// T, recIndex, targetI, targetJ, recCount);
......@@ -871,12 +883,12 @@ bool KGrLevelPlayer::doRecordedMove()
// emit setMousePos (i, j);
}
else {
dbe3 "T %04d recIndex %03d PLAY codes %d %d %d\n",
dbe2 "T %04d recIndex %03d PLAY codes %d %d %d\n",
T, recIndex, targetI, targetJ, recCount);
}
if (--recCount <= 0) {
recIndex = recIndex + 3;
dbe3 "T %04d recIndex %03d PLAY - next index\n",
dbe2 "T %04d recIndex %03d PLAY - next index\n",
T, recIndex);
}
break;
......
......@@ -25,7 +25,8 @@
#include "kgrrulebook.h"
KGrRunner::KGrRunner (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
int i, int j, int pSpriteId, KGrRuleBook * pRules)
int i, int j, const int pSpriteId,
KGrRuleBook * pRules, const int startDelay)
:
QObject (pLevelPlayer), // Destroy runner when level is destroyed.
levelPlayer (pLevelPlayer),
......@@ -41,13 +42,26 @@ KGrRunner::KGrRunner (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
currDirection (STAND),
currAnimation (FALL_L),
timeLeft (TickTime),
// The start delay is zero for the hero and 50 msec for the enemies. This
// gives the hero about one grid-point advantage. Without this lead, some
// levels become impossible, notably Challenge, 4, "Quick Off The Mark" and
// Curse of the Mummy, 20, "The Parting of the Red Sea".
timeLeft (TickTime + startDelay),
leftRightSearch (true)
{
getRules();
gridX = i * pointsPerCell;
gridY = j * pointsPerCell;
gridX = i * pointsPerCell;
gridY = j * pointsPerCell;
// As soon as the initial timeLeft has expired (i.e. at the first tick in
// the hero's case and after a short delay in the enemies' case), the
// pointCtr will reach its maximum, the EndCell situation will occur and
// each runner will look for a new direction and head that way if he can.
pointCtr = pointsPerCell - 1;
dbgLevel = 0;
}
KGrRunner::~KGrRunner()
......@@ -68,10 +82,14 @@ Situation KGrRunner::situation (const int scaledTime)
{
timeLeft -= scaledTime;
if (timeLeft >= scaledTime) {
dbe3 "%d sprite %02d scaled %02d timeLeft %03d - Not Time Yet\n",
pointCtr, spriteId, scaledTime, timeLeft);
return NotTimeYet;
}
if (grid->cellType (gridI, gridJ) == BRICK) {
dbe2 "%d sprite %02d scaled %02d timeLeft %03d - Caught in brick\n",
pointCtr, spriteId, scaledTime, timeLeft);
return CaughtInBrick;
}
......@@ -82,9 +100,13 @@ Situation KGrRunner::situation (const int scaledTime)
// TODO - Count one extra tick when turning to L or R from another dirn.
if (pointCtr < pointsPerCell) {
timeLeft += interval;
dbe2 "%d sprite %02d scaled %02d timeLeft %03d - Mid Cell\n",
pointCtr, spriteId, scaledTime, timeLeft);
return MidCell;
}
dbe2 "%d sprite %02d scaled %02d timeLeft %03d - END Cell\n",
pointCtr, spriteId, scaledTime, timeLeft);
return EndCell;
}
......@@ -92,7 +114,7 @@ Situation KGrRunner::situation (const int scaledTime)
KGrHero::KGrHero (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
int i, int j, int pSpriteId, KGrRuleBook * pRules)
:
KGrRunner (pLevelPlayer, pGrid, i, j, pSpriteId, pRules),
KGrRunner (pLevelPlayer, pGrid, i, j, pSpriteId, pRules, 0),
nuggets (0) // KGrLevelPlayer object will call hero->setNuggets().
{
kDebug() << "THE HERO IS BORN at" << i << j << "sprite ID" << pSpriteId;
......@@ -126,6 +148,11 @@ HeroStatus KGrHero::run (const int scaledTime)
return WON_LEVEL;
}
// TODO - Do we need to do this on every grid-point?
bool standingOnEnemy = levelPlayer->standOnEnemy (spriteId, gridX, gridY);
if ((! standingOnEnemy) && levelPlayer->heroCaught (gridX, gridY)) {
return DEAD;
}
if (s == MidCell) {
return NORMAL;
}
......@@ -168,6 +195,9 @@ HeroStatus KGrHero::run (const int scaledTime)
timeLeft += interval;
dbe2 "%d sprite %02d [%02d,%02d] timeLeft %03d currDir %d nextDir %d\n",
pointCtr, spriteId, gridI, gridJ, timeLeft, currDirection, nextDirection);
if ((! onEnemy) && levelPlayer->heroCaught (gridX, gridY)) {
return DEAD;
}
......@@ -256,7 +286,7 @@ void KGrHero::showState (char option)
KGrEnemy::KGrEnemy (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
int i, int j, int pSpriteId, KGrRuleBook * pRules)
:
KGrRunner (pLevelPlayer, pGrid, i, j, pSpriteId, pRules),
KGrRunner (pLevelPlayer, pGrid, i, j, pSpriteId, pRules, 50),
nuggets (0),
birthI (i),
birthJ (j),
......@@ -406,6 +436,9 @@ void KGrEnemy::run (const int scaledTime)
deltaX = movement [nextDirection][X];
deltaY = movement [nextDirection][Y];
dbe2 "%d sprite %02d [%02d,%02d] timeLeft %03d currDir %d nextDir %d\n",
pointCtr, spriteId, gridI, gridJ, timeLeft, currDirection, nextDirection);
// If moving, occupy the next cell in the enemy's path and release this one.
if (nextDirection != STAND) {
// If multiple enemies move into a cell, they stack. Each enemy uses
......
......@@ -47,9 +47,11 @@ public:
* @param j The starting row-number (>=1).
* @param pSpriteId The sprite ID of the runner, as used in animation.
* @param pRules The rules that apply to this game and level.
* @param startDelay The starting-time advantage enemies give to the hero.
*/
KGrRunner (KGrLevelPlayer * pLevelPlayer, KGrLevelGrid * pGrid,
int i, int j, int pSpriteId, KGrRuleBook * pRules);
int i, int j, const int pSpriteId,
KGrRuleBook * pRules, const int startDelay);
virtual ~KGrRunner();
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment