当前位置: 首页>>代码示例>>C++>>正文


C++ CUnit::CanMove方法代码示例

本文整理汇总了C++中CUnit::CanMove方法的典型用法代码示例。如果您正苦于以下问题:C++ CUnit::CanMove方法的具体用法?C++ CUnit::CanMove怎么用?C++ CUnit::CanMove使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在CUnit的用法示例。


在下文中一共展示了CUnit::CanMove方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1:

/* virtual */ void COrder_Move::Execute(CUnit &unit)
{
    Assert(unit.CanMove());

    if (unit.Wait) {
        if (!unit.Waiting) {
            unit.Waiting = 1;
            unit.WaitBackup = unit.Anim;
        }
        UnitShowAnimation(unit, unit.Type->Animations->Still);
        unit.Wait--;
        return;
    }
    if (unit.Waiting) {
        unit.Anim = unit.WaitBackup;
        unit.Waiting = 0;
    }
    // FIXME: (mr-russ) Make a reachable goal here with GoalReachable ...

    switch (DoActionMove(unit)) { // reached end-point?
        case PF_UNREACHABLE:
            // Some tries to reach the goal
            this->Range++;
            break;

        case PF_REACHED:
            this->Finished = true;
            break;
        default:
            break;
    }
}
开发者ID:JerryZhou,项目名称:Stratagus,代码行数:32,代码来源:action_move.cpp

示例2: CommandPatrolUnit

/**
**  Let a unit patrol from current to new position
**
**  FIXME: want to support patroling between units.
**
**  @param unit   pointer to unit.
**  @param pos    map position to patrol between.
**  @param flush  if true, flush command queue.
*/
void CommandPatrolUnit(CUnit &unit, const Vec2i &pos, int flush)
{
    Assert(Map.Info.IsPointOnMap(pos));

    if (IsUnitValidForNetwork(unit) == false) {
        return ;
    }
    //Wyrmgus start
    CMapField &mf = *Map.Field(unit.tilePos);
    if ((mf.Flags & MapFieldBridge) && !unit.Type->BoolFlag[BRIDGE_INDEX].value && unit.Type->UnitType == UnitTypeLand) { 
        std::vector<CUnit *> table;
        Select(unit.tilePos, unit.tilePos, table);
        for (size_t i = 0; i != table.size(); ++i) {
            if (!table[i]->Removed && table[i]->Type->BoolFlag[BRIDGE_INDEX].value && table[i]->CanMove()) {
                CommandStopUnit(*table[i]); //always stop the raft if a new command is issued
            }
        }
    }
    //Wyrmgus end
    COrderPtr *order;

    if (!unit.CanMove()) {
        ClearNewAction(unit);
        order = &unit.NewOrder;
    } else {
        order = GetNextOrder(unit, flush);
        if (order == NULL) {
            return;
        }
    }
    *order = COrder::NewActionPatrol(unit.tilePos, pos);

    ClearSavedAction(unit);
}
开发者ID:meiavy,项目名称:Wyrmgus,代码行数:43,代码来源:command.cpp

示例3: AutoRepair

/* virtual */ void COrder_Still::Execute(CUnit &unit)
{
    // If unit is not bunkered and removed, wait
    if (unit.Removed
        //Wyrmgus start
//		&& (unit.Container == nullptr || unit.Container->Type->BoolFlag[ATTACKFROMTRANSPORTER_INDEX].value == false)) {
        && (unit.Container == nullptr || !unit.Container->Type->BoolFlag[ATTACKFROMTRANSPORTER_INDEX].value || !unit.Type->BoolFlag[ATTACKFROMTRANSPORTER_INDEX].value)) { // make both the unit and the transporter have the tag be necessary for the attack to be possible
            if (unit.Container != nullptr) {
                LeaveShelter(unit); // leave shelter if surrounded
            }
        //Wyrmgus end
        return ;
    }
    this->Finished = false;

    switch (this->State) {
        case SUB_STILL_STANDBY:
            //Wyrmgus start
//			UnitShowAnimation(unit, unit.Type->Animations->Still);
            if (unit.Variable[STUN_INDEX].Value == 0) { //only show the idle animation when still if the unit is not stunned
                UnitShowAnimation(unit, unit.GetAnimations()->Still);
            }
            if (SyncRand(100000) == 0) {
                PlayUnitSound(unit, VoiceIdle);
            }
            unit.StepCount = 0;
            //Wyrmgus end
            break;
        case SUB_STILL_ATTACK: // attacking unit in attack range.
            AnimateActionAttack(unit, *this);
            break;
    }
    if (unit.Anim.Unbreakable) { // animation can't be aborted here
        return;
    }
    //Wyrmgus start
    if (unit.Variable[STUN_INDEX].Value > 0) { //if unit is stunned, remain still
        return;
    }
    //Wyrmgus end
    this->State = SUB_STILL_STANDBY;
    this->Finished = (this->Action == UnitActionStill);
    if (this->Action == UnitActionStandGround || unit.Removed || unit.CanMove() == false) {
        if (unit.AutoCastSpell) {
            this->AutoCastStand(unit);
        }
        if (unit.IsAgressive()) {
            this->AutoAttackStand(unit);
        }
    } else {
        if (AutoCast(unit) || (unit.IsAgressive() && AutoAttack(unit))
            || AutoRepair(unit)
            //Wyrmgus start
//			|| MoveRandomly(unit)) {
            || MoveRandomly(unit) || PickUpItem(unit)) {
            //Wyrmgus end
        }
    }
}
开发者ID:Andrettin,项目名称:Wyrmgus,代码行数:59,代码来源:action_still.cpp

