/** ** Destroy all units */ static void EditorDestroyAllUnits() { while (UnitManager.empty() == false) { CUnit &unit = **UnitManager.begin(); unit.Remove(NULL); UnitLost(unit); UnitClearOrders(unit); unit.Release(); } }
/** ** Cast polymorph. ** ** @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_Polymorph::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &goalPos) { if (!target) { return 0; } CUnitType &type = *this->NewForm; const Vec2i pos(goalPos - type.GetHalfTileSize()); caster.Player->Score += target->Variable[POINTS_INDEX].Value; if (caster.IsEnemy(*target)) { if (target->Type->Building) { caster.Player->TotalRazings++; } else { caster.Player->TotalKills++; } 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; caster.Variable[KILL_INDEX].Value++; caster.Variable[KILL_INDEX].Max++; caster.Variable[KILL_INDEX].Enable = 1; } // as said somewhere else -- no corpses :) target->Remove(NULL); Vec2i offset; for (offset.x = 0; offset.x < type.TileWidth; ++offset.x) { for (offset.y = 0; offset.y < type.TileHeight; ++offset.y) { if (!UnitTypeCanBeAt(type, pos + offset)) { target->Place(target->tilePos); return 0; } } } caster.Variable[MANA_INDEX].Value -= spell.ManaCost; if (this->PlayerNeutral == 1) { MakeUnitAndPlace(pos, type, Players + PlayerNumNeutral); } else if (this->PlayerNeutral == 2) { MakeUnitAndPlace(pos, type, caster.Player); } else { MakeUnitAndPlace(pos, type, target->Player); } UnitLost(*target); UnitClearOrders(*target); target->Release(); return 1; }
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; }
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; }