Пример #1
0
void PlayerCharacterEntity::update()
{
  m_velocity = ((float)m_health + 10)/m_velocityModifier;

  if (m_controlledByAI == true)
  {
    // this is a bot character, here's the AI! :D

    // set check surroundings timer to one of two primes
    m_checkTimer--;
    if (m_checkTimer <= 0)
    {
      m_checkTimer = (rand()%2 > 0) ? 37 : 67;
      checkEnvironment();
    }

    if (m_goalList.empty() && m_insList.empty())
    {
      determineGoals();
    }

    if (m_insList.empty())
    {
      determineInstructionsFromGoal();
    }

    // add AI for important surroundings sensing whateverness

    processNextInstruction();
  }
}
Пример #2
0
static void instructionMove()
{
	checkToMap(self);

	setCustomAction(&player, &helpless, 5, 0, 0);

	if (self->dirX == 0 && self->dirY == 0)
	{
		processNextInstruction();
	}

	else if (self->x == self->endX && self->y == self->endY)
	{
		runScript("robot_end");

		self->dirX = 0;
		self->dirY = 0;

		self->action = &entityWait;

		setEntityAnimation(self, "STAND");

		activateEntitiesWithRequiredName(self->objectiveName, TRUE);

		centerMapOnEntity(&player);

		setPlayerLocked(FALSE);

		self->health = 2;

		self->target->inUse = FALSE;

		self->target = NULL;

		self->touch = NULL;

		self->activate = NULL;
	}
}
Пример #3
0
void PlayerCharacterEntity::processNextInstruction()
{
  if (m_insList.empty())
  {
    return;
  }

  AIInstruction * ins = m_insList.front();
  m_insList.pop_front();

  switch (ins->m_type)
  {
    case AIInstruction::CREATE_ENTITY:
      {
        if (m_health < 15)
        {
          break;
        }
        // check if this tile already has a static entity
        bool staticAtLocation = this->staticEntityAtLocation(getTileX(), getTileY());

        if (staticAtLocation)
        {
          // there is already a static entity

          // if this is an egg type required, move to nearest "empty" tile
          if (   ins->m_targetType == EGG1
                 || ins->m_targetType == EGG2
                 || ins->m_targetType == EGG3
                 || ins->m_targetType == EGG4
                 || ins->m_targetType == EGG5 )
          {
            // find nearest empty tile and move there, replace instruction

            if (goToNearestEmptyTile(ins->m_targetTileX, ins->m_targetTileY))
            {
              // can go to an empty tile
              AIInstruction * copiedIns =
                new AIInstruction(*ins);

              // put CREATE instruction after GOTO at head of list
              AIInstruction * goToIns = m_insList.front();
              m_insList.pop_front();
              m_insList.push_front(copiedIns);
              m_insList.push_front(goToIns);
            }
            else
            {
              // failed to find a nearby empty tile

              // forget this instruction for now

            }
          }
          else
          {
            // is a weapon/block type
            // probably not very helpful to move location
            // so forget this instruction

          }


        }
        else
        {
          // there isn't a static entity

          // if this is an egg, is it a safe enough location?

          // is this a weapon? if so, check desired spot
          if (ins->m_targetType == BOMB ||
              ins->m_targetType == BLOCK ||
              ins->m_targetType == MINE ||
              ins->m_targetType == ROCKET_SPIN)
          {
            if (ins->m_targetType == BOMB ||
                ins->m_targetType == MINE)
            {
              if (!safeLocationToBomb(m_tileX, m_tileY))
              {
                break;
              }
            }

            if (ins->m_targetTileX == m_tileX
                && ins->m_targetTileY == m_tileY)
            {
              createEntity(ins->m_targetType);
            }
          }
          else
          {
            // check this location is safe for an egg

            bool bombOrMineFound = false;

            for (int i = 0; i < 4; ++i)
            {
              int x, y;
              x = m_tileX;
              y = m_tileY;

              switch (i)
              {
                case 0:
                  x++;
                  break;
                case 1:
                  x--;
                  break;
                case 2:
                  y++;
                  break;
                case 3:
                  y--;
                  break;
              }

              vector<EntityInfo> eiVec = AIGameView::getInstance()->getEntityInfoAtLocation(x, y);
              vector<EntityInfo>::iterator it;

              for (it = eiVec.begin(); it != eiVec.end(); ++it)
              {
                // even our team's bombs and mines are dangerous to eggs
                if (it->type == BOMB || it->type == MINE)
                {
                  bombOrMineFound = true;
                  break;
                }

              }

              if (bombOrMineFound)
              {
                break;
              }

            } // end for 0..3

            if (!bombOrMineFound)
            {
              createEntity(ins->m_targetType);
            }
            else
            {
              // move elsewhere
              AIInstruction * copy = new AIInstruction(*ins);
              m_insList.push_front(copy);

              goNumTilesAway(3);
            }
          }
        }


      }
      break;
    case AIInstruction::GO_TO:
      {
        // check for simple 0 or 1 tile movement
        int xDist, yDist;
        xDist = m_tileX - ins->m_targetTileX;
        yDist = m_tileY - ins->m_targetTileY;

        bool moved = false;


        if (xDist == 0 && yDist == 0)
        {
          // in target tile, close enough to center?
          if (nearTileCenter())
          {
            // finished this instruction
            break;
          }
          else
          {
            // keep moving in current direction
            DIRECTION dir = static_cast<DIRECTION>(m_currentAnimState - 1);
            moveInDirection(dir);
            moved = true;
          }
        }

        // only one tile to go?

        // check target tile isn't blocked
        if (Map::getInstance()->staticTileAt(ins->m_targetTileX, ins->m_targetTileY) != Map::EMPTY)
        {
          break;
        }

        if (xDist == -1 && yDist == 0)
        {
          moveInDirection(RIGHT);
          moved = true;
        }
        else if (xDist == 1 && yDist == 0)
        {
          moveInDirection(LEFT);
          moved = true;
        }
        else if (xDist == 0 && yDist == 1)
        {
          moveInDirection(UP);
          moved = true;
        }
        else if (xDist == 0 && yDist == -1)
        {
          moveInDirection(DOWN);
          moved = true;
        }



        if (moved)
        {
          // copy instruction
          AIInstruction * copyIns = new AIInstruction(*ins);
          m_insList.push_front(copyIns);

          incAnimFrame();
          break;
        }


        // there is a multiple tile distance, use path finding

        // get next tile by pathfinding
        coord next = getNextTileFromPathfinding(ins->m_targetTileX, ins->m_targetTileY);
        // did pathfinding work?
        if (next.first == getTileX() && next.second == getTileY())
        {
          // did not work, or we're already where we want to be


        }
        else
        {
          // copy instruction
          AIInstruction * copyIns = new AIInstruction(*ins);
          m_insList.push_front(copyIns);

          // add this tile as goto
          AIInstruction * newIns = new AIInstruction(AIInstruction::GO_TO,
              0, getType(), next.first, next.second);
          m_insList.push_front(newIns);
          processNextInstruction();
        }

      }
      break;
    case AIInstruction::MOVE_FROM_LOCATION:
      {
        goNumTilesAway(ins->m_targetAmount);
      }
      break;
    case AIInstruction::WAIT:
      {
        int waitAmount = ins->m_targetAmount - 1;
        if (waitAmount > 0)
        {
          AIInstruction * newIns = new AIInstruction(ins->m_type,
              waitAmount, ins->m_targetType, ins->m_targetTileX, ins->m_targetTileY);
          m_insList.push_front(newIns);
        }
        // else nothing more to do
      }
      break;
  }

  delete ins;
}