/**
**  The transporter unloads a unit.
**
**  @param unit  Pointer to unit.
*/
void HandleActionUnload(CUnit *unit)
{
	int i;
	int x;
	int y;

	if (!CanMove(unit)) {
		unit->SubAction = 2;
	}
	switch (unit->SubAction) {
		//
		// Move the transporter
		//
		case 0:
			if (!unit->Orders[0]->Goal) {
				if (!ClosestFreeDropZone(unit, unit->Orders[0]->X, unit->Orders[0]->Y,
						&x, &y)) {
					// Sorry... I give up.
					unit->ClearAction();
					return;
				}
				unit->Orders[0]->X = x;
				unit->Orders[0]->Y = y;
			}

			NewResetPath(unit);
			unit->SubAction = 1;
		case 1:
			// The Goal is the unit that we have to unload.
			if (!unit->Orders[0]->Goal) {
				// We have to unload everything
				if ((i = MoveToDropZone(unit))) {
					if (i == PF_REACHED) {
						if (++unit->SubAction == 1) {
							unit->ClearAction();
						}
					} else {
						unit->SubAction = 2;
					}
				}
				break;
			}
		//
		// Leave the transporter
		//
		case 2:
			// FIXME: show still animations ?
			LeaveTransporter(unit);
			if (CanMove(unit) && unit->Orders[0]->Action != UnitActionStill) {
				HandleActionUnload(unit);
			}
			break;
	}
}
Example #2
0
/* 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 ;
	}
}