示例4:

/**
**  Unit attacks!
**
**  if (SubAction & WEAK_TARGET) is true the goal is a weak goal.
**  This means the unit AI (little AI) could choose a new better goal.
**
**  @todo  Lets do some tries to reach the target.
**         If target place is not reachable, choose better goal to reduce
**         the pathfinder load.
**
**  @param unit  Unit, for that the attack is handled.
*/
/* virtual */ void COrder_Attack::Execute(CUnit &unit)
{
    Assert(this->HasGoal() || Map.Info.IsPointOnMap(this->goalPos));

    if (unit.Wait) {
        unit.Wait--;
        return;
    }

    switch (this->State) {
        case 0: { // First entry
            // did Order change ?
            if (CheckForTargetInRange(unit)) {
                return;
            }
            // Can we already attack ?
            if (this->HasGoal()) {
                CUnit &goal = *this->GetGoal();
                const int dist = goal.MapDistanceTo(unit);

                if (unit.Type->MinAttackRange < dist &&
                    dist <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
                    const Vec2i dir = goal.tilePos + goal.Type->GetHalfTileSize() - unit.tilePos;

                    UnitHeadingFromDeltaXY(unit, dir);
                    this->State = ATTACK_TARGET;
                    AttackTarget(unit);
                    return;
                }
            }
            this->State = MOVE_TO_TARGET;
            // FIXME: should use a reachable place to reduce pathfinder time.
        }
        // FALL THROUGH
        case MOVE_TO_TARGET:
        case MOVE_TO_TARGET + WEAK_TARGET:
            if (!unit.CanMove()) {
                this->Finished = true;
                return;
            }
            MoveToTarget(unit);
            break;

        case ATTACK_TARGET:
        case ATTACK_TARGET + WEAK_TARGET:
            AttackTarget(unit);
            break;

        case WEAK_TARGET:
            DebugPrint("FIXME: wrong entry.\n");
            break;
    }
}
开发者ID:ajaykon,项目名称:Stratagus,代码行数:65,代码来源:action_attack.cpp

示例5: CommandMove

/**
**  Move unit to new position
**
**  @param unit   pointer to unit.
**  @param pos    map position to move to.
**  @param flush  if true, flush command queue.
*/
void CommandMove(CUnit &unit, const Vec2i &pos, int flush)
{
    Assert(Map.Info.IsPointOnMap(pos));

    if (IsUnitValidForNetwork(unit) == false) {
        return ;
    }
    //Wyrmgus start
    CMapField &mf = *Map.Field(unit.tilePos);
    CMapField &new_mf = *Map.Field(pos);
    //if the unit is a land unit over a raft, move the raft instead of the unit
    if ((mf.Flags & MapFieldBridge) && !unit.Type->BoolFlag[BRIDGE_INDEX].value && unit.Type->UnitType == UnitTypeLand) { 
        std::vector<CUnit *> table;
        Select(unit.tilePos, unit.tilePos, table);
        for (size_t i = 0; i != table.size(); ++i) {
            if (!table[i]->Removed && table[i]->Type->BoolFlag[BRIDGE_INDEX].value && table[i]->CanMove()) {
                CommandStopUnit(*table[i]); //always stop the raft if a new command is issued
                if ((new_mf.Flags & MapFieldWaterAllowed) || (new_mf.Flags & MapFieldCoastAllowed) || (mf.Flags & MapFieldWaterAllowed)) { // if is standing on water, tell the raft to go to the nearest coast, even if the ultimate goal is on land
                    CommandStopUnit(unit);
                    CommandMove(*table[i], pos, flush);
                    return;
                }
            }
        }
    }
    //Wyrmgus end
    COrderPtr *order;

    if (!unit.CanMove()) {
        ClearNewAction(unit);
        order = &unit.NewOrder;
    } else {
        order = GetNextOrder(unit, flush);
        if (order == NULL) {
            return;
        }
    }
    *order = COrder::NewActionMove(pos);
    ClearSavedAction(unit);
}
开发者ID:meiavy,项目名称:Wyrmgus,代码行数:47,代码来源:command.cpp

