本文整理汇总了C++中CUnit::RestoreOrder方法的典型用法代码示例。如果您正苦于以下问题:C++ CUnit::RestoreOrder方法的具体用法?C++ CUnit::RestoreOrder怎么用?C++ CUnit::RestoreOrder使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CUnit
的用法示例。
在下文中一共展示了CUnit::RestoreOrder方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: RepairUnit
/**
** Repair a unit.
**
** @param unit unit repairing
** @param goal unit being repaired
*/
static void RepairUnit(CUnit &unit, CUnit &goal)
{
CPlayer *player;
int animlength;
int hp;
char buf[100];
player = unit.Player;
if (goal.CurrentAction() != UnitActionBuilt) {
//
// Calculate the repair costs.
//
Assert(goal.Stats->Variables[HP_INDEX].Max);
//
// Check if enough resources are available
//
for (int i = 1; i < MaxCosts; ++i) {
if (player->Resources[i] < goal.Type->RepairCosts[i]) {
snprintf(buf, 100, _("We need more %s for repair!"),
DefaultResourceNames[i].c_str());
player->Notify(NotifyYellow, unit.tilePos.x, unit.tilePos.y, buf);
if (player->AiEnabled) {
// FIXME: call back to AI?
unit.CurrentOrder()->ClearGoal();
if (!unit.RestoreOrder()) {
unit.ClearAction();
unit.State = 0;
}
}
// FIXME: We shouldn't animate if no resources are available.
return;
}
}
//
// Subtract the resources
//
player->SubCosts(goal.Type->RepairCosts);
goal.Variable[HP_INDEX].Value += goal.Type->RepairHP;
if (goal.Variable[HP_INDEX].Value > goal.Variable[HP_INDEX].Max) {
goal.Variable[HP_INDEX].Value = goal.Variable[HP_INDEX].Max;
}
} else {
int costs = goal.Stats->Costs[TimeCost] * 600;
// hp is the current damage taken by the unit.
hp = (goal.Data.Built.Progress * goal.Variable[HP_INDEX].Max) /
costs - goal.Variable[HP_INDEX].Value;
//
// Calculate the length of the attack (repair) anim.
//
animlength = unit.Data.Repair.Cycles;
unit.Data.Repair.Cycles = 0;
// FIXME: implement this below:
//unit.Data.Built.Worker->Type->BuilderSpeedFactor;
goal.Data.Built.Progress += 100 * animlength * SpeedBuild;
// Keep the same level of damage while increasing HP.
goal.Variable[HP_INDEX].Value =
(goal.Data.Built.Progress * goal.Stats->Variables[HP_INDEX].Max) /
costs - hp;
if (goal.Variable[HP_INDEX].Value > goal.Variable[HP_INDEX].Max) {
goal.Variable[HP_INDEX].Value = goal.Variable[HP_INDEX].Max;
}
}
}
示例2: HandleActionRepair
/**
** Unit repairs
**
** @param unit Unit, for that the attack is handled.
*/
void HandleActionRepair(CUnit &unit)
{
CUnit *goal;
int err;
switch (unit.SubAction) {
case 0:
NewResetPath(unit);
unit.SubAction = 1;
// FALL THROUGH
//
// Move near to target.
//
case 1:
// FIXME: RESET FIRST!! Why? We move first and than check if
// something is in sight.
err = DoActionMove(unit);
if (!unit.Anim.Unbreakable) {
//
// No goal: if meeting damaged building repair it.
//
goal = unit.CurrentOrder()->GetGoal();
//
// Target is dead, choose new one.
//
// Check if goal is correct unit.
if (goal) {
if (!goal->IsVisibleAsGoal(unit.Player)) {
DebugPrint("repair target gone.\n");
unit.CurrentOrder()->goalPos = goal->tilePos;
// FIXME: should I clear this here?
unit.CurrentOrder()->ClearGoal();
goal = NULL;
NewResetPath(unit);
}
} else if (unit.Player->AiEnabled) {
// Ai players workers should stop if target is killed
err = -1;
}
//
// Have reached target? FIXME: could use return value
//
if (goal && unit.MapDistanceTo(*goal) <= unit.Type->RepairRange &&
goal->Variable[HP_INDEX].Value < goal->Variable[HP_INDEX].Max) {
unit.State = 0;
unit.SubAction = 2;
unit.Data.Repair.Cycles = 0;
const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
UnitHeadingFromDeltaXY(unit, dir);
} else if (err < 0) {
unit.CurrentOrder()->ClearGoal();
if (!unit.RestoreOrder()) {
unit.ClearAction();
unit.State = 0;
}
return;
}
// FIXME: Should be it already?
Assert(unit.CurrentAction() == UnitActionRepair);
}
break;
//
// Repair the target.
//
case 2:
AnimateActionRepair(unit);
unit.Data.Repair.Cycles++;
if (!unit.Anim.Unbreakable) {
goal = unit.CurrentOrder()->GetGoal();
//
// Target is dead, choose new one.
//
// Check if goal is correct unit.
// FIXME: should I do a function for this?
if (goal) {
if (!goal->IsVisibleAsGoal(unit.Player)) {
DebugPrint("repair goal is gone\n");
unit.CurrentOrder()->goalPos = goal->tilePos;
// FIXME: should I clear this here?
unit.CurrentOrder()->ClearGoal();
goal = NULL;
NewResetPath(unit);
} else {
int dist = unit.MapDistanceTo(*goal);
if (dist <= unit.Type->RepairRange) {
RepairUnit(unit, *goal);
goal = unit.CurrentOrder()->GetGoal();
} else if (dist > unit.Type->RepairRange) {
// If goal has move, chase after it
unit.State = 0;
//.........这里部分代码省略.........
示例3: 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);
}
}
示例4: 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;
}
}
示例5: if
/* virtual */ void COrder_SpellCast::Execute(CUnit &unit)
{
COrder_SpellCast &order = *this;
if (unit.Wait) {
unit.Wait--;
return ;
}
const SpellType &spell = order.GetSpell();
switch (this->State) {
case 0:
// Check if we can cast the spell.
if (!CanCastSpell(unit, spell, order.GetGoal(), order.goalPos)) {
// Notify player about this problem
if (unit.Variable[MANA_INDEX].Value < spell.ManaCost) {
unit.Player->Notify(NotifyYellow, unit.tilePos,
_("%s: not enough mana for spell: %s"),
unit.Type->Name.c_str(), spell.Name.c_str());
} else if (unit.SpellCoolDownTimers[spell.Slot]) {
unit.Player->Notify(NotifyYellow, unit.tilePos,
_("%s: spell is not ready yet: %s"),
unit.Type->Name.c_str(), spell.Name.c_str());
} else if (unit.Player->CheckCosts(spell.Costs, false)) {
unit.Player->Notify(NotifyYellow, unit.tilePos,
_("%s: not enough resources to cast spell: %s"),
unit.Type->Name.c_str(), spell.Name.c_str());
} else {
unit.Player->Notify(NotifyYellow, unit.tilePos,
_("%s: can't cast spell: %s"),
unit.Type->Name.c_str(), spell.Name.c_str());
}
if (unit.Player->AiEnabled) {
DebugPrint("FIXME: do we need an AI callback?\n");
}
if (!unit.RestoreOrder()) {
this->Finished = true;
}
return ;
}
if (CheckForDeadGoal(unit)) {
return;
}
// FIXME FIXME FIXME: Check if already in range and skip straight to 2(casting)
unit.ReCast = 0; // repeat spell on next pass? (defaults to `no')
this->State = 1;
// FALL THROUGH
case 1: // Move to the target.
if (spell.Range && spell.Range != INFINITE_RANGE) {
if (SpellMoveToTarget(unit) == true) {
if (!unit.RestoreOrder()) {
this->Finished = true;
}
return ;
}
return ;
} else {
this->State = 2;
}
// FALL THROUGH
case 2: // Cast spell on the target.
if (!spell.IsCasterOnly() || spell.ForceUseAnimation) {
AnimateActionSpellCast(unit, *this);
if (unit.Anim.Unbreakable) {
return ;
}
} else {
// FIXME: what todo, if unit/goal is removed?
CUnit *goal = order.GetGoal();
if (goal && goal != &unit && !goal->IsVisibleAsGoal(*unit.Player)) {
unit.ReCast = 0;
} else {
unit.ReCast = SpellCast(unit, spell, goal, order.goalPos);
}
}
// Target is dead ? Change order ?
if (CheckForDeadGoal(unit)) {
return;
}
// Check, if goal has moved (for ReCast)
if (unit.ReCast && order.GetGoal() && unit.MapDistanceTo(*order.GetGoal()) > this->Range) {
this->State = 0;
return;
}
if (!unit.ReCast && unit.CurrentAction() != UnitActionDie) {
if (!unit.RestoreOrder()) {
this->Finished = true;
}
return ;
}
break;
default:
this->State = 0; // Reset path, than move to target
break;
}
}