本文整理汇总了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;
}
}
示例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);
}
示例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
}
}
}
示例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;
}
}
示例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);
}
示例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;
}
}
示例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)) {
}
}
}
示例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;
}
示例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) {
//.........这里部分代码省略.........
示例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);
}
}
示例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;
}
}
示例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 ;
}
}