示例6:

/* virtual */ void COrder_Move::Execute(CUnit &unit)
{
    Assert(unit.CanMove());

    if (unit.Wait) {
        unit.Wait--;
        return ;
    }
    // FIXME: (mr-russ) Make a reachable goal here with GoalReachable ...

    switch (DoActionMove(unit)) { // reached end-point?
        case PF_UNREACHABLE:
            // Some tries to reach the goal
            this->Range++;
            break;

        case PF_REACHED:
            this->Finished = true;
            break;
        default:
            break;
    }
}
开发者ID:ajaykon,项目名称:Stratagus,代码行数:23,代码来源:action_move.cpp

示例7: AutoRepair

/* virtual */ void COrder_Still::Execute(CUnit &unit)
{
    // If unit is not bunkered and removed, wait
    if (unit.Removed
        && (unit.Container == NULL || unit.Container->Type->BoolFlag[ATTACKFROMTRANSPORTER_INDEX].value == false)) {
        return ;
    }
    this->Finished = false;

    switch (this->State) {
        case SUB_STILL_STANDBY:
            UnitShowAnimation(unit, unit.Type->Animations->Still);
            break;
        case SUB_STILL_ATTACK: // attacking unit in attack range.
            AnimateActionAttack(unit, *this);
            break;
    }
    if (unit.Anim.Unbreakable) { // animation can't be aborted here
        return;
    }
    this->State = SUB_STILL_STANDBY;
    this->Finished = (this->Action == UnitActionStill);
    if (this->Action == UnitActionStandGround || unit.Removed || unit.CanMove() == false) {
        if (unit.AutoCastSpell) {
            this->AutoCastStand(unit);
        }
        if (unit.IsAgressive()) {
            this->AutoAttackStand(unit);
        }
    } else {
        if (AutoCast(unit) || (unit.IsAgressive() && AutoAttack(unit))
            || AutoRepair(unit)
            || MoveRandomly(unit)) {
        }
    }
}
开发者ID:onkrot,项目名称:stratagus,代码行数:36,代码来源:action_still.cpp

示例8: DoActionMove

