本文整理汇总了C++中CUnit::RefsDecrease方法的典型用法代码示例。如果您正苦于以下问题:C++ CUnit::RefsDecrease方法的具体用法?C++ CUnit::RefsDecrease怎么用?C++ CUnit::RefsDecrease使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CUnit
的用法示例。
在下文中一共展示了CUnit::RefsDecrease方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: LeaveTransporter
/**
** Make one or more unit leave the transporter.
**
** @param unit Pointer to unit.
*/
static void LeaveTransporter(CUnit *unit)
{
int i;
int stillonboard;
CUnit *goal;
stillonboard = 0;
goal = unit->Orders[0]->Goal;
//
// Goal is the specific unit unit that you want to unload.
// This can be NULL, in case you want to unload everything.
//
if (goal) {
unit->Orders[0]->Goal = NoUnitP;
if (goal->Destroyed) {
DebugPrint("destroyed unit unloading?\n");
goal->RefsDecrease();
return;
}
goal->RefsDecrease();
goal->X = unit->X;
goal->Y = unit->Y;
// Try to unload the unit. If it doesn't work there is no problem.
if (UnloadUnit(goal)) {
unit->BoardCount--;
}
} else {
// Unload all units.
goal = unit->UnitInside;
for (i = unit->InsideCount; i; --i, goal = goal->NextContained) {
if (goal->Boarded) {
goal->X = unit->X;
goal->Y = unit->Y;
if (!UnloadUnit(goal)) {
++stillonboard;
} else {
unit->BoardCount--;
}
}
}
}
if (IsOnlySelected(unit)) {
SelectedUnitChanged();
}
// We still have some units to unload, find a piece of free coast.
if (stillonboard) {
// We tell it to unload at it's current position. This can't be done,
// so it will search for a piece of free coast nearby.
unit->Orders[0]->Action = UnitActionUnload;
unit->Orders[0]->Goal = NoUnitP;
unit->Orders[0]->X = unit->X;
unit->Orders[0]->Y = unit->Y;
unit->SubAction = 0;
} else {
unit->ClearAction();
}
}
示例2: PlayersEachCycle
/**
** Handle AI of all players each game cycle.
*/
void PlayersEachCycle()
{
for (int player = 0; player < NumPlayers; ++player) {
CPlayer *p = &Players[player];
if (p->AutoAttackTargets.size() > 0) {
CUnitCache &autoatacktargets = p->AutoAttackTargets;
/* both loops can not be connected !!!! */
for (unsigned int i = 0; i < autoatacktargets.size();) {
CUnit *aatarget = autoatacktargets[i];
if (!aatarget->IsAliveOnMap() ||
Map.Field(aatarget->Offset)->Guard[player] == 0) {
autoatacktargets.Units.erase(autoatacktargets.Units.begin() + i);
aatarget->RefsDecrease();
continue;
}
++i;
}
if (autoatacktargets.size() > 0) {
for (int j = 0; j < p->TotalNumUnits; ++j) {
CUnit &guard = *p->Units[j];
bool stand_ground = guard.CurrentAction() == UnitActionStandGround;
if (guard.Type->CanAttack &&
(stand_ground || guard.IsIdle()) &&
!guard.IsUnusable()) {
AutoAttack(guard, autoatacktargets, stand_ground);
}
}
}
}
if (p->AiEnabled) {
AiEachCycle(p);
}
}
}
示例3: EnterTransporter
/**
** Enter the transporter.
**
** @param unit Pointer to unit.
*/
static void EnterTransporter(CUnit *unit)
{
CUnit *transporter;
unit->ClearAction();
transporter = unit->Orders[0]->Goal;
if (!transporter->IsVisibleAsGoal(unit->Player)) {
DebugPrint("Transporter gone\n");
transporter->RefsDecrease();
unit->Orders[0]->Goal = NoUnitP;
return;
}
transporter->RefsDecrease();
unit->Orders[0]->Goal = NoUnitP;
//
// Place the unit inside the transporter.
//
if (transporter->BoardCount < transporter->Type->MaxOnBoard) {
unit->Remove(transporter);
transporter->BoardCount++;
unit->Boarded = 1;
if (!unit->Player->AiEnabled) {
// Don't make anything funny after going out of the transporter.
// FIXME: This is probably wrong, but it works for me (n0b0dy)
unit->OrderCount = 1;
unit->ClearAction();
}
if (IsOnlySelected(transporter)) {
SelectedUnitChanged();
}
return;
}
DebugPrint("No free slot in transporter\n");
}
示例4: FreeMissile
/**
** Free a missile.
**
** @param missiles Missile pointer.
** @param i Index in missiles of missile to free
*/
static void FreeMissile(std::vector<Missile *> &missiles, size_t i)
{
Missile *missile;
CUnit *unit;
missile = missiles[i];
//
// Release all unit references.
//
if ((unit = missile->SourceUnit)) {
unit->RefsDecrease();
}
if ((unit = missile->TargetUnit)) {
unit->RefsDecrease();
}
for (std::vector<Missile*>::iterator j = missiles.begin(); j != missiles.end(); ++j) {
if (*j == missile) {
missiles.erase(j);
break;
}
}
delete missile;
}
示例5: WaitForTransporter
/**
** Wait for transporter.
**
** @param unit Pointer to unit.
**
** @return True if ship arrived/present, False otherwise.
*/
static int WaitForTransporter(CUnit *unit)
{
CUnit *trans;
if (unit->Wait) {
unit->Wait--;
return 0;
}
trans = unit->Orders[0]->Goal;
if (!trans || !CanTransport(trans, unit)) {
// FIXME: destination destroyed??
unit->Wait = 6;
return 0;
}
if (!trans->IsVisibleAsGoal(unit->Player)) {
DebugPrint("Transporter Gone\n");
trans->RefsDecrease();
unit->Orders[0]->Goal = NoUnitP;
unit->Wait = 6;
return 0;
}
if (MapDistanceBetweenUnits(unit, trans) == 1) {
// enter transporter
return 1;
}
//
// FIXME: any enemies in range attack them, while waiting.
//
// n0b0dy: This means we have to search with a smaller range.
// It happens only when you reach the shore,and the transporter
// is not there. The unit searches with a big range, so it thinks
// it's there. This is why we reset the search. The transporter
// should be a lot closer now, so it's not as bad as it seems.
unit->SubAction = 0;
unit->Orders[0]->Range = 1;
// Uhh wait a bit.
unit->Wait = 10;
return 0;
}
示例6: 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->Orders[0]->Goal;
//
// 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->Orders[0]->X = goal->X;
unit->Orders[0]->Y = goal->Y;
goal->RefsDecrease();
// FIXME: should I clear this here?
unit->Orders[0]->Goal = 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 && MapDistanceBetweenUnits(unit, 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;
UnitHeadingFromDeltaXY(unit,
goal->X + (goal->Type->TileWidth - 1) / 2 - unit->X,
goal->Y + (goal->Type->TileHeight - 1) / 2 - unit->Y);
} else if (err < 0) {
if (goal) { // release reference
goal->RefsDecrease();
unit->Orders[0]->Goal = NoUnitP;
}
unit->Orders[0]->Action = UnitActionStill;
unit->State = unit->SubAction = 0;
if (unit->Selected) { // update display for new action
SelectedUnitChanged();
}
return;
}
// FIXME: Should be it already?
Assert(unit->Orders[0]->Action == UnitActionRepair);
}
break;
//
// Repair the target.
//
case 2:
AnimateActionRepair(unit);
unit->Data.Repair.Cycles++;
if (!unit->Anim.Unbreakable) {
goal = unit->Orders[0]->Goal;
//
// 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->Orders[0]->X = goal->X;
unit->Orders[0]->Y = goal->Y;
goal->RefsDecrease();
// FIXME: should I clear this here?
unit->Orders[0]->Goal = goal = NULL;
NewResetPath(unit);
}
//.........这里部分代码省略.........
示例7: HandleActionBoard
/**
** The unit boards a transporter.
**
** @todo FIXME: While waiting for the transporter the units must defend themselves.
**
** @param unit Pointer to unit.
*/
void HandleActionBoard(CUnit *unit)
{
int i;
CUnit *goal;
switch (unit->SubAction) {
//
// Wait for transporter
//
case 201:
if (WaitForTransporter(unit)) {
unit->SubAction = 202;
} else {
UnitShowAnimation(unit, unit->Type->Animations->Still);
}
break;
//
// Enter transporter
//
case 202:
EnterTransporter(unit);
break;
//
// Move to transporter
//
case 0:
if (unit->Wait) {
unit->Wait--;
return;
}
NewResetPath(unit);
unit->SubAction = 1;
// FALL THROUGH
default:
if (unit->SubAction <= 200) {
// FIXME: if near transporter wait for enter
if ((i = MoveToTransporter(unit))) {
if (i == PF_UNREACHABLE) {
if (++unit->SubAction == 200) {
unit->ClearAction();
if ((goal = unit->Orders[0]->Goal)) {
goal->RefsDecrease();
unit->Orders[0]->Goal = NoUnitP;
}
} else {
//
// Try with a bigger range.
//
if (unit->Orders[0]->Range <= Map.Info.MapWidth ||
unit->Orders[0]->Range <= Map.Info.MapHeight) {
unit->Orders[0]->Range++;
unit->SubAction--;
}
}
} else if (i == PF_REACHED) {
unit->SubAction = 201;
}
}
}
break;
}
}
示例8: AutoAttack
/**
** Auto attack nearby units if possible
*/
static void AutoAttack(CUnit *unit, bool stand_ground)
{
CUnit *temp;
CUnit *goal;
if (unit->Wait) {
unit->Wait--;
return;
}
// Cowards don't attack unless ordered.
if (unit->Type->CanAttack && !unit->Type->Coward) {
// Normal units react in reaction range.
if (CanMove(unit) && !unit->Removed && !stand_ground) {
if ((goal = AttackUnitsInReactRange(unit))) {
// Weak goal, can choose other unit, come back after attack
CommandAttack(unit, goal->X, goal->Y, NULL, FlushCommands);
Assert(unit->SavedOrder.Action == UnitActionStill);
Assert(!unit->SavedOrder.Goal);
unit->SavedOrder.Action = UnitActionAttack;
unit->SavedOrder.Range = 0;
unit->SavedOrder.X = unit->X;
unit->SavedOrder.Y = unit->Y;
unit->SavedOrder.Goal = NoUnitP;
} else {
unit->Wait = 15;
}
// Removed units can only attack in AttackRange, from bunker
} else if ((goal = AttackUnitsInRange(unit))) {
temp = unit->Orders[0]->Goal;
if (temp && temp->Orders[0]->Action == UnitActionDie) {
temp->RefsDecrease();
unit->Orders[0]->Goal = temp = NoUnitP;
}
if (!unit->SubAction || temp != goal) {
// New target.
if (temp) {
temp->RefsDecrease();
}
unit->Orders[0]->Goal = goal;
goal->RefsIncrease();
unit->State = 0;
unit->SubAction = 1; // Mark attacking.
UnitHeadingFromDeltaXY(unit,
goal->X + (goal->Type->TileWidth - 1) / 2 - unit->X,
goal->Y + (goal->Type->TileHeight - 1) / 2 - unit->Y);
}
return;
}
} else {
unit->Wait = 15;
}
if (unit->SubAction) { // was attacking.
if ((temp = unit->Orders[0]->Goal)) {
temp->RefsDecrease();
unit->Orders[0]->Goal = NoUnitP;
}
unit->SubAction = unit->State = 0; // No attacking, restart
}
Assert(!unit->Orders[0]->Goal);
}
示例9: MissileHit
/**
** Work for missile hit.
**
** @param missile Missile reaching end-point.
*/
void MissileHit(Missile *missile)
{
CUnit *goal;
int x;
int y;
CUnit *table[UnitMax];
int n;
int i;
int splash;
if (missile->Type->ImpactSound.Sound) {
PlayMissileSound(missile, missile->Type->ImpactSound.Sound);
}
x = missile->X + missile->Type->Width / 2;
y = missile->Y + missile->Type->Height / 2;
//
// The impact generates a new missile.
//
if (missile->Type->ImpactMissile) {
MakeMissile(missile->Type->ImpactMissile, x, y, x, y);
}
if (missile->Type->ImpactParticle) {
missile->Type->ImpactParticle->pushPreamble();
missile->Type->ImpactParticle->pushInteger(x);
missile->Type->ImpactParticle->pushInteger(y);
missile->Type->ImpactParticle->run();
}
if (!missile->SourceUnit) { // no owner - green-cross ...
return;
}
x /= TileSizeX;
y /= TileSizeY;
if (x < 0 || y < 0 || x >= Map.Info.MapWidth || y >= Map.Info.MapHeight) {
// FIXME: this should handled by caller?
DebugPrint("Missile gone outside of map!\n");
return; // outside the map.
}
//
// Choose correct goal.
//
if (!missile->Type->Range) {
if (missile->TargetUnit) {
//
// Missiles without range only hits the goal always.
//
goal = missile->TargetUnit;
if (goal->Destroyed) { // Destroyed
goal->RefsDecrease();
missile->TargetUnit = NoUnitP;
return;
}
MissileHitsGoal(missile, goal, 1);
return;
}
return;
}
//
// Hits all units in range.
//
i = missile->Type->Range;
n = UnitCache.Select(x - i + 1, y - i + 1, x + i, y + i, table, UnitMax);
Assert(missile->SourceUnit != NULL);
for (i = 0; i < n; ++i) {
goal = table[i];
//
// Can the unit attack the this unit-type?
// NOTE: perhaps this should be come a property of the missile.
//
if (CanTarget(missile->SourceUnit->Type, goal->Type)) {
splash = MapDistanceToUnit(x, y, goal);
if (splash) {
splash *= missile->Type->SplashFactor;
} else {
splash = 1;
}
MissileHitsGoal(missile, goal, splash);
}
}
}