本文整理汇总了C++中CUnit::Remove方法的典型用法代码示例。如果您正苦于以下问题:C++ CUnit::Remove方法的具体用法?C++ CUnit::Remove怎么用?C++ CUnit::Remove使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CUnit
的用法示例。
在下文中一共展示了CUnit::Remove方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: EnterTransporter
/**
** Enter the transporter.
**
** @param unit Pointer to unit.
*/
static void EnterTransporter(CUnit &unit, COrder_Board &order)
{
CUnit *transporter = order.GetGoal();
Assert(transporter != NULL);
if (!transporter->IsVisibleAsGoal(*unit.Player)) {
DebugPrint("Transporter gone\n");
return;
}
if (transporter->BoardCount < transporter->Type->MaxOnBoard) {
// Place the unit inside the transporter.
unit.Remove(transporter);
transporter->BoardCount++;
unit.Boarded = 1;
if (!unit.Player->AiEnabled) {
// Don't make anything funny after going out of the transporter.
CommandStopUnit(unit);
}
if (IsOnlySelected(*transporter)) {
SelectedUnitChanged();
}
return;
}
DebugPrint("No free slot in transporter\n");
}
示例2: CclRemoveUnit
/**
** Remove unit from the map.
**
** @param l Lua state.
**
** @return Returns 1.
*/
static int CclRemoveUnit(lua_State *l)
{
LuaCheckArgs(l, 1);
lua_pushvalue(l, 1);
CUnit *unit = CclGetUnit(l);
lua_pop(l, 1);
unit->Remove(NULL);
lua_pushvalue(l, 1);
return 1;
}
示例3:
/* virtual */ void COrder_Die::Execute(CUnit &unit)
{
// Show death animation
if (AnimateActionDie(unit) == false) {
// some units has no death animation
unit.Anim.Unbreakable = 0;
}
if (unit.Anim.Unbreakable) {
return ;
}
const CUnitType &type = *unit.Type;
// Die sequence terminated, generate corpse.
if (type.CorpseType == NULL) {
unit.Remove(NULL);
unit.Release();
return ;
}
const CUnitType &corpseType = *type.CorpseType;
Assert(type.TileWidth >= corpseType.TileWidth && type.TileHeight >= corpseType.TileHeight);
// Update sight for new corpse
// We have to unmark BEFORE changing the type.
// Always do that, since types can have different vision properties.
unit.Remove(NULL);
unit.Type = &corpseType;
unit.Stats = &corpseType.Stats[unit.Player->Index];
UpdateUnitSightRange(unit);
//Wyrmgus start
// unit.Place(unit.tilePos);
unit.Place(unit.tilePos, unit.MapLayer);
//Wyrmgus end
unit.Frame = 0;
UnitUpdateHeading(unit);
AnimateActionDie(unit); // with new corpse.
}
示例4: ClosestFreeDropZone
/**
** Find the closest available drop zone for a transporter.
** Fail if transporter don't transport any unit..
**
** @param transporter the transporter
** @param startPos start location for the search
** @param maxRange The maximum distance from initial position to search...
** @param resPos drop zone position
**
** @return 1 if a location was found, 0 otherwise
*/
static int ClosestFreeDropZone(CUnit &transporter, const Vec2i &startPos, int maxRange, Vec2i *resPos)
{
// Check there are units onboard
if (!transporter.UnitInside) {
return 0;
}
const bool isTransporterRemoved = transporter.Removed;
const bool selected = transporter.Selected;
if (!isTransporterRemoved) {
// Remove transporter to avoid "collision" with itself.
transporter.Remove(NULL);
}
const bool res = ClosestFreeDropZone_internal(transporter, startPos, maxRange, resPos);
if (!isTransporterRemoved) {
transporter.Place(transporter.tilePos);
if (selected) {
SelectUnit(transporter);
SelectionChanged();
}
}
return res;
}
示例5: StartBuilding
bool COrder_Build::StartBuilding(CUnit &unit, CUnit &ontop)
{
const CUnitType &type = this->GetUnitType();
unit.Player->SubUnitType(type);
CUnit *build = MakeUnit(const_cast<CUnitType &>(type), unit.Player);
// If unable to make unit, stop, and report message
if (build == NULL) {
// FIXME: Should we retry this?
unit.Player->Notify(NotifyYellow, unit.tilePos,
_("Unable to create building %s"), type.Name.c_str());
if (unit.Player->AiEnabled) {
AiCanNotBuild(unit, type);
}
return false;
}
build->Constructed = 1;
build->CurrentSightRange = 0;
// Building on top of something, may remove what is beneath it
if (&ontop != &unit) {
CBuildRestrictionOnTop *b;
b = static_cast<CBuildRestrictionOnTop *>(OnTopDetails(*build, ontop.Type));
Assert(b);
if (b->ReplaceOnBuild) {
build->ResourcesHeld = ontop.ResourcesHeld; // We capture the value of what is beneath.
build->Variable[GIVERESOURCE_INDEX].Value = ontop.Variable[GIVERESOURCE_INDEX].Value;
build->Variable[GIVERESOURCE_INDEX].Max = ontop.Variable[GIVERESOURCE_INDEX].Max;
build->Variable[GIVERESOURCE_INDEX].Enable = ontop.Variable[GIVERESOURCE_INDEX].Enable;
ontop.Remove(NULL); // Destroy building beneath
UnitLost(ontop);
UnitClearOrders(ontop);
ontop.Release();
}
}
// Must set action before placing, otherwise it will incorrectly mark radar
delete build->CurrentOrder();
build->Orders[0] = COrder::NewActionBuilt(unit, *build);
UpdateUnitSightRange(*build);
// Must place after previous for map flags
build->Place(this->goalPos);
// HACK: the building is not ready yet
build->Player->UnitTypesCount[type.Slot]--;
if (build->Active) {
build->Player->UnitTypesAiActiveCount[type.Slot]--;
}
// We need somebody to work on it.
if (!type.BoolFlag[BUILDEROUTSIDE_INDEX].value) {
UnitShowAnimation(unit, unit.Type->Animations->Still);
unit.Remove(build);
this->State = State_BuildFromInside;
if (unit.Selected) {
SelectedUnitChanged();
}
} else {
this->State = State_BuildFromOutside;
this->BuildingUnit = build;
unit.Direction = DirectionToHeading(build->tilePos - unit.tilePos);
UnitUpdateHeading(unit);
}
return true;
}
示例6: offset
//Wyrmgus start
///* virtual */ int Spell_Summon::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &goalPos)
/* virtual */ int Spell_Summon::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &goalPos, int z)
//Wyrmgus end
{
Vec2i pos = goalPos;
bool cansummon;
CUnitType &unittype = *this->UnitType;
int ttl = this->TTL;
if (this->RequireCorpse) {
const Vec2i offset(1, 1);
const Vec2i minPos = pos - offset;
const Vec2i maxPos = pos + offset;
//Wyrmgus start
// CUnit *unit = FindUnit_If(minPos, maxPos, IsDyingAndNotABuilding());
CUnit *unit = FindUnit_If(minPos, maxPos, z, IsDyingAndNotABuilding());
//Wyrmgus end
cansummon = false;
if (unit != NULL) { // Found a corpse. eliminate it and proceed to summoning.
pos = unit->tilePos;
//Wyrmgus start
z = unit->MapLayer;
//Wyrmgus end
unit->Remove(NULL);
unit->Release();
cansummon = true;
}
} else {
cansummon = true;
}
if (cansummon) {
//Wyrmgus start
// DebugPrint("Summoning a %s\n" _C_ unittype.Name.c_str());
DebugPrint("Summoning a %s\n" _C_ unittype.GetDefaultName(*caster.Player).c_str());
//Wyrmgus end
//
// Create units.
// FIXME: do summoned units count on food?
//
target = MakeUnit(unittype, caster.Player);
if (target != NULL) {
target->tilePos = pos;
//Wyrmgus start
target->MapLayer = z;
//Wyrmgus end
DropOutOnSide(*target, LookingW, NULL);
// To avoid defending summoned unit for AI
target->Summoned = 1;
//
// set life span. ttl=0 results in a permanent unit.
//
if (ttl) {
target->TTL = GameCycle + ttl;
}
// Insert summoned unit to AI force so it will help them in battle
if (this->JoinToAiForce && caster.Player->AiEnabled) {
int force = caster.Player->Ai->Force.GetForce(caster);
if (force != -1) {
caster.Player->Ai->Force[force].Insert(*target);
target->GroupId = caster.GroupId;
CommandDefend(*target, caster, FlushCommands);
}
}
caster.Variable[MANA_INDEX].Value -= spell.ManaCost;
} else {
DebugPrint("Unable to allocate Unit");
}
return 1;
}
return 0;
}
示例7: TransformUnitIntoType
//Wyrmgus start
//static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
//Wyrmgus end
{
const CUnitType &oldtype = *unit.Type;
if (&oldtype == &newtype) { // nothing to do
return 1;
}
const Vec2i pos = unit.tilePos + oldtype.GetHalfTileSize() - newtype.GetHalfTileSize();
CUnit *container = unit.Container;
//Wyrmgus start
/*
if (container) {
MapUnmarkUnitSight(unit);
} else {
SaveSelection();
unit.Remove(NULL);
if (!UnitTypeCanBeAt(newtype, pos)) {
unit.Place(unit.tilePos);
RestoreSelection();
// FIXME unit is not modified, try later ?
return 0;
}
}
*/
if (!SaveGameLoading) {
if (container) {
MapUnmarkUnitSight(unit);
} else {
SaveSelection();
unit.Remove(NULL);
if (!UnitTypeCanBeAt(newtype, pos)) {
unit.Place(unit.tilePos);
RestoreSelection();
// FIXME unit is not modified, try later ?
return 0;
}
}
}
//Wyrmgus end
CPlayer &player = *unit.Player;
player.UnitTypesCount[oldtype.Slot]--;
player.UnitTypesCount[newtype.Slot]++;
if (unit.Active) {
player.UnitTypesAiActiveCount[oldtype.Slot]--;
player.UnitTypesAiActiveCount[newtype.Slot]++;
}
//Wyrmgus start
if (unit.Character == NULL) {
player.UnitTypesNonHeroCount[oldtype.Slot]--;
player.UnitTypesNonHeroCount[newtype.Slot]++;
}
//Wyrmgus end
player.Demand += newtype.Stats[player.Index].Variables[DEMAND_INDEX].Value - oldtype.Stats[player.Index].Variables[DEMAND_INDEX].Value;
player.Supply += newtype.Stats[player.Index].Variables[SUPPLY_INDEX].Value - oldtype.Stats[player.Index].Variables[SUPPLY_INDEX].Value;
// Change resource limit
for (int i = 0; i < MaxCosts; ++i) {
if (player.MaxResources[i] != -1) {
player.MaxResources[i] += newtype.Stats[player.Index].Storing[i] - oldtype.Stats[player.Index].Storing[i];
player.SetResource(i, player.StoredResources[i], STORE_BUILDING);
}
}
// adjust Variables with percent.
const CUnitStats &newstats = newtype.Stats[player.Index];
//Wyrmgus start
const CUnitStats &oldstats = oldtype.Stats[player.Index];
//Wyrmgus end
for (unsigned int i = 0; i < UnitTypeVar.GetNumberVariable(); ++i) {
//Wyrmgus start
/*
if (unit.Variable[i].Max && unit.Variable[i].Value) {
unit.Variable[i].Value = newstats.Variables[i].Max *
unit.Variable[i].Value / unit.Variable[i].Max;
} else {
unit.Variable[i].Value = newstats.Variables[i].Value;
}
if (i == KILL_INDEX || i == XP_INDEX) {
unit.Variable[i].Value = unit.Variable[i].Max;
} else {
unit.Variable[i].Max = newstats.Variables[i].Max;
unit.Variable[i].Increase = newstats.Variables[i].Increase;
unit.Variable[i].Enable = newstats.Variables[i].Enable;
}
*/
if (i == LEVEL_INDEX) { //if the unit's level changed in accordance to the difference between the levels of the two unit types, then its level change would be duplicated when leveling up, so let's skip the level variable here
continue;
}
if (unit.Variable[i].Max && unit.Variable[i].Value) {
unit.Variable[i].Value += newstats.Variables[i].Max - oldstats.Variables[i].Max;
} else {
unit.Variable[i].Value += newstats.Variables[i].Value - oldstats.Variables[i].Value;
}
if (i == KILL_INDEX || i == XP_INDEX) {
//.........这里部分代码省略.........
示例8: 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) {
//.........这里部分代码省略.........
示例9: StartGathering
/**
** Start harvesting the resource.
**
** @param unit Pointer to unit.
**
** @return TRUE if ready, otherwise FALSE.
*/
int COrder_Resource::StartGathering(CUnit &unit)
{
CUnit *goal;
const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];
Assert(!unit.IX);
Assert(!unit.IY);
//Wyrmgus start
// if (resinfo.TerrainHarvester) {
if (Map.Info.IsPointOnMap(this->goalPos)) {
//Wyrmgus end
// This shouldn't happened?
#if 0
if (!Map.IsTerrainResourceOnMap(unit.Orders->goalPos, this->CurrentResource)) {
DebugPrint("Wood gone, just like that?\n");
return 0;
}
#endif
UnitHeadingFromDeltaXY(unit, this->goalPos - unit.tilePos);
if (resinfo.WaitAtResource) {
this->TimeToHarvest = std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
} else {
this->TimeToHarvest = 1;
}
this->DoneHarvesting = 0;
if (this->CurrentResource != unit.CurrentResource) {
DropResource(unit);
unit.CurrentResource = this->CurrentResource;
}
return 1;
}
goal = this->GetGoal();
// Target is dead, stop getting resources.
if (!goal || goal->IsVisibleAsGoal(*unit.Player) == false) {
// Find an alternative, but don't look too far.
this->goalPos.x = -1;
this->goalPos.y = -1;
if ((goal = UnitFindResource(unit, unit, 15, this->CurrentResource, unit.Player->AiEnabled))) {
this->State = SUB_START_RESOURCE;
this->SetGoal(goal);
} else {
this->ClearGoal();
this->Finished = true;
}
return 0;
}
// FIXME: 0 can happen, if to near placed by map designer.
Assert(unit.MapDistanceTo(*goal) <= 1);
// Update the heading of a harvesting unit to looks straight at the resource.
//Wyrmgus start
// UnitHeadingFromDeltaXY(unit, goal->tilePos - unit.tilePos + goal->Type->GetHalfTileSize());
UnitHeadingFromDeltaXY(unit, Vec2i(goal->tilePos.x * PixelTileSize.x, goal->tilePos.y * PixelTileSize.y) - Vec2i(unit.tilePos.x * PixelTileSize.x, unit.tilePos.y * PixelTileSize.y) + goal->Type->GetHalfTilePixelSize() - unit.Type->GetHalfTilePixelSize());
//Wyrmgus end
// If resource is still under construction, wait!
if ((goal->Type->MaxOnBoard && goal->Resource.Active >= goal->Type->MaxOnBoard)
|| goal->CurrentAction() == UnitActionBuilt) {
// FIXME: Determine somehow when the resource will be free to use
// FIXME: Could we somehow find another resource? Think minerals
// FIXME: We should add a flag for that, and a limited range.
// However the CPU usage is really low (no pathfinding stuff).
unit.Wait = 10;
return 0;
}
// Place unit inside the resource
//Wyrmgus start
// if (!resinfo.HarvestFromOutside) {
if (!goal->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
//Wyrmgus end
if (goal->Variable[MAXHARVESTERS_INDEX].Value == 0 || goal->Variable[MAXHARVESTERS_INDEX].Value > goal->InsideCount) {
this->ClearGoal();
int selected = unit.Selected;
unit.Remove(goal);
if (selected && !Preference.DeselectInMine) {
unit.Removed = 0;
SelectUnit(unit);
SelectionChanged();
unit.Removed = 1;
}
} else if (goal->Variable[MAXHARVESTERS_INDEX].Value <= goal->InsideCount) {
//Resource is full, wait
unit.Wait = 10;
return 0;
}
}
if (this->CurrentResource != unit.CurrentResource) {
DropResource(unit);
//.........这里部分代码省略.........
示例10: MoveToDepot
/**
** Move to resource depot
**
** @param unit Pointer to unit.
**
** @return TRUE if reached, otherwise FALSE.
*/
int COrder_Resource::MoveToDepot(CUnit &unit)
{
const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];
CUnit &goal = *this->GetGoal();
CPlayer &player = *unit.Player;
Assert(&goal);
switch (DoActionMove(unit)) { // reached end-point?
case PF_UNREACHABLE:
//Wyrmgus start
//if is unreachable and is on a raft, see if the raft can move closer
if ((Map.Field(unit.tilePos)->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()) {
if (table[i]->CurrentAction() == UnitActionStill) {
CommandStopUnit(*table[i]);
CommandMove(*table[i], this->HasGoal() ? this->GetGoal()->tilePos : this->goalPos, FlushCommands);
}
return 0;
}
}
}
//Wyrmgus end
return -1;
case PF_REACHED:
break;
case PF_WAIT:
if (unit.Player->AiEnabled) {
this->Range++;
if (this->Range >= 5) {
this->Range = 0;
AiCanNotMove(unit);
}
}
default:
if (unit.Anim.Unbreakable || goal.IsVisibleAsGoal(player)) {
return 0;
}
break;
}
//
// Target is dead, stop getting resources.
//
if (!goal.IsVisibleAsGoal(player)) {
DebugPrint("%d: Worker %d report: Destroyed depot\n" _C_ player.Index _C_ UnitNumber(unit));
unit.CurrentOrder()->ClearGoal();
CUnit *depot = FindDeposit(unit, 1000, unit.CurrentResource);
if (depot) {
UnitGotoGoal(unit, depot, SUB_MOVE_TO_DEPOT);
DebugPrint("%d: Worker %d report: Going to new deposit.\n" _C_ player.Index _C_ UnitNumber(unit));
} else {
DebugPrint("%d: Worker %d report: Can't find a new resource deposit.\n"
_C_ player.Index _C_ UnitNumber(unit));
// FIXME: perhaps we should choose an alternative
this->Finished = true;
}
return 0;
}
// If resource depot is still under construction, wait!
if (goal.CurrentAction() == UnitActionBuilt) {
unit.Wait = 10;
return 0;
}
this->ClearGoal();
unit.Wait = resinfo.WaitAtDepot;
// Place unit inside the depot
if (unit.Wait) {
int selected = unit.Selected;
unit.Remove(&goal);
if (selected && !Preference.DeselectInMine) {
unit.Removed = 0;
SelectUnit(unit);
SelectionChanged();
unit.Removed = 1;
}
unit.Anim.CurrAnim = NULL;
}
// Update resource.
const int rindex = resinfo.FinalResource;
//Wyrmgus start
// player.ChangeResource(rindex, (unit.ResourcesHeld * player.Incomes[rindex]) / 100, true);
// player.TotalResources[rindex] += (unit.ResourcesHeld * player.Incomes[rindex]) / 100;
//.........这里部分代码省略.........
示例11: Finish
static void Finish(COrder_Built &order, CUnit &unit)
{
const CUnitType &type = *unit.Type;
CPlayer &player = *unit.Player;
DebugPrint("%d: Building %s(%s) ready.\n" _C_ player.Index _C_ type.Ident.c_str() _C_ type.Name.c_str());
// HACK: the building is ready now
player.UnitTypesCount[type.Slot]++;
if (unit.Active) {
player.UnitTypesAiActiveCount[type.Slot]++;
}
unit.Constructed = 0;
if (unit.Frame < 0) {
unit.Frame = -1;
} else {
unit.Frame = 0;
}
CUnit *worker = order.GetWorkerPtr();
if (worker != NULL) {
if (type.BoolFlag[BUILDERLOST_INDEX].value) {
// Bye bye worker.
LetUnitDie(*worker);
worker = NULL;
} else { // Drop out the worker.
worker->ClearAction();
DropOutOnSide(*worker, LookingW, &unit);
// If we can harvest from the new building, do it.
if (worker->Type->ResInfo[type.GivesResource]) {
CommandResource(*worker, unit, 0);
}
// If we can reurn goods to a new depot, do it.
if (worker->CurrentResource && worker->ResourcesHeld > 0 && type.CanStore[worker->CurrentResource]) {
CommandReturnGoods(*worker, &unit, 0);
}
}
}
if (type.GivesResource && type.StartingResources != 0) {
// Has StartingResources, Use those
unit.ResourcesHeld = type.StartingResources;
}
player.Notify(NotifyGreen, unit.tilePos, _("New %s done"), type.Name.c_str());
if (&player == ThisPlayer) {
if (type.MapSound.Ready.Sound) {
PlayUnitSound(unit, VoiceReady);
} else if (worker) {
PlayUnitSound(*worker, VoiceWorkCompleted);
} else {
PlayUnitSound(unit, VoiceBuilding);
}
}
if (player.AiEnabled) {
/* Worker can be NULL */
AiWorkComplete(worker, unit);
}
// FIXME: Vladi: this is just a hack to test wall fixing,
// FIXME: also not sure if the right place...
// FIXME: Johns: hardcoded unit-type wall / more races!
if (&type == UnitTypeOrcWall || &type == UnitTypeHumanWall) {
Map.SetWall(unit.tilePos, &type == UnitTypeHumanWall);
unit.Remove(NULL);
UnitLost(unit);
UnitClearOrders(unit);
unit.Release();
return ;
}
UpdateForNewUnit(unit, 0);
// Set the direction of the building if it supports them
if (type.NumDirections > 1 && type.BoolFlag[NORANDOMPLACING_INDEX].value == false) {
if (type.BoolFlag[WALL_INDEX].value) { // Special logic for walls
CorrectWallDirections(unit);
CorrectWallNeighBours(unit);
} else {
unit.Direction = (MyRand() >> 8) & 0xFF; // random heading
}
UnitUpdateHeading(unit);
}
if (IsOnlySelected(unit) || &player == ThisPlayer) {
SelectedUnitChanged();
}
MapUnmarkUnitSight(unit);
unit.CurrentSightRange = unit.Stats->Variables[SIGHTRANGE_INDEX].Max;
MapMarkUnitSight(unit);
order.Finished = true;
}
示例12: TransformUnitIntoType
/**
** Transform a unit in another.
**
** @param unit unit to transform.
** @param newtype new type of the unit.
**
** @return 0 on error, 1 if nothing happens, 2 else.
*/
static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
{
const CUnitType &oldtype = *unit.Type;
if (&oldtype == &newtype) { // nothing to do
return 1;
}
const Vec2i pos = unit.tilePos + oldtype.GetHalfTileSize() - newtype.GetHalfTileSize();
CUnit *container = unit.Container;
if (container) {
MapUnmarkUnitSight(unit);
} else {
SaveSelection();
unit.Remove(NULL);
if (!UnitTypeCanBeAt(newtype, pos)) {
unit.Place(unit.tilePos);
RestoreSelection();
// FIXME unit is not modified, try later ?
return 0;
}
}
CPlayer &player = *unit.Player;
player.UnitTypesCount[oldtype.Slot]--;
player.UnitTypesCount[newtype.Slot]++;
player.Demand += newtype.Demand - oldtype.Demand;
player.Supply += newtype.Supply - oldtype.Supply;
// Change resource limit
for (int i = 0; i < MaxCosts; ++i) {
if (player.MaxResources[i] != -1) {
player.MaxResources[i] += newtype.Stats[player.Index].Storing[i] - oldtype.Stats[player.Index].Storing[i];
player.SetResource(i, player.StoredResources[i], STORE_BUILDING);
}
}
// adjust Variables with percent.
const CUnitStats &newstats = newtype.Stats[player.Index];
for (unsigned int i = 0; i < UnitTypeVar.GetNumberVariable(); ++i) {
if (unit.Variable[i].Max && unit.Variable[i].Value) {
unit.Variable[i].Value = newstats.Variables[i].Max *
unit.Variable[i].Value / unit.Variable[i].Max;
} else {
unit.Variable[i].Value = newstats.Variables[i].Value;
}
unit.Variable[i].Max = newstats.Variables[i].Max;
unit.Variable[i].Increase = newstats.Variables[i].Increase;
unit.Variable[i].Enable = newstats.Variables[i].Enable;
}
unit.Type = const_cast<CUnitType *>(&newtype);
unit.Stats = &unit.Type->Stats[player.Index];
if (newtype.CanCastSpell && !unit.AutoCastSpell) {
unit.AutoCastSpell = new char[SpellTypeTable.size()];
memset(unit.AutoCastSpell, 0, SpellTypeTable.size() * sizeof(char));
}
UpdateForNewUnit(unit, 1);
// Update Possible sight range change
UpdateUnitSightRange(unit);
if (!container) {
unit.Place(pos);
RestoreSelection();
} else {
MapMarkUnitSight(unit);
}
//
// Update possible changed buttons.
//
if (IsOnlySelected(unit) || &player == ThisPlayer) {
// could affect the buttons of any selected unit
SelectedUnitChanged();
}
return 1;
}
示例13: MakeAndPredicate
/**
** Cast capture.
**
** @param caster Unit that casts the spell
** @param spell Spell-type pointer
** @param target Target unit that spell is addressed to
** @param goalPos coord of target spot when/if target does not exist
**
** @return =!0 if spell should be repeated, 0 if not
*/
/* virtual */ int Spell_Capture::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &/*goalPos*/)
{
if (!target || caster.Player == target->Player) {
return 0;
}
if (this->DamagePercent) {
if ((100 * target->Variable[HP_INDEX].Value) /
target->Variable[HP_INDEX].Max > this->DamagePercent &&
target->Variable[HP_INDEX].Value > this->Damage) {
HitUnit(&caster, *target, this->Damage);
if (this->SacrificeEnable) {
// No corpse.
caster.Remove(NULL);
caster.Release();
}
return 1;
}
}
caster.Player->Score += target->Variable[POINTS_INDEX].Value;
if (caster.IsEnemy(*target)) {
if (target->Type->Building) {
caster.Player->TotalRazings++;
} else {
caster.Player->TotalKills++;
}
//Wyrmgus start
caster.Player->UnitTypeKills[target->Type->Slot]++;
/*
if (UseHPForXp) {
caster.Variable[XP_INDEX].Max += target->Variable[HP_INDEX].Value;
} else {
caster.Variable[XP_INDEX].Max += target->Variable[POINTS_INDEX].Value;
}
caster.Variable[XP_INDEX].Value = caster.Variable[XP_INDEX].Max;
*/
//distribute experience between nearby units belonging to the same player
if (!target->Type->BoolFlag[BUILDING_INDEX].value) {
std::vector<CUnit *> table;
SelectAroundUnit(caster, 6, table, MakeAndPredicate(HasSamePlayerAs(*caster.Player), IsNotBuildingType()));
if (UseHPForXp) {
caster.Variable[XP_INDEX].Max += target->Variable[HP_INDEX].Value / (table.size() + 1);
} else {
caster.Variable[XP_INDEX].Max += target->Variable[POINTS_INDEX].Value / (table.size() + 1);
}
caster.Variable[XP_INDEX].Value = caster.Variable[XP_INDEX].Max;
caster.XPChanged();
for (size_t i = 0; i != table.size(); ++i) {
if (UseHPForXp) {
table[i]->Variable[XP_INDEX].Max += target->Variable[HP_INDEX].Value / (table.size() + 1);
} else {
table[i]->Variable[XP_INDEX].Max += target->Variable[POINTS_INDEX].Value / (table.size() + 1);
}
table[i]->Variable[XP_INDEX].Value = table[i]->Variable[XP_INDEX].Max;
table[i]->XPChanged();
}
}
//Wyrmgus end
caster.Variable[KILL_INDEX].Value++;
caster.Variable[KILL_INDEX].Max++;
caster.Variable[KILL_INDEX].Enable = 1;
}
target->ChangeOwner(*caster.Player);
UnitClearOrders(*target);
if (this->JoinToAIForce && caster.Player->AiEnabled) {
int force = caster.Player->Ai->Force.GetForce(caster);
if (force != -1) {
caster.Player->Ai->Force[force].Insert(*target);
target->GroupId = caster.GroupId;
CommandDefend(*target, caster, FlushCommands);
}
}
if (this->SacrificeEnable) {
// No corpse.
caster.Remove(NULL);
caster.Release();
} else {
caster.Variable[MANA_INDEX].Value -= spell.ManaCost;
}
return 0;
}