/**
**  Unit moves! Generic function called from other actions.
**
**  @param unit  Pointer to unit.
**
**  @return      >0 remaining path length, 0 wait for path, -1
**               reached goal, -2 can't reach the goal.
*/
int DoActionMove(CUnit &unit)
{
    Vec2i posd; // movement in tile.
    int d;

    Assert(unit.CanMove());

    if (!unit.Moving && (unit.Type->Animations->Move != unit.Anim.CurrAnim || !unit.Anim.Wait)) {
        Assert(!unit.Anim.Unbreakable);

        // FIXME: So units flying up and down are not affected.
        unit.IX = 0;
        unit.IY = 0;

        UnmarkUnitFieldFlags(unit);
        d = NextPathElement(unit, &posd.x, &posd.y);
        MarkUnitFieldFlags(unit);
        switch (d) {
            case PF_UNREACHABLE: // Can't reach, stop
                if (unit.Player->AiEnabled) {
                    AiCanNotMove(unit);
                }
                unit.Moving = 0;
                return d;
            case PF_REACHED: // Reached goal, stop
                unit.Moving = 0;
                return d;
            case PF_WAIT: // No path, wait
                // Reset frame to still frame while we wait
                // FIXME: Unit doesn't animate.
                unit.Frame = unit.Type->StillFrame;
                UnitUpdateHeading(unit);
                unit.Wait = 10;

                unit.Moving = 0;
                return d;
            default: // On the way moving
                unit.Moving = 1;
                break;
        }

        if (unit.Type->UnitType == UnitTypeNaval) { // Boat (un)docking?
            const CMapField &mf_cur = *Map.Field(unit.Offset);
            const CMapField &mf_next = *Map.Field(unit.tilePos + posd);

            if (mf_cur.WaterOnMap() && mf_next.CoastOnMap()) {
                PlayUnitSound(unit, VoiceDocking);
            } else if (mf_cur.CoastOnMap() && mf_next.WaterOnMap()) {
                PlayUnitSound(unit, VoiceDocking); // undocking
            }
        }
        Vec2i pos = unit.tilePos + posd;
        unit.MoveToXY(pos);

        // Remove unit from the current selection
        if (unit.Selected && !Map.Field(pos)->playerInfo.IsTeamVisible(*ThisPlayer)) {
            if (NumSelected == 1) { //  Remove building cursor
                CancelBuildingMode();
            }
            if (!ReplayRevealMap) {
                UnSelectUnit(unit);
                SelectionChanged();
            }
        }

        unit.IX = -posd.x * PixelTileSize.x;
        unit.IY = -posd.y * PixelTileSize.y;
        unit.Frame = unit.Type->StillFrame;
        UnitHeadingFromDeltaXY(unit, posd);
    } else {
        posd.x = Heading2X[unit.Direction / NextDirection];
        posd.y = Heading2Y[unit.Direction / NextDirection];
        d = unit.pathFinderData->output.Length + 1;
    }

    unit.pathFinderData->output.Cycles++;//reset have to be manualy controled by caller.
    int move = UnitShowAnimationScaled(unit, unit.Type->Animations->Move, Map.Field(unit.Offset)->Cost);

    unit.IX += posd.x * move;
    unit.IY += posd.y * move;

    // Finished move animation, set Moving to 0 so we recalculate the path
    // next frame
    // FIXME: this is broken for subtile movement
    if (!unit.Anim.Unbreakable && !unit.IX && !unit.IY) {
        unit.Moving = 0;
    }
    return d;
}
开发者ID:ajaykon,项目名称:Stratagus,代码行数:97,代码来源:action_move.cpp

示例9: AttackUnitsInReactRange

/* virtual */ void COrder_Follow::Execute(CUnit &unit)
{
    if (unit.Wait) {
        if (!unit.Waiting) {
            unit.Waiting = 1;
            unit.WaitBackup = unit.Anim;
        }
        //Wyrmgus start
//		UnitShowAnimation(unit, unit.Type->Animations->Still);
        UnitShowAnimation(unit, unit.GetAnimations()->Still);
        //Wyrmgus end
        unit.Wait--;
        return;
    }
    if (unit.Waiting) {
        unit.Anim = unit.WaitBackup;
        unit.Waiting = 0;
    }
    CUnit *goal = this->GetGoal();

    // Reached target
    if (this->State == State_TargetReached) {

        if (!goal || !goal->IsVisibleAsGoal(*unit.Player)) {
            DebugPrint("Goal gone\n");
            this->Finished = true;
            return ;
        }

        // Don't follow after immobile units
        if (goal && goal->CanMove() == false) {
            this->Finished = true;
            return;
        }

        //Wyrmgus start
//		if (goal->tilePos == this->goalPos) {
        if (goal->tilePos == this->goalPos && goal->MapLayer == this->MapLayer) {
        //Wyrmgus end
            // Move to the next order
            if (unit.Orders.size() > 1) {
                this->Finished = true;
                return ;
            }

            unit.Wait = 10;
            if (this->Range > 1) {
                this->Range = 1;
                this->State = State_Init;
            }
            return ;
        }
        this->State = State_Init;
    }
    if (this->State == State_Init) { // first entry
        this->State = State_Initialized;
    }
    switch (DoActionMove(unit)) { // reached end-point?
        case PF_UNREACHABLE:
            //Wyrmgus start
            if ((Map.Field(unit.tilePos, unit.MapLayer)->Flags & MapFieldBridge) && !unit.Type->BoolFlag[BRIDGE_INDEX].value && unit.Type->UnitType == UnitTypeLand) {
                std::vector<CUnit *> table;
                Select(unit.tilePos, unit.tilePos, table, unit.MapLayer);
                for (size_t i = 0; i != table.size(); ++i) {
                    if (!table[i]->Removed && table[i]->Type->BoolFlag[BRIDGE_INDEX].value && table[i]->CanMove()) {
                        if (table[i]->CurrentAction() == UnitActionStill) {
                            CommandStopUnit(*table[i]);
                            CommandMove(*table[i], this->HasGoal() ? this->GetGoal()->tilePos : this->goalPos, FlushCommands, this->HasGoal() ? this->GetGoal()->MapLayer : this->MapLayer);
                        }
                        return;
                    }
                }
            }
            //Wyrmgus end
            // Some tries to reach the goal
            this->Range++;
            break;
        case PF_REACHED: {
            if (!goal) { // goal has died
                this->Finished = true;
                return ;
            }
            // Handle Teleporter Units
            // FIXME: BAD HACK
            // goal shouldn't be busy and portal should be alive
            if (goal->Type->BoolFlag[TELEPORTER_INDEX].value && goal->Goal && goal->Goal->IsAlive() && unit.MapDistanceTo(*goal) <= 1) {
                if (!goal->IsIdle()) { // wait
                    unit.Wait = 10;
                    return;
                }
                // Check if we have enough mana
                if (goal->Goal->Type->TeleportCost > goal->Variable[MANA_INDEX].Value) {
                    this->Finished = true;
                    return;
                } else {
                    goal->Variable[MANA_INDEX].Value -= goal->Goal->Type->TeleportCost;
                }
                // Everything is OK, now teleport the unit
                unit.Remove(NULL);
                if (goal->Type->TeleportEffectIn) {
//.........这里部分代码省略.........
开发者ID:KroArtem,项目名称:Wyrmgus,代码行数:101,代码来源:action_follow.cpp

示例10: AttackTarget

/**
**  Handle attacking the target.
**
**  @param unit  Unit, for that the attack is handled.
*/
void COrder_Attack::AttackTarget(CUnit &unit)
{
    Assert(this->HasGoal() || Map.Info.IsPointOnMap(this->goalPos));

    AnimateActionAttack(unit, *this);
    if (unit.Anim.Unbreakable) {
        return;
    }

    if (!this->HasGoal() && (this->Action == UnitActionAttackGround || Map.WallOnMap(this->goalPos))) {
        return;
    }

    // Target is dead ? Change order ?
    if (CheckForDeadGoal(unit)) {
        return;
    }
    CUnit *goal = this->GetGoal();
    bool dead = !goal || goal->IsAlive() == false;

    // No target choose one.
    if (!goal) {
        goal = AttackUnitsInReactRange(unit);

        // No new goal, continue way to destination.
        if (!goal) {
            // Return to old task ?
            if (unit.RestoreOrder()) {
                return;
            }
            this->State = MOVE_TO_TARGET;
            return;
        }
        // Save current command to come back.
        COrder *savedOrder = COrder::NewActionAttack(unit, this->goalPos);

        if (unit.CanStoreOrder(savedOrder) == false) {
            delete savedOrder;
            savedOrder = NULL;
        } else {
            unit.SavedOrder = savedOrder;
        }
        this->SetGoal(goal);
        this->goalPos = goal->tilePos;
        this->MinRange = unit.Type->MinAttackRange;
        this->Range = unit.Stats->Variables[ATTACKRANGE_INDEX].Max;
        this->State |= WEAK_TARGET;

        // Have a weak target, try a better target.
        // FIXME: if out of range also try another target quick
    } else {
        if ((this->State & WEAK_TARGET)) {
            CUnit *newTarget = AttackUnitsInReactRange(unit);
            if (newTarget && ThreatCalculate(unit, *newTarget) < ThreatCalculate(unit, *goal)) {
                if (unit.CanStoreOrder(this)) {
                    unit.SavedOrder = this->Clone();
                }
                goal = newTarget;
                this->SetGoal(newTarget);
                this->goalPos = newTarget->tilePos;
                this->MinRange = unit.Type->MinAttackRange;
                this->State = MOVE_TO_TARGET;
            }
        }
    }

    // Still near to target, if not goto target.
    const int dist = unit.MapDistanceTo(*goal);
    if (dist > unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
        // towers don't chase after goal
        if (unit.CanMove()) {
            if (unit.CanStoreOrder(this)) {
                if (dead) {
                    unit.SavedOrder = COrder::NewActionAttack(unit, this->goalPos);
                } else {
                    unit.SavedOrder = this->Clone();
                }
            }
        }
        unit.Frame = 0;
        this->State &= WEAK_TARGET;
        this->State |= MOVE_TO_TARGET;
    }
    if (dist < unit.Type->MinAttackRange) {
        this->State = MOVE_TO_TARGET;
    }

    // Turn always to target
    if (goal) {
        const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
        UnitHeadingFromDeltaXY(unit, dir);
    }
}
开发者ID:ajaykon,项目名称:Stratagus,代码行数:98,代码来源:action_attack.cpp

示例11: MoveToTarget

/**
**  Controls moving a unit to its target when attacking
**
**  @param unit  Unit that is attacking and moving
*/
void COrder_Attack::MoveToTarget(CUnit &unit)
{
    Assert(!unit.Type->Vanishes && !unit.Destroyed && !unit.Removed);
    Assert(unit.CurrentOrder() == this);
    Assert(unit.CanMove());
    Assert(this->HasGoal() || Map.Info.IsPointOnMap(this->goalPos));

    int err = DoActionMove(unit);

    if (unit.Anim.Unbreakable) {
        return;
    }

    // Look if we have reached the target.
    if (err == 0 && !this->HasGoal()) {
        // Check if we're in range when attacking a location and we are waiting
        if (unit.MapDistanceTo(this->goalPos) <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
            err = PF_REACHED;
        }
    }
    if (err >= 0) {
        if (CheckForTargetInRange(unit)) {
            return;
        }
        return;
    }
    if (err == PF_REACHED) {
        CUnit *goal = this->GetGoal();
        // Have reached target? FIXME: could use the new return code?
        if (goal
            && unit.MapDistanceTo(*goal) <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
            // Reached another unit, now attacking it
            const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
            UnitHeadingFromDeltaXY(unit, dir);
            this->State++;
            return;
        }
        // Attacking wall or ground.
        if (((goal && goal->Type && goal->Type->Wall)
             || (!goal && (Map.WallOnMap(this->goalPos) || this->Action == UnitActionAttackGround)))
            && unit.MapDistanceTo(this->goalPos) <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
            // Reached wall or ground, now attacking it
            UnitHeadingFromDeltaXY(unit, this->goalPos - unit.tilePos);
            this->State &= WEAK_TARGET;
            this->State |= ATTACK_TARGET;
            return;
        }
    }
    // Unreachable.

    if (err == PF_UNREACHABLE) {
        if (!this->HasGoal()) {
            // When attack-moving we have to allow a bigger range
            this->Range++;
            unit.Wait = 5;
            return;
        } else {
            this->ClearGoal();
        }
    }

    // Return to old task?
    if (!unit.RestoreOrder()) {
        this->Finished = true;
    }
}
开发者ID:ajaykon,项目名称:Stratagus,代码行数:71,代码来源:action_attack.cpp

示例12: MoveToDropZone

/* virtual */ void COrder_Unload::Execute(CUnit &unit)
{
    const int maxSearchRange = 20;

    if (!unit.CanMove()) {
        this->State = 2;
    }

    if (unit.Wait) {
        if (!unit.Waiting) {
            unit.Waiting = 1;
            unit.WaitBackup = unit.Anim;
        }
        UnitShowAnimation(unit, unit.Type->Animations->Still);
        unit.Wait--;
        return;
    }
    if (unit.Waiting) {
        unit.Anim = unit.WaitBackup;
        unit.Waiting = 0;
    }
    if (this->State == 1 && this->Range >= 5) {
        // failed to reach the goal
        this->State = 2;
    }

    switch (this->State) {
        case 0: // Choose destination
            if (!this->HasGoal()) {
                Vec2i pos;

                if (!ClosestFreeDropZone(unit, this->goalPos, maxSearchRange, &pos)) {
                    this->Finished = true;
                    return ;
                }
                this->goalPos = pos;
            }

            this->State = 1;
        // follow on next case
        case 1: // Move unit to destination
            // The Goal is the unit that we have to unload.
            if (!this->HasGoal()) {
                const int moveResult = MoveToDropZone(unit);

                // We have to unload everything
                if (moveResult) {
                    if (moveResult == PF_REACHED) {
                        if (++this->State == 1) {
                            this->Finished = true;
                            return ;
                        }
                    } else if (moveResult == PF_UNREACHABLE) {
                        unit.Wait = 30;
                        this->Range++;
                        break;
                    } else {
                        this->State = 2;
                    }
                }
                return ;
            }
        case 2: { // Leave the transporter
            // FIXME: show still animations ?
            if (LeaveTransporter(unit)) {
                this->Finished = true;
                return ;
            }
            return ;
        }
        default:
            return ;
    }
}
开发者ID:onkrot,项目名称:stratagus,代码行数:74,代码来源:action_unload.cpp


注:本文中的CUnit::CanMove方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。