コード例 #1
0
  //
  // GoToNextPoint
  //
  void SquadMoveTogether::GoToNextPoint(SquadObj::ListNode *node)
  {
    // We are attempting to go to the next point
    NPoint *p = points[node->data];
    node->data++;
    node->completed = TRUE;

    point = Max(point, node->data);

    ASSERT(node->Alive())
    UnitObj *unit = node->GetData();

    if (p)
    {
      // Mark the time a unit attempts to move to this point
      if (p->timestamp)
      {
        // The squad will need to wait for me to catch up
        if (GameTime::SimCycle() - p->timestamp > timeDiffMax)
        {
//          LOG_DIAG(("Detected that we're [%d] way behind at this point, changing to waiting state", node->Id()))
          NextState(0xCC45C48B); // "Waiting"
        }
      }
      else
      {
        p->timestamp = GameTime::SimCycle();

        // Since we're the first unit to this point we 
        // should check to make sure that no units are 
        // more than two points behind.  If there are,
        // then we'll have to wait here for them

        SquadObj::UnitList::Iterator i(&subject->GetList());
        for (!i; *i; i++)
        {
          if 
          (
            (*i)->Alive() && 
            ((*i)->data + pointDiffMax < point)
          )
          {
//            LOG_DIAG(("We're [%d] first to this point [%d] and detected that [%d] is way behind", node->Id(), node->data, (*i)->Id()))
            NextState(0xCC45C48B); // "Waiting"
            return;
          }
        }
      }

      // Find the closest point to that point that we can go to
      U32 x, z;

      // Use the formation slot offset for this unit
      Vector location(WorldCtrl::CellToMetresX(p->x), 0.0f, WorldCtrl::CellToMetresZ(p->z));

      F32 dir = p->direction + node->slot.direction;
      VectorDir::FixU(dir);

      F32 orient = p->direction + node->slot.orientation;
      VectorDir::FixU(orient);

      Vector offset;
      offset.x = (F32) cos(dir);
      offset.y = 0.0f;
      offset.z = (F32) sin(dir);
      offset *= node->slot.distance;
      offset += location;

      // Make sure the point is on the map
      WorldCtrl::ClampMetreMap(offset.x, offset.z);

      x = WorldCtrl::MetresToCellX(offset.x);
      z = WorldCtrl::MetresToCellZ(offset.z);

      if (PathSearch::FindClosestCell(unit->MapType()->GetTractionIndex(unit->MapType()->GetDefaultLayer()), x, z, x, z, meetingRange))
      {
        node->completed = FALSE;
        unit->PrependTask(new Tasks::UnitMove(unit, offset));
      }
      else
      {
        // Cound not find a cell, go to the next point
        GoToNextPoint(node);
      }
    }
  }
コード例 #2
0
  //
  // StateInit
  //
  void SquadBoard::StateInit()
  {
    // Get each of the units in the squad to board transports
    SquadObj::UnitList::Iterator u(&subject->GetList());

    // We could enhance this to use units which are closest to transports etc.

    // Clear the squad's completed flags
    for (!u; *u; u++)
    {
      (*u)->completed = FALSE;
      (*u)->task = 0;
    }

    // Reset squad iterator
    !u;

    for (TransportObjList::Iterator t(&transports); *t; t++)
    {
      if ((*t)->Alive())
      {
        TransportObj *transport = **t;
        U32 slots = transport->TransportType()->GetSpaces();
        U32 added = 0;

        while (slots--)
        {
          UnitObjPtr *unitPtr = *u;

          if (unitPtr)
          {
            ASSERT(unitPtr->Alive())
            UnitObj *unit = *unitPtr;

            if (unit->CanEverMove())
            {
              // Tell the unit to board
              unit->FlushTasks(Tasks::UnitBoard::GetConfigBlockingPriority());

              Task *task;

              // Is this a telepad
              if (TaskCtrl::PromoteIdle<Tasks::TransportPad>(transport))
              {
                unit->PrependTask(task = new Tasks::UnitMove(unit, transport), GetFlags());
              }
              else
              {
                unit->PrependTask(task = new Tasks::UnitBoard(unit, transport), GetFlags());
              }

              (*u)->task = task->GetTaskId();

              added++;
            }
            else
            {
              // This unit can't move so complete it
              (*u)->completed = TRUE;
            }
          }
          else
          {
            break;
          }

          // Increment iterator
          u++;
        }

        if (!added)
        {
          // No units were added
          break;
        }
      }
    }

    // Complete those units which missed out
    for (; *u; u++)
    {
      (*u)->completed = TRUE;
    }

    NextState(0x09E5F977); // "Boarding"
  }