Exemplo n.º 1
0
void KGrFigure::walkDown(int WALKDELAY, int FALLDELAY)
{
    if (hangAtPole() || (! canStand())) {
	// On bar or no firm ground underneath: so must fall.
	initFall (FALL2, FALLDELAY);
    }
    else {
	actualPixmap = (actualPixmap == CLIMB1) ? CLIMB2 : CLIMB1;
	if (walkCounter++ < 4) {
	    // Not end of 4-step cycle: move one step down, if possible.
	    if (canWalkDown()) {
		rely += STEP;
		absy += STEP;
	    }
	    walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE);
	}
	else {
	    // End of 4-step cycle: move down to next cell, if possible.
	    if (canWalkDown()) {
		y++;
	    }
	    // Always reset position, in case we are stuck partly into a brick.
	    rely = 0;
	    absy = y*16;

	    // Must be able to halt at a pole when going down.
	    if (! (canStand() || hangAtPole()))
		initFall(FALL2, FALLDELAY);	// kein Halt....urgs
	    else
		// Wait for caller to set next direction.
		status = STANDING;
	}
    }
}
Exemplo n.º 2
0
void KGrFigure::walkRight(int WALKDELAY, int FALLDELAY)
{
    if (walkCounter++) {		// wenn 0, soll sich Figur nur umdrehen
	if (++actualPixmap % 4) {	// wenn true, dann ist kein vollständiger Schritt gemacht
	    if (canWalkRight()) {
		relx += STEP;
		absx += STEP;	// nur vorwärts gehen, wenn es auch möglich ist
	    }
	    walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE);
	}
	else {
	    actualPixmap -= 4;		// Schritt war vollendet
	    if (canWalkRight()) {
		x++;
	    }				//gehe entgültig nach rechts
	    // Always reset position, in case we are stuck partly into a brick.
	    relx = 0;
	    absx = x*16;

	    if (!(canStand()||hangAtPole())) // kein Halt mehr...arrrgghhh
		initFall (FALL2, FALLDELAY);
	    else
		status = STANDING;	// Figur hat Halt
	}
    }
    else {
	status = STANDING;		// Figur sollte sich nur Umdrehen.
    }
}
Exemplo n.º 3
0
void KGrFigure::walkLeft (int WALKDELAY, int FALLDELAY)
{
    // If counter != 0, the figure is walking, otherwise he is turning around.
    if (walkCounter++ != 0) {
	// Change to the next pixmap in the animation.
	if ((++actualPixmap%4) != 0) {
	    // Not end of 4-pixmap cycle: move one step left, if possible.
	    if (canWalkLeft()) {
		relx -= STEP;
		absx -=STEP;
	    }
	    walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE);
	}
	else {
	    // End of 4-pixmap cycle: start again, in next cell if possible.
	    actualPixmap -= 4;
	    if (canWalkLeft()) {
		x--;
	    }
	    // Always reset position, in case we are stuck partly into a brick.
	    relx = 0;
	    absx = x*16;

	    // If cannot stand or hang, start fall, else await next assignment.
	    if (! (canStand() || hangAtPole()))
		initFall (FALL1, FALLDELAY);
	    else
		status = STANDING;	// Caller should set next direction.
	}
    }
    else {
	status = STANDING;		// The figure is turning around.
    }
}
Exemplo n.º 4
0
Direction KGrEnemy::searchbestway(int ew,int eh,int hw,int hh)
{
  Direction dirn;

  if ((*playfield)[x][y]->whatIam() == USEDHOLE)	// Could not get out of
      return UP;					// hole (eg. brick above
							// closed): keep trying.

  if (!canStand() &&					// Cannot stand,
      !hangAtPole() &&					// not on pole, not
      !standOnEnemy() &&				// walking on friend and
      !((*playfield)[x][y+1]->whatIam() == HOLE))	// not just out of hole,
      return DOWN;					// so must fall.

  switch (searchStrategy) {

  // Traditional search strategy.
  case LOW:
  dirn = STAND;
  if (eh == hh) {					// Hero on same row.
    dirn = lowGetHero (ew, eh, hw);
  }
  if (dirn != STAND) return (dirn);			// Can go towards him.

  if (eh >= hh) {					// Hero above enemy.
    dirn = lowSearchUp (ew, eh, hh);		// Find a way up.
  }
  else {						// Hero below enemy.
    dirn = lowSearchDown (ew, eh, hh);		// Find way down to him.
    if (dirn == STAND) {
	dirn = lowSearchUp (ew, eh, hh);		// No go: try up.
    }
  }

  if (dirn == STAND) {					// When all else fails,
    dirn = lowSearchDown (ew, eh, eh - 1);		// find way below hero.
  }
  return dirn;
  break;

  // KGoldrunner search strategy.
  case MEDIUM:
  case HIGH:
  if(searchStatus==VERTIKAL){
    if (eh > hh)
      return searchupway(ew,eh);
    if (eh < hh)
      return searchdownway(ew,eh);
    return STAND;
  } else {
    if (ew > hw)
      return searchleftway(ew,eh);
    if (ew < hw)
      return searchrightway(ew,eh);
    return STAND;
  }
  break;
  }
  return STAND;
}
Exemplo n.º 5
0
/* Es ist Notwendig der eigentlichen Timerfunktion diese
   Startwalk vorzuschalten, um bei einem evtl. notwendigem
   Richtungswechsel der Figur diese Bewegung mit einzufügen */
void KGrHero::startWalk ()
{
  switch (nextDir) {
    case UP:
      if ((*playfield)[x][y]->whatIam () == LADDER)
	{walkCounter = 1;
	direction = UP;}
      break;
    case RIGHT:
      if (hangAtPole())
	actualPixmap = RIGHTCLIMB1;
      else
	actualPixmap = RIGHTWALK1;
      if (direction != RIGHT)
	walkCounter = 0;
      else
	walkCounter = 1;
      direction = RIGHT;
      break;
    case DOWN:
      if (((*playfield)[x][y]->whatIam () == LADDER)||
	  ((*playfield)[x][y+1]->whatIam () == LADDER))
	{walkCounter = 1;
	direction = DOWN;}
      else // wenn figur an Stange haengt und nichts unter ihr,
	if (hangAtPole() && (!canStand())) // dann soll sie fallen
	  { status = STANDING;
	  actualPixmap = (direction==RIGHT)?19:18;
	  walkCounter=1;
	  direction=STAND;
	  walkTimer->stop();
	  }
      break;
    case LEFT:
      if (hangAtPole())
	actualPixmap = LEFTCLIMB1;
      else
	actualPixmap = LEFTWALK1;
      if (direction != LEFT)
	walkCounter = 0;
      else
	walkCounter = 1;
      direction = LEFT;
      break;
    default :
      direction = STAND;
      status = FALLING;
      break;
    }
  nextDir = STAND;
  if (status != FALLING)//immer ausführen, ausser beim fallen
    { status = WALKING; // da sonst der FALLINGstatus wieder
    showFigure ();      // geaendert wird und der falsche Timer anspringt.
    }
} // END KGrHero::startWalk
Exemplo n.º 6
0
void KGrHero::fallTimeDone()
{
    if (! started) return;		// Ignore signals from earlier play.
    if (KGrObject::frozen) {fallFrozen = TRUE; return; }

    if (!standOnEnemy()) {
	if (walkCounter++ < 4) {	// Held fällt vier Positionen
	    fallTimer->start((FALLDELAY * NSPEED) / speed, TRUE);
	    rely+=STEP;
	    absy+=STEP;
	}
	else {				//Held ist ein Feld weitergefallen
	    // Verschiebung der Figur zum 0-Punkt des Objekts (Brick etc...)
	    heroy = ++y;
	    rely = 0;
	    absy = y*16;		// wird Null und Figur eins runter
	    collectNugget();		// gesetzt. Zeit evtl. Nugget zu nehmen
	    if (! (canStand()||hangAtPole())) {	// Held muss wohl weiterfallen.
		fallTimer->start((FALLDELAY * NSPEED) / speed, TRUE);
		walkCounter = 1;
	    }
	    else {			// Held hat Boden (oder Feind) unter den
		status = STANDING;	// Füssen oder hängt an Stange -> steh!
		walkTimer->start((WALKDELAY * NSPEED) / speed, TRUE);
		direction = (actualPixmap == 19) ? RIGHT : LEFT;
		if ((*playfield)[x][y]->whatIam() == POLE)
		    actualPixmap = (direction == RIGHT)? RIGHTCLIMB1:LEFTCLIMB1;
		// else
		    // Reduce jerkiness when descending over a falling enemy.
		    // actualPixmap = (direction == RIGHT)? RIGHTWALK1:LEFTWALK1;
	    }
	}
	showFigure();
    }
    else {
	if (rely == 0) {
	    // If at the bottom of a cell, try to walk or just stand still.
	    status = STANDING;
	    direction = (actualPixmap == 19) ? RIGHT : LEFT;
	    if ((*playfield)[x][y]->whatIam() == POLE)
		actualPixmap = (direction == RIGHT)? RIGHTCLIMB1:LEFTCLIMB1;
	    // else
		// Reduce jerkiness when descending over a falling enemy.
		// actualPixmap = (direction == RIGHT)? RIGHTWALK1:LEFTWALK1;
	    walkTimer->start((WALKDELAY * NSPEED) / speed, TRUE);
	}
	else {
	    // Else, freeze hero until enemy moves out of the way.
	    fallTimer->start((FALLDELAY * NSPEED) / speed, TRUE);
	}
    }
    if (isInEnemy() && (! standOnEnemy()))
	emit caughtHero();
}
Exemplo n.º 7
0
void KGrHero::start()
{
    started = TRUE;
    walkFrozen = FALSE;
    fallFrozen = FALSE;

    if (!(canStand()||hangAtPole())) {		// Held muss wohl fallen...
	status = FALLING;
	fallTimeDone();
    }
    else {
	status = STANDING;
	walkTimeDone();
    }
}
Exemplo n.º 8
0
void KGrEnemy::startSearching()
{
    // Called from "KGoldrunner::startPlaying" and "KGrEnemy::dieAndReappear".
    init(x,y);

    if (canStand()||((*playfield)[x][y+1]->whatIam()==USEDHOLE)) {
	status = WALKING;
	walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE);
    }
    else {
	status = FALLING;
	fallTimer->start ((FALLDELAY * NSPEED) / speed, TRUE);
    }

    walkCounter = 1;
    direction = searchbestway(x,y,herox,heroy);
    startWalk();
}
Exemplo n.º 9
0
Direction KGrEnemy :: searchupway(int ew,int eh){
int i,j;
 i=j=ew;
 if ( (*playfield)[ew][eh]->searchValue & CANWALKUP)
   return UP;
 else while((i>=0)||(j<=FIELDWIDTH)){// search for the first way up
   if (i>=0)
     if ( (*playfield)[i][eh]->searchValue & CANWALKUP)
       return LEFT;
     else
       if (!(( (*playfield)[i--][eh]->searchValue & CANWALKLEFT) ||
	     (runThruHole && ( (*playfield)[i][eh]->whatIam() == HOLE))))
       i=-1;
   if (j<=FIELDWIDTH)
     if ( (*playfield)[j][eh]->searchValue & CANWALKUP)
       return RIGHT;
     else
       if (!(( (*playfield)[j++][eh]->searchValue & CANWALKRIGHT) ||
	     (runThruHole && ( (*playfield)[j][eh]->whatIam() == HOLE))))
	 j=FIELDWIDTH+1;
 }
 // BUG FIX - Ian W., 30/4/01 - Don't leave an enemy standing in mid air.
 if (!canStand()) return DOWN; else return STAND;
}
// Checked: 2010-12-11 (RLVa-1.2.2)
bool RlvActions::canAcceptTpOffer(const LLUUID& idSender)
{
	return ((!gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) || (gRlvHandler.isException(RLV_BHVR_TPLURE, idSender))) && (canStand());
}
Exemplo n.º 11
0
/**
 * This method calculates the moves for the AI player
 *
 * @param movePtr Pointer to move the move list into
 */
bool AIPlayer::getAIMove(Move *movePtr)
{
   *movePtr = NullMove;

   // Use the eye as the current position.
   MatrixF eye;
   getEyeTransform(&eye);
   Point3F location = eye.getPosition();
   Point3F rotation = getRotation();

#ifdef TORQUE_NAVIGATION_ENABLED
   if(mDamageState == Enabled)
   {
      if(mMoveState != ModeStop)
         updateNavMesh();
      if(!mFollowData.object.isNull())
      {
         if(mPathData.path.isNull())
         {
            if((getPosition() - mFollowData.object->getPosition()).len() > mFollowData.radius)
               followObject(mFollowData.object, mFollowData.radius);
         }
         else
         {
            if((mPathData.path->mTo - mFollowData.object->getPosition()).len() > mFollowData.radius)
               repath();
            else if((getPosition() - mFollowData.object->getPosition()).len() < mFollowData.radius)
            {
               clearPath();
               mMoveState = ModeStop;
            throwCallback("onTargetInRange");
            }
            else if((getPosition() - mFollowData.object->getPosition()).len() < mAttackRadius)
            {
            throwCallback("onTargetInFiringRange");
            }
         }
      }
   }
#endif // TORQUE_NAVIGATION_ENABLED

   // Orient towards the aim point, aim object, or towards
   // our destination.
   if (mAimObject || mAimLocationSet || mMoveState != ModeStop) 
   {
      // Update the aim position if we're aiming for an object
      if (mAimObject)
         mAimLocation = mAimObject->getPosition() + mAimOffset;
      else
         if (!mAimLocationSet)
            mAimLocation = mMoveDestination;

      F32 xDiff = mAimLocation.x - location.x;
      F32 yDiff = mAimLocation.y - location.y;

      if (!mIsZero(xDiff) || !mIsZero(yDiff)) 
      {
         // First do Yaw
         // use the cur yaw between -Pi and Pi
         F32 curYaw = rotation.z;
         while (curYaw > M_2PI_F)
            curYaw -= M_2PI_F;
         while (curYaw < -M_2PI_F)
            curYaw += M_2PI_F;

         // find the yaw offset
         F32 newYaw = mAtan2( xDiff, yDiff );
         F32 yawDiff = newYaw - curYaw;

         // make it between 0 and 2PI
         if( yawDiff < 0.0f )
            yawDiff += M_2PI_F;
         else if( yawDiff >= M_2PI_F )
            yawDiff -= M_2PI_F;

         // now make sure we take the short way around the circle
         if( yawDiff > M_PI_F )
            yawDiff -= M_2PI_F;
         else if( yawDiff < -M_PI_F )
            yawDiff += M_2PI_F;

         movePtr->yaw = yawDiff;

         // Next do pitch.
         if (!mAimObject && !mAimLocationSet) 
         {
            // Level out if were just looking at our next way point.
            Point3F headRotation = getHeadRotation();
            movePtr->pitch = -headRotation.x;
         }
         else 
         {
            // This should be adjusted to run from the
            // eye point to the object's center position. Though this
            // works well enough for now.
            F32 vertDist = mAimLocation.z - location.z;
            F32 horzDist = mSqrt(xDiff * xDiff + yDiff * yDiff);
            F32 newPitch = mAtan2( horzDist, vertDist ) - ( M_PI_F / 2.0f );
            if (mFabs(newPitch) > 0.01f) 
            {
               Point3F headRotation = getHeadRotation();
               movePtr->pitch = newPitch - headRotation.x;
            }
         }
      }
   }
   else 
   {
      // Level out if we're not doing anything else
      Point3F headRotation = getHeadRotation();
      movePtr->pitch = -headRotation.x;
   }

   // Move towards the destination
   if (mMoveState != ModeStop) 
   {
      F32 xDiff = mMoveDestination.x - location.x;
      F32 yDiff = mMoveDestination.y - location.y;

      // Check if we should mMove, or if we are 'close enough'
      if (mFabs(xDiff) < mMoveTolerance && mFabs(yDiff) < mMoveTolerance) 
      {
         mMoveState = ModeStop;
         onReachDestination();
      }
      else 
      {
         // Build move direction in world space
         if (mIsZero(xDiff))
            movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
         else
            if (mIsZero(yDiff))
               movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f;
            else
               if (mFabs(xDiff) > mFabs(yDiff)) 
               {
                  F32 value = mFabs(yDiff / xDiff);
                  movePtr->y = (location.y > mMoveDestination.y) ? -value : value;
                  movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f;
               }
               else 
               {
                  F32 value = mFabs(xDiff / yDiff);
                  movePtr->x = (location.x > mMoveDestination.x) ? -value : value;
                  movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
               }

         // Rotate the move into object space (this really only needs
         // a 2D matrix)
         Point3F newMove;
         MatrixF moveMatrix;
         moveMatrix.set(EulerF(0.0f, 0.0f, -(rotation.z + movePtr->yaw)));
         moveMatrix.mulV( Point3F( movePtr->x, movePtr->y, 0.0f ), &newMove );
         movePtr->x = newMove.x;
         movePtr->y = newMove.y;

         // Set movement speed.  We'll slow down once we get close
         // to try and stop on the spot...
         if (mMoveSlowdown) 
         {
            F32 speed = mMoveSpeed;
            F32 dist = mSqrt(xDiff*xDiff + yDiff*yDiff);
            F32 maxDist = mMoveTolerance*2;
            if (dist < maxDist)
               speed *= dist / maxDist;
            movePtr->x *= speed;
            movePtr->y *= speed;

            mMoveState = ModeSlowing;
         }
         else 
         {
            movePtr->x *= mMoveSpeed;
            movePtr->y *= mMoveSpeed;

            mMoveState = ModeMove;
         }

         if (mMoveStuckTestCountdown > 0)
            --mMoveStuckTestCountdown;
         else
         {
            // We should check to see if we are stuck...
            F32 locationDelta = (location - mLastLocation).len();
            if (locationDelta < mMoveStuckTolerance && mDamageState == Enabled) 
            {
               // If we are slowing down, then it's likely that our location delta will be less than
               // our move stuck tolerance. Because we can be both slowing and stuck
               // we should TRY to check if we've moved. This could use better detection.
               if ( mMoveState != ModeSlowing || locationDelta == 0 )
               {
                  mMoveState = ModeStuck;
                  onStuck();
               }
            }
         }
      }
   }

   // Test for target location in sight if it's an object. The LOS is
   // run from the eye position to the center of the object's bounding,
   // which is not very accurate.
   if (mAimObject)
   {
      if (checkInLos(mAimObject.getPointer()))
      {
         if (!mTargetInLOS)
         {
            throwCallback( "onTargetEnterLOS" );
            mTargetInLOS = true;
         }
   }
      else if (mTargetInLOS)
      {
            throwCallback( "onTargetExitLOS" );
            mTargetInLOS = false;
         }
      }

   Pose desiredPose = mPose;

   if ( mSwimming )  
      desiredPose = SwimPose;   
   else if ( mAiPose == 1 && canCrouch() )   
      desiredPose = CrouchPose;  
   else if ( mAiPose == 2 && canProne() )  
      desiredPose = PronePose;  
   else if ( mAiPose == 3 && canSprint() )  
      desiredPose = SprintPose;  
   else if ( canStand() )  
      desiredPose = StandPose;  
  
   setPose( desiredPose );
   
   // Replicate the trigger state into the move so that
   // triggers can be controlled from scripts.
   for( U32 i = 0; i < MaxTriggerKeys; i++ )
      movePtr->trigger[ i ] = getImageTriggerState( i );

#ifdef TORQUE_NAVIGATION_ENABLED
   if(mJump == Now)
   {
      movePtr->trigger[2] = true;
      mJump = None;
   }
   else if(mJump == Ledge)
   {
      // If we're not touching the ground, jump!
      RayInfo info;
      if(!getContainer()->castRay(getPosition(), getPosition() - Point3F(0, 0, 0.4f), StaticShapeObjectType, &info))
      {
         movePtr->trigger[2] = true;
         mJump = None;
      }
   }
#endif // TORQUE_NAVIGATION_ENABLED

   mLastLocation = location;

   return true;
}
Exemplo n.º 12
0
void KGrEnemy::fallTimeDone ()
{
  if (KGrObject::frozen) {fallFrozen = TRUE; return; }

  if ((*playfield)[x][y+1]->whatIam() == HOLE) {  // wenn Enemy ins Loch fällt
    ((KGrBrick*)(*playfield)[x][y+1])->useHole(); // reserviere das Loch, damit
						  // kein anderer es benutzt und
    if (nuggets) {			  // er muss Gold vorher fallen lassen
      nuggets=0;
      switch ((*playfield)[x][y]->whatIam()) {
      case FREE:
      case HLADDER:	
        ((KGrFree *)(*playfield)[x][y])->setNugget(true); break;
      default:
	emit lostNugget(); break;		// Cannot drop the nugget here.
      }
    }
    emit trapped (75);				// Enemy trapped: score 75.
  }
  else if (walkCounter <= 1) {
	// Enemies collect nuggets when falling.
	if (!nuggets) {
	  collectNugget();
	}
  }

  if ((*playfield)[x][y]->whatIam()==BRICK) {	// sollte er aber in einem Brick
    dieAndReappear();				// sein, dann stirbt er wohl
    return;			// Must leave "fallTimeDone" when an enemy dies.
    }

  if (standOnEnemy()) {				// Don't fall into a friend.
    fallTimer->start((FALLDELAY * NSPEED) / speed, TRUE);
    return;
  }

  if (walkCounter++ < 4){
    fallTimer->start((FALLDELAY * NSPEED) / speed, TRUE);
    { rely+=STEP; absy+=STEP;}
  }
  else {
    rely = 0; y ++; absy=16*y;
    if ((*playfield)[x][y]->whatIam() == USEDHOLE) {
        captiveCounter = 0;
        status = CAPTIVE;
        captiveTimer->start((CAPTIVEDELAY * NSPEED) / speed, TRUE);
    }
    else if (!(canStand()||hangAtPole())) {
	fallTimer->start((FALLDELAY * NSPEED) / speed, TRUE);
	walkCounter=1;
    }
    else {
	status = STANDING;
	if (hangAtPole())
	  actualPixmap=(direction ==RIGHT)?8:12;
    }
  }
  if (status == STANDING) {
    status = WALKING;
    walkCounter = 1;
    direction = searchbestway(x,y,herox,heroy);
    walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE);
    startWalk ();
    if (!nuggets)
      collectNugget();
    else
      dropNugget();
  }
  showFigure();
}
Exemplo n.º 13
0
void KGrEnemy::walkTimeDone ()
{
  if (KGrObject::frozen) {walkFrozen = TRUE; return; }

  // Check we are alive BEFORE checking for friends being in the way.
  // Maybe a friend overhead is blocking our escape from a brick.
  if ((*playfield)[x][y]->whatIam()==BRICK) {	// sollte er aber in einem Brick
    dieAndReappear();				// sein, dann stirbt er wohl
    return;			// Must leave "walkTimeDone" when an enemy dies.
    }

  if (! bumpingFriend()) {
    switch (direction) {
      case UP:		walkUp (WALKDELAY);
			if ((rely == 0) &&
			    ((*playfield)[x][y+1]->whatIam() == USEDHOLE))
			    // Enemy kletterte grad aus einem Loch hinaus
			    // -> gib es frei!
			    ((KGrBrick *)(*playfield)[x][y+1])->unUseHole();
			break;
      case DOWN:	walkDown (WALKDELAY, FALLDELAY); break;
      case RIGHT:	walkRight (WALKDELAY, FALLDELAY); break;
      case LEFT:	walkLeft (WALKDELAY, FALLDELAY); break;
      default:		// Switch search direction in KGoldrunner search (only).
			searchStatus = (searchStatus==VERTIKAL) ?
					HORIZONTAL : VERTIKAL;

                        // In KGoldrunner rules, if a hole opens under an enemy
                        // who is standing and waiting to move, he should fall.
                        if (!(canStand()||hangAtPole())) {
                            initFall (actualPixmap, FALLDELAY);
                        }
                        else {
                            status = STANDING;
                        }

			break;
    }
    // wenn die Figur genau ein Feld gelaufen ist
    if (status == STANDING) { // dann suche den Helden
      direction = searchbestway(x,y,herox,heroy); // und
      if (walkCounter >= 4) {
        if (! nuggets)
	    collectNugget();
        else
	    dropNugget();
      }
      status = WALKING; // initialisiere die Zählervariablen und
      walkCounter = 1; // den Timer um den Held weiter
      walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE); // zu jagen
      startWalk ();
      }
  }
  else {
    // A friend is in the way.  Try a new direction, but not if leaving a hole.
    Direction dirn;

    // In KGoldrunner rules, change the search strategy,
    // to avoid enemy-enemy deadlock.
    searchStatus = (searchStatus==VERTIKAL) ? HORIZONTAL : VERTIKAL;

    dirn = searchbestway (x, y, herox, heroy);
    if ((dirn != direction) && ((*playfield)[x][y]->whatIam() != USEDHOLE)) {
      direction = dirn;
      status = WALKING;
      walkCounter = 1;
      relx = 0; absx = 16 * x;
      rely = 0; absy = 16 * y;
      startWalk ();
    }
    walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE);
  }
  showFigure();
}
Exemplo n.º 14
0
void KGrHero::walkTimeDone ()
{
  if (! started) return;	// Ignore signals from earlier play.
  if (KGrObject::frozen) {walkFrozen = TRUE; return; }

  if ((*playfield)[x][y]->whatIam() == BRICK) {
    emit caughtHero();		// Brick closed over hero.
    return;
  }

  if ((y==1)&&(nuggets<=0)) {	// If on top row and all nuggets collected,
    emit leaveLevel();		// the hero has won and can go to next level.
    return;
  }

  if (status == STANDING)
    setNextDir();
  if ((status == STANDING) && (nextDir != STAND)) {
    if ((standOnEnemy()) && (nextDir == DOWN)) {
	emit caughtHero();	// Hero is going to step down into an enemy.
	return;
    }
    startWalk();
  }
  if (status != STANDING) {
      switch (direction) {
      case UP:		walkUp (WALKDELAY); break;
      case DOWN:	walkDown (WALKDELAY, FALLDELAY); break;
      case RIGHT:	walkRight (WALKDELAY, FALLDELAY); break;
      case LEFT:	walkLeft (WALKDELAY, FALLDELAY); break;
      default :
	// The following code is strange.  It makes the hero fall off a pole.
	// It works because of other strange code in "startWalk(), case DOWN:".
	if (!canStand()||hangAtPole()) // falling
	  initFall(FALL1, FALLDELAY);
	else  status = STANDING;
      break;
      }
    herox=x;heroy=y; // Koordinatenvariablen neu
    // wenn Held genau ein Feld weitergelaufen ist,
    if ((relx==0)&&(rely==0)) // dann setzte statische
      {
      collectNugget(); // und nehme evtl. Nugget
      }
    showFigure();	// Is this REDUNDANT now?  See showFigure() below.
			//////////////////////////////////////////////////
    }
  if (status == STANDING)
    if (!canStand()&&!hangAtPole())
      initFall(FALL1, FALLDELAY);
    else
      walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE);

  // This additional showFigure() is to update the hero position after it is
  // altered by the hero-enemy deadlock fix in standOnEnemy().  Messy, but ...
  ////////////////////////////////////////////////////////////////////////////
  showFigure();
  if(isInEnemy()) {
    walkTimer->stop();
    emit caughtHero();
  }
}