/** ** 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; }
/** ** Cast circle of power. ** ** @param caster Unit that casts the spell ** @param spell Spell-type pointer ** @param target Target unit that spell is addressed to ** @param goalPos tilePos of target spot when/if target does not exist ** ** @return =!0 if spell should be repeated, 0 if not */ /* virtual */ int Spell_SpawnPortal::Cast(CUnit &caster, const SpellType &, CUnit *, const Vec2i &goalPos) { // FIXME: vladi: cop should be placed only on explored land CUnit *portal = caster.Goal; DebugPrint("Spawning a portal exit.\n"); if (portal) { portal->MoveToXY(goalPos); } else { portal = MakeUnitAndPlace(goalPos, *this->PortalType, &Players[PlayerNumNeutral]); } // Goal is used to link to destination circle of power caster.Goal = portal; //FIXME: setting destination circle of power should use mana return 0; }
/** ** Game main loop. ** ** Unit actions. ** Missile actions. ** Players (AI). ** Cyclic events (color cycle,...) ** Display update. ** Input/Network/Sound. */ void GameMainLoop() { const EventCallback *old_callbacks; InitGameCallbacks(); old_callbacks = GetCallbacks(); SetCallbacks(&GameCallbacks); SetVideoSync(); GameCursor = UI.Point.Cursor; GameRunning = true; CParticleManager::init(); #ifdef REALVIDEO RealVideoSyncSpeed = VideoSyncSpeed; #endif CclCommand("if (GameStarting ~= nil) then GameStarting() end"); MultiPlayerReplayEachCycle(); //Wyrmgus start //if the person player has no faction, bring up the faction choice interface if (!GrandStrategy && ThisPlayer && ThisPlayer->Faction == -1) { char buf[256]; snprintf(buf, sizeof(buf), "if (ChooseFaction ~= nil) then ChooseFaction(\"%s\", \"%s\") end", ThisPlayer->Race != -1 ? PlayerRaces.Name[ThisPlayer->Race].c_str() : "", ""); CclCommand(buf); } if (!IsNetworkGame() && ThisPlayer && CurrentCustomHero != NULL) { Vec2i resPos; FindNearestDrop(*CurrentCustomHero->Type, ThisPlayer->StartPos, resPos, LookingW); CUnit *custom_hero = MakeUnitAndPlace(resPos, *CurrentCustomHero->Type, ThisPlayer); custom_hero->SetCharacter(CurrentCustomHero->GetFullName(), true); } //Wyrmgus end SingleGameLoop(); // // Game over // if (GameResult == GameExit) { Exit(0); return; } #ifdef REALVIDEO if (FastForwardCycle > GameCycle) { VideoSyncSpeed = RealVideoSyncSpeed; } #endif NetworkQuitGame(); EndReplayLog(); GameCycle = 0;//???? //Wyrmgus start GameTimeOfDay = NoTimeOfDay; //Wyrmgus end CParticleManager::exit(); FlagRevealMap = 0; ReplayRevealMap = 0; GamePaused = false; GodMode = false; SetCallbacks(old_callbacks); }
/** ** Game main loop. ** ** Unit actions. ** Missile actions. ** Players (AI). ** Cyclic events (color cycle,...) ** Display update. ** Input/Network/Sound. */ void GameMainLoop() { const EventCallback *old_callbacks; InitGameCallbacks(); old_callbacks = GetCallbacks(); SetCallbacks(&GameCallbacks); SetVideoSync(); GameCursor = UI.Point.Cursor; //Wyrmgus start GameEstablishing = false; //Wyrmgus end GameRunning = true; CParticleManager::init(); #ifdef REALVIDEO RealVideoSyncSpeed = VideoSyncSpeed; #endif CclCommand("if (GameStarting ~= nil) then GameStarting() end"); MultiPlayerReplayEachCycle(); //Wyrmgus start if (GameCycle == 0) { // so that these don't trigger when loading a saved game if (CurrentCampaign != NULL) { for (int i = 0; i < NumPlayers; ++i) { if (Players[i].Type != PlayerNobody && Players[i].Race != 0 && Players[i].Faction != -1) { if (CurrentCampaign->StartDate.year) { CCivilization *civilization = PlayerRaces.Civilizations[Players[i].Race]; CFaction *faction = PlayerRaces.Factions[Players[i].Race][Players[i].Faction]; for (std::map<std::string, std::map<CDate, bool>>::iterator iterator = civilization->HistoricalUpgrades.begin(); iterator != civilization->HistoricalUpgrades.end(); ++iterator) { int upgrade_id = UpgradeIdByIdent(iterator->first); if (upgrade_id == -1) { fprintf(stderr, "Upgrade \"%s\" doesn't exist.\n", iterator->first.c_str()); continue; } for (std::map<CDate, bool>::reverse_iterator second_iterator = iterator->second.rbegin(); second_iterator != iterator->second.rend(); ++second_iterator) { if (second_iterator->first.year == 0 || CurrentCampaign->StartDate >= second_iterator->first) { if (second_iterator->second && UpgradeIdentAllowed(Players[i], iterator->first.c_str()) != 'R') { UpgradeAcquire(Players[i], AllUpgrades[upgrade_id]); } else if (!second_iterator->second) { break; } } } } for (std::map<std::string, std::map<CDate, bool>>::iterator iterator = faction->HistoricalUpgrades.begin(); iterator != faction->HistoricalUpgrades.end(); ++iterator) { int upgrade_id = UpgradeIdByIdent(iterator->first); if (upgrade_id == -1) { fprintf(stderr, "Upgrade \"%s\" doesn't exist.\n", iterator->first.c_str()); continue; } for (std::map<CDate, bool>::reverse_iterator second_iterator = iterator->second.rbegin(); second_iterator != iterator->second.rend(); ++second_iterator) { if (second_iterator->first.year == 0 || CurrentCampaign->StartDate >= second_iterator->first) { if (second_iterator->second && UpgradeIdentAllowed(Players[i], iterator->first.c_str()) != 'R') { UpgradeAcquire(Players[i], AllUpgrades[upgrade_id]); } else if (!second_iterator->second) { break; } } } } for (std::map<std::pair<int, CFaction *>, int>::iterator iterator = faction->HistoricalDiplomacyStates.begin(); iterator != faction->HistoricalDiplomacyStates.end(); ++iterator) { //set the appropriate historical diplomacy states to other factions if (iterator->second == 0 || CurrentCampaign->StartDate.year >= iterator->first.first) { CPlayer *diplomacy_state_player = GetFactionPlayer(iterator->first.second); if (diplomacy_state_player) { CommandDiplomacy(i, iterator->second, diplomacy_state_player->Index); CommandDiplomacy(diplomacy_state_player->Index, iterator->second, i); if (iterator->second == DiplomacyAllied) { CommandSharedVision(i, true, diplomacy_state_player->Index); CommandSharedVision(diplomacy_state_player->Index, true, i); } } } } for (std::map<std::pair<CDate, int>, int>::iterator iterator = faction->HistoricalResources.begin(); iterator != faction->HistoricalResources.end(); ++iterator) { //set the appropriate historical resource quantities if (iterator->second == 0 || CurrentCampaign->StartDate >= iterator->first.first) { Players[i].SetResource(iterator->first.second, iterator->second); } } } } } if (CurrentCampaign->StartEffects) { CurrentCampaign->StartEffects->pushPreamble(); CurrentCampaign->StartEffects->run(); } } //if the person player has no faction, bring up the faction choice interface if (!GrandStrategy && ThisPlayer && ThisPlayer->Faction == -1) { char buf[256]; snprintf(buf, sizeof(buf), "if (ChooseFaction ~= nil) then ChooseFaction(\"%s\", \"%s\") end", ThisPlayer->Race != -1 ? PlayerRaces.Name[ThisPlayer->Race].c_str() : "", ""); CclCommand(buf); } if (!IsNetworkGame() && ThisPlayer && CurrentCustomHero != NULL) { Vec2i resPos; FindNearestDrop(*CurrentCustomHero->Type, ThisPlayer->StartPos, resPos, LookingW, ThisPlayer->StartMapLayer); CUnit *custom_hero = MakeUnitAndPlace(resPos, *CurrentCustomHero->Type, ThisPlayer, ThisPlayer->StartMapLayer); custom_hero->SetCharacter(CurrentCustomHero->Ident, true); } if (CurrentQuest != NULL && CurrentQuest->IntroductionDialogue != NULL) { CurrentQuest->IntroductionDialogue->Call(ThisPlayer->Index); } } //Wyrmgus end SingleGameLoop(); // // Game over // if (GameResult == GameExit) { Exit(0); return; } #ifdef REALVIDEO if (FastForwardCycle > GameCycle) { VideoSyncSpeed = RealVideoSyncSpeed; } #endif NetworkQuitGame(); EndReplayLog(); GameCycle = 0;//???? CParticleManager::exit(); FlagRevealMap = 0; ReplayRevealMap = 0; GamePaused = false; GodMode = false; SetCallbacks(old_callbacks); }
/** ** Add a unit to random locations on the map, unit will be neutral ** ** @param unit_type unit type to add to map as a character string ** @param count the number of times to add the unit ** @param value resources to be stored in that unit */ static void EditorRandomizeUnit(const char *unit_type, int count, int value) { //Wyrmgus start // const Vec2i mpos(Map.Info.MapWidth, Map.Info.MapHeight); const Vec2i mpos(Map.Info.MapWidths[CurrentMapLayer], Map.Info.MapHeights[CurrentMapLayer]); //Wyrmgus end CUnitType *typeptr = UnitTypeByIdent(unit_type); if (!typeptr) { // Error return; } CUnitType &type = *typeptr; const Vec2i tpos(type.TileWidth, type.TileHeight); for (int i = 0; i < count; ++i) { const Vec2i rpos(rand() % (mpos.x / 2 - tpos.x + 1), rand() % (mpos.y / 2 - tpos.y + 1)); const Vec2i mirror(mpos.x - rpos.x - 1, mpos.y - rpos.y - 1); const Vec2i mirrorh(rpos.x, mirror.y); const Vec2i mirrorv(mirror.x, rpos.y); const Vec2i tmirror(mpos.x - rpos.x - tpos.x, mpos.y - rpos.y - tpos.y); const Vec2i tmirrorh(rpos.x, tmirror.y); const Vec2i tmirrorv(tmirror.x, rpos.y); int tile = GRASS_TILE; const int z = type.TileHeight; // FIXME: vladi: the idea is simple: make proper land for unit(s) :) // FIXME: handle units larger than 1 square TileFill(rpos, tile, z * 2); TileFill(mirrorh, tile, z * 2); TileFill(mirrorv, tile, z * 2); TileFill(mirror, tile, z * 2); // FIXME: can overlap units //Wyrmgus start // CUnit *unit = MakeUnitAndPlace(rpos, type, &Players[PlayerNumNeutral]); CUnit *unit = MakeUnitAndPlace(rpos, type, &Players[PlayerNumNeutral], CurrentMapLayer); //Wyrmgus end if (unit == NULL) { DebugPrint("Unable to allocate Unit"); } else { //Wyrmgus start // unit->ResourcesHeld = value; unit->SetResourcesHeld(value); //Wyrmgus end } //Wyrmgus start // unit = MakeUnitAndPlace(tmirrorh, type, &Players[PlayerNumNeutral]); unit = MakeUnitAndPlace(tmirrorh, type, &Players[PlayerNumNeutral], CurrentMapLayer); //Wyrmgus end if (unit == NULL) { DebugPrint("Unable to allocate Unit"); } else { //Wyrmgus start // unit->ResourcesHeld = value; unit->SetResourcesHeld(value); //Wyrmgus end } //Wyrmgus start // unit = MakeUnitAndPlace(tmirrorv, type, &Players[PlayerNumNeutral]); unit = MakeUnitAndPlace(tmirrorv, type, &Players[PlayerNumNeutral], CurrentMapLayer); //Wyrmgus end if (unit == NULL) { DebugPrint("Unable to allocate Unit"); } else { //Wyrmgus start // unit->ResourcesHeld = value; unit->SetResourcesHeld(value); //Wyrmgus end } //Wyrmgus start // unit = MakeUnitAndPlace(tmirror, type, &Players[PlayerNumNeutral]); unit = MakeUnitAndPlace(tmirror, type, &Players[PlayerNumNeutral], CurrentMapLayer); //Wyrmgus end if (unit == NULL) { DebugPrint("Unable to allocate Unit"); } else { //Wyrmgus start // unit->ResourcesHeld = value; unit->SetResourcesHeld(value); //Wyrmgus end } } }