/** ** Enable display mana as vertical bar. ** ** Equivalent of ** DefineDecorations({Index = "Mana", HideNeutral = true, ** Method = {"bar", {Width = 3, BorderSize = 1, Orientation = "vertical"}}}) ** For index Mana, Transport, Research, Training, UpgradeTo, Resource. ** ** @param l Lua state */ static int CclShowManaVertical(lua_State *l) { char lua_equiv[] = "DefineDecorations({Index = \"Mana\", HideNeutral = true" "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})\n" "DefineDecorations({Index = \"Transport\", HideNeutral = true," "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})\n" "DefineDecorations({Index = \"Research\", HideNeutral = true," "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})\n" "DefineDecorations({Index = \"Training\", HideNeutral = true," "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})\n" "DefineDecorations({Index = \"UpgradeTo\", HideNeutral = true," "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})\n" "DefineDecorations({Index = \"GiveResource\", HideNeutral = false," "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})\n" "DefineDecorations({Index = \"CarryResource\", HideNeutral = false," "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})\n"; LuaCheckArgs(l, 0); DebugPrint("instead of ShowManaVertical, you should write instead :\n%s\n" _C_ lua_equiv); CclCommand(lua_equiv); return 0; }
/** ** Enable display mana as mana-sprite. ** ** Equivalent of ** DefineDecorations({Index = "Mana", HideNeutral = true, CenterX = true, ** OffsetPercent = {50, 100}, ** Method = {"sprite", {0}}}) ** For index Mana, Transport, Research, Training, UpgradeTo, Resource. ** Except for ressource which have HideNeutral = false. ** ** @param l Lua state */ static int CclShowManaDot(lua_State *l) { char lua_equiv[] = "DefineDecorations({Index = \"Mana\", HideNeutral = true, CenterX = true," "OffsetPercent = {50, 100},Method = {\"sprite\", {\"sprite-mana\"}}})\n" "DefineDecorations({Index = \"Transport\", HideNeutral = true, CenterX = true," "OffsetPercent = {50, 100},Method = {\"sprite\", {\"sprite-mana\"}}})\n" "DefineDecorations({Index = \"Research\", HideNeutral = true, CenterX = true," "OffsetPercent = {50, 100},Method = {\"sprite\", {\"sprite-mana\"}}})\n" "DefineDecorations({Index = \"Training\", HideNeutral = true, CenterX = true," "OffsetPercent = {50, 100},Method = {\"sprite\", {\"sprite-mana\"}}})\n" "DefineDecorations({Index = \"UpgradeTo\", HideNeutral = true, CenterX = true," "OffsetPercent = {50, 100},Method = {\"sprite\", {\"sprite-mana\"}}})\n" "DefineDecorations({Index = \"GiveResource\", HideNeutral = false, CenterX = true," "OffsetPercent = {50, 100},Method = {\"sprite\", {\"sprite-mana\"}}})\n" "DefineDecorations({Index = \"CarryResource\", HideNeutral = false, CenterX = true," "OffsetPercent = {50, 100},Method = {\"sprite\", {\"sprite-mana\"}}})\n"; LuaCheckArgs(l, 0); DebugPrint("instead of ShowManaDot, you should write instead :\n%s\n" _C_ lua_equiv); CclCommand(lua_equiv); return 0; }
/** ** Enable display health as health-sprite. ** Equivalent of ** DefineDecorations({Index = "HitPoints", HideNeutral = true, CenterX = true, ** OffsetPercent = {50, 100}, Offset = {0, -7}, ** Method = {"sprite", {1}}}) ** ** @param l Lua state */ static int CclShowHealthDot(lua_State *l) { const char *lua_equiv = "DefineDecorations({Index = \"HitPoints\", HideNeutral = true, CenterX = true," "OffsetPercent = {50, 100}, Method = {\"sprite\", {\"sprite-health\"}}})"; LuaCheckArgs(l, 0); DebugPrint("instead of ShowHealthDot, you should write instead :\n%s\n" _C_ lua_equiv); CclCommand(lua_equiv); return 0; }
/** ** Enable display health as health-bar. ** Equivalent of ** DefineDecorations({Index = "HitPoints", HideNeutral = true, ** Offset = {-7, 0}, ** Method = {"bar", {Width = 3, BorderSize = 1, Orientation = "vertical"}}}) ** ** @param l Lua state */ static int CclShowHealthVertical(lua_State *l) { const char *lua_equiv = "DefineDecorations({Index = \"HitPoints\", HideNeutral = true," "Offset = {-7, 0}," "Method = {\"bar\", {Width = 3, BorderSize = 1, Orientation = \"vertical\"}}})"; LuaCheckArgs(l, 0); DebugPrint("instead of ShowHealthVertical, you should write instead :\n%s\n" _C_ lua_equiv); CclCommand(lua_equiv); return 0; }
/** ** Enable display health as health-bar. ** Equivalent of ** DefineDecorations({Index = "HitPoints", HideNeutral = true, CenterX = true, ** OffsetPercent = {50, 100}, Offset = {0, -7}, ** Method = {"bar", {Width = 3, BorderSize = 1}}}) ** ** @param l Lua state */ static int CclShowHealthHorizontal(lua_State *l) { const char *lua_equiv = "DefineDecorations({Index = \"HitPoints\", HideNeutral = true, CenterX = true," "OffsetPercent = {50, 100}, Offset = {0, -7}," "Method = {\"bar\", {Width = 3, BorderSize = 1}}})"; LuaCheckArgs(l, 0); DebugPrint("instead of ShowHealthHorizontal, you should write instead :\n%s\n" _C_ lua_equiv); CclCommand(lua_equiv); 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(); 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); }
/** ** Define health sprite. ** ** @param l Lua state */ static int CclHealthSprite(lua_State *l) { char buffer[1024]; // lua equivalent. LuaCheckArgs(l, 5); sprintf(buffer, "DefineSprites({Name = \"%s\", File = \"%s\", " "Offset = {%i, %i}, Size = {%i, %i}})", "sprite-health", LuaToString(l, 1), (int) LuaToNumber(l, 2), (int) LuaToNumber(l, 3), (int )LuaToNumber(l, 4), (int) LuaToNumber(l, 5)); DebugPrint("instead of HealthSprite, you should write instead :\n%s\n" _C_ buffer); CclCommand(buffer); return 0; }
/** ** Game main loop. ** ** Unit actions. ** Missile actions. ** Players (AI). ** Cyclic events (color cycle,...) ** Display update. ** Input/Network/Sound. */ void GameMainLoop(void) { int player; const EventCallback *old_callbacks; InitGameCallbacks(); old_callbacks = GetCallbacks(); SetCallbacks(&GameCallbacks); SetVideoSync(); GameCursor = UI.Point.Cursor; GameRunning = true; CParticleManager::init(); MultiPlayerReplayEachCycle(); CclCommand("GameStarting()"); std::ofstream output; std::wstring templ; firstClock = std::clock(); templateClock = 0; int messageNumber = 1; std::ofstream outputEventsPerSec; std::ofstream outputNT; outputEventsPerSec.open("/tmp/boswarseventspersec.csv",std::ios::out); outputNT.open("/tmp/boswarsclocksperevents.csv",std::ios::out); output.open("/tmp/beepbeep.fifo",std::ios::out); templ = templ = L"<message>\n" L" <units>\n" L"{% for unit in units.tabunits %}" L" <unit>\n" L" <id>{$unit.id}</id>\n" L" <type>{$unit.type}</type>\n" L" <isbuilding>{$unit.isbuilding}</isbuilding>\n" L" <player>{$unit.player}</player>\n" L" <order>\n" L" <action>{$unit.action}</action>\n" L" <goal>{$unit.goal}</goal>\n" L" </order>\n" L" <neworder>\n" L" <action>{$unit.neworder}</action>\n" L" <goal>{$unit.newgoal}</goal>\n" L" </neworder>\n" L" </unit>\n" L"{% endfor %}" L" </units>\n" L"<overhead>{$overhead}</overhead>\n" L"</message>\n"; while (GameRunning) { // Can't find a better place. SaveGameLoading = false; // // Game logic part // if (!GamePaused && NetworkInSync && !SkipGameCycle) { SinglePlayerReplayEachCycle(); ++GameCycle; MultiPlayerReplayEachCycle(); NetworkCommands(); // Get network commands UnitActions(); // handle units MissileActions(); // handle missiles PlayersEachCycle(); // handle players UpdateTimer(); // update game timer // // Work todo each second. // Split into different frames, to reduce cpu time. // Increment mana of magic units. // Update mini-map. // Update map fog of war. // Call AI. // Check game goals. // Check rescue of units. // switch (GameCycle % CYCLES_PER_SECOND) { case 0: // At cycle 0, start all ai players... if (GameCycle == 0) { for (player = 0; player < NumPlayers; ++player) { PlayersEachSecond(player); } } break; case 1: break; case 2: break; case 3: // minimap update UI.Minimap.Update(); break; case 4: break; case 5: break; case 6: // overtaking units RescueUnits(); break; default: // FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7) player = (GameCycle % CYCLES_PER_SECOND) - 7; Assert(player >= 0); if (player < NumPlayers) { PlayersEachSecond(player); } } ////////////GET INFORMATION FOR MONITORING!!!//////////////////// if(NumUnits > 0) { std::clock_t littleClock = std::clock(); cpptempl::data_list theUnits; std::stringstream ss; for(int i = 0; i < NumUnits; i++) { cpptempl::data_map uni; /////////ID///////// ss.str(""); ss << Units[i]->Slot; std::string theID = ss.str(); std::wstring wTheID; wTheID.assign(theID.begin(),theID.end()); uni[L"id"] = cpptempl::make_data(wTheID); //////UNITTYPE////// ss.str(""); ss << Units[i]->Type->Name; std::string theType = ss.str(); std::wstring wTheType; wTheType.assign(theType.begin(),theType.end()); uni[L"type"] = cpptempl::make_data(wTheType); //////ISBUILDING////// ss.str(""); if (Units[i]->Type->Building == 1) ss << "true"; else ss << "false"; std::string theIsBuilding = ss.str(); std::wstring wTheIsBuilding; wTheIsBuilding.assign(theIsBuilding.begin(),theIsBuilding.end()); uni[L"isbuilding"] = cpptempl::make_data(wTheIsBuilding); //////PLAYER////// ss.str(""); ss << Units[i]->Player; std::string thePlayer = ss.str(); std::wstring wThePlayer; wThePlayer.assign(thePlayer.begin(),thePlayer.end()); uni[L"player"] = cpptempl::make_data(wThePlayer); //////UnitAction////// ss.str(""); switch(Units[i]->Orders[0]->Action) { case UnitActionNone: ss << "UnitActionNone"; break; case UnitActionStill: ss << "UnitActionStill"; break; case UnitActionStandGround: ss << "UnitActionStandGround"; break; case UnitActionFollow: ss << "UnitActionFollow"; break; case UnitActionMove: ss << "UnitActionMove"; break; case UnitActionAttack: ss << "UnitActionAttack"; break; case UnitActionAttackGround: ss << "UnitActionAttackGround"; break; case UnitActionDie: ss << "UnitActionDie"; break; case UnitActionSpellCast: ss << "UnitActionSpellCast"; break; case UnitActionTrain: ss << "UnitActionTrain"; break; case UnitActionBuilt: ss << "UnitActionBuilt"; break; case UnitActionBoard: ss << "UnitActionBoard"; break; case UnitActionUnload: ss << "UnitActionUnload"; break; case UnitActionPatrol: ss << "UnitActionPatrol"; break; case UnitActionBuild: ss << "UnitActionBuild"; break; case UnitActionRepair: ss << "UnitActionRepair"; break; case UnitActionResource: ss << "UnitActionResource"; break; default: ss << "None"; } std::string theAction = ss.str(); std::wstring wTheAction; wTheAction.assign(theAction.begin(),theAction.end()); uni[L"action"] = cpptempl::make_data(wTheAction); //////UnitGoal////// ss.str(""); if(Units[i]->Orders[0]->Goal != NULL) ss << Units[i]->Orders[0]->Goal->Slot; else ss << "None"; std::string theGoal = ss.str(); std::wstring wTheGoal; wTheGoal.assign(theGoal.begin(),theGoal.end()); uni[L"goal"] = cpptempl::make_data(wTheGoal); ///////NEW ORDER///////// ss.str(""); switch(Units[i]->NewOrder.Action) { case UnitActionNone: ss << "UnitActionNone"; break; case UnitActionStill: ss << "UnitActionStill"; break; case UnitActionStandGround: ss << "UnitActionStandGround"; break; case UnitActionFollow: ss << "UnitActionFollow"; break; case UnitActionMove: ss << "UnitActionMove"; break; case UnitActionAttack: ss << "UnitActionAttack"; break; case UnitActionAttackGround: ss << "UnitActionAttackGround"; break; case UnitActionDie: ss << "UnitActionDie"; break; case UnitActionSpellCast: ss << "UnitActionSpellCast"; break; case UnitActionTrain: ss << "UnitActionTrain"; break; case UnitActionBuilt: ss << "UnitActionBuilt"; break; case UnitActionBoard: ss << "UnitActionBoard"; break; case UnitActionUnload: ss << "UnitActionUnload"; break; case UnitActionPatrol: ss << "UnitActionPatrol"; break; case UnitActionBuild: ss << "UnitActionBuild"; break; case UnitActionRepair: ss << "UnitActionRepair"; break; case UnitActionResource: ss << "UnitActionResource"; break; default: ss << "None"; } std::string theNewOrder = ss.str(); std::wstring wTheNewOrder; wTheNewOrder.assign(theNewOrder.begin(),theNewOrder.end()); uni[L"neworder"] = cpptempl::make_data(wTheNewOrder); //////NEW GOAL////// ss.str(""); if(Units[i]->NewOrder.Goal != NULL) ss << Units[i]->NewOrder.Goal->Slot; else ss << "None"; std::string theNewGoal = ss.str(); std::wstring wTheNewGoal; wTheNewGoal.assign(theNewGoal.begin(),theNewGoal.end()); uni[L"newgoal"] = cpptempl::make_data(wTheNewGoal); theUnits.push_back((cpptempl::make_data(uni))); } cpptempl::data_map lesUnits; lesUnits[L"tabunits"] = cpptempl::make_data(theUnits); // Now set this in the data map cpptempl::data_map data; data[L"units"] = cpptempl::make_data(lesUnits); //////////////////TIMESTAMP///////////////////////// std::clock_t t = std::clock() - firstClock; double timeStamp = ((double)t/(double)CLOCKS_PER_SEC); ss.str(""); ss << std::setprecision(8) << timeStamp; std::string sTimeStamp = ss.str(); std::string gnuPlotStringT = ss.str(); std::wstring wTimeStamp; wTimeStamp.assign(sTimeStamp.begin(),sTimeStamp.end()); data[L"timestamp"] = cpptempl::make_data(wTimeStamp); ///OVERHEAD///// templateClock += std::clock()-littleClock; long double overhead = (long double)templateClock / ((long double)std::clock()-(long double)firstClock)*(long double)100.0; ss.str(""); ss << std::setprecision(10) << overhead; std::string sOverhead = ss.str(); std::wstring wOverhead; wOverhead.assign(sOverhead.begin(),sOverhead.end()); data[L"overhead"] = cpptempl::make_data(wOverhead); std::cout << overhead << "% overhead\n"; //std::cout << std::clock() << " clocl\n"; /////////////////MESSAGENUMBER/////////////////////////< ss.str(""); ss << messageNumber; std::string gnuPlotStringN = ss.str(); std::string sMessageNumber = ss.str(); std::wstring wMessageNumber; wMessageNumber.assign(sMessageNumber.begin(),sMessageNumber.end()); data[L"messagenumber"] = cpptempl::make_data(wMessageNumber); std::wstring result = cpptempl::parse(templ, data); ss.str(""); double templateTime = ((double)templateClock/(double)CLOCKS_PER_SEC)*(double)1000; ss << std::setprecision(8) << templateTime; std::string templTime = ss.str(); double totalT = ((std::clock()-firstClock)/(double)CLOCKS_PER_SEC); std::cout << totalT << "totaltime\n"; std::cout << CYCLES_PER_SECOND << "cycles\n"; std::string s; s.assign(result.begin(), result.end()); if (messageNumber == 1) { std::ofstream traceoutput; traceoutput.open("/tmp/traceout.xml",std::ios::out); traceoutput << s; traceoutput.close(); } messageNumber++; /////STATS///// output << s; std::string out = gnuPlotStringN + "," + gnuPlotStringT + "\n"; outputEventsPerSec << out; //OutputNT //std::string theT; out = ""; //ss.str(""); //ss << templTime; //theT = ss.str(); out = templTime + "," + gnuPlotStringN + "\n"; outputNT << out; } ///////////////////////////////////////////////////////////////// } TriggersEachCycle(); // handle triggers UpdateMessages(); // update messages ParticleManager.update(); // handle particles CheckMusicFinished(); // Check for next song // // Map scrolling // DoScrollArea(MouseScrollState | KeyScrollState, (KeyModifiers & ModifierControl) != 0); if (FastForwardCycle <= GameCycle || GameCycle <= 10 || !(GameCycle & 0x3f)) { //FIXME: this might be better placed somewhere at front of the // program, as we now still have a game on the background and // need to go through the game-menu or supply a map file UpdateDisplay(); // // If double-buffered mode, we will display the contains of // VideoMemory. If direct mode this does nothing. In X11 it does // XFlush // RealizeVideoMemory(); } if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) { WaitEventsOneFrame(); } if (!NetworkInSync) { NetworkRecover(); // recover network } } output.close(); outputNT.close(); outputEventsPerSec.close(); // // Game over // NetworkQuit(); EndReplayLog(); CParticleManager::exit(); FlagRevealMap = 0; ReplayRevealMap = 0; GamePaused = false; GodMode = false; SetCallbacks(old_callbacks); }
/** ** Handle keys in input mode. ** ** @param key Key scancode. ** @return True input finished. */ static int InputKey(int key) { char ChatMessage[sizeof(Input) + 40]; int i; char *namestart; char *p; char *q; switch (key) { case SDLK_RETURN: case SDLK_KP_ENTER: // RETURN // Replace ~~ with ~ for (p = q = Input; *p;) { if (*p == '~') { ++p; } *q++ = *p++; } *q = '\0'; #ifdef DEBUG if (Input[0] == '-') { if (!GameObserve && !GamePaused) { CommandLog("input", NoUnitP, FlushCommands, -1, -1, NoUnitP, Input, -1); CclCommand(Input + 1, false); } } else #endif if (!IsNetworkGame()) { if (!GameObserve && !GamePaused) { if (HandleCheats(Input)) { CommandLog("input", NoUnitP, FlushCommands, -1, -1, NoUnitP, Input, -1); } } } // Check for Replay and ffw x #ifdef DEBUG if (strncmp(Input, "ffw ", 4) == 0) { #else if (strncmp(Input, "ffw ", 4) == 0 && ReplayGameType != ReplayNone) { #endif FastForwardCycle = atoi(&Input[4]); } if (Input[0]) { // Replace ~ with ~~ for (p = Input; *p; ++p) { if (*p == '~') { q = p + strlen(p); q[1] = '\0'; while (q > p) { *q = *(q - 1); --q; } ++p; } } snprintf(ChatMessage, sizeof(ChatMessage), "~%s~<%s>~> %s", PlayerColorNames[ThisPlayer->Index].c_str(), ThisPlayer->Name.c_str(), Input); // FIXME: only to selected players ... NetworkChatMessage(ChatMessage); } // FALL THROUGH case SDLK_ESCAPE: KeyState = KeyStateCommand; UI.StatusLine.Clear(); return 1; case SDLK_BACKSPACE: if (InputIndex) { if (Input[InputIndex - 1] == '~') { Input[--InputIndex] = '\0'; } InputIndex = UTF8GetPrev(Input, InputIndex); if (InputIndex >= 0) { Input[InputIndex] = '\0'; ShowInput(); } } return 1; case SDLK_TAB: namestart = strrchr(Input, ' '); if (namestart) { ++namestart; } else { namestart = Input; } if (!strlen(namestart)) { return 1; } for (i = 0; i < PlayerMax; ++i) { if (Players[i].Type != PlayerPerson) { continue; } if (!strncasecmp(namestart, Players[i].Name.c_str(), strlen(namestart))) { InputIndex += strlen(Players[i].Name.c_str()) - strlen(namestart); strcpy_s(namestart, sizeof(Input) - (namestart - Input), Players[i].Name.c_str()); if (namestart == Input) { InputIndex += 2; strcat_s(namestart, sizeof(Input) - (namestart - Input), ": "); } ShowInput(); } } return 1; default: if (key >= ' ') { gcn::Key k(key); std::string kstr = k.toString(); if (key == '~') { if (InputIndex < (int)sizeof(Input) - 2) { Input[InputIndex++] = key; Input[InputIndex++] = key; Input[InputIndex] = '\0'; ShowInput(); } } else if (InputIndex < (int)(sizeof(Input) - kstr.size())) { for (size_t i = 0; i < kstr.size(); ++i) { Input[InputIndex++] = kstr[i]; } Input[InputIndex] = '\0'; ShowInput(); } return 1; } break; } return 0; } /** ** Save a screenshot. */ static void Screenshot() { CFile fd; char filename[30]; int i; for (i = 1; i <= 99; ++i) { // FIXME: what if we can't write to this directory? snprintf(filename, sizeof(filename), "screen%02d.png", i); if (fd.open(filename, CL_OPEN_READ) == -1) { break; } fd.close(); } SaveScreenshotPNG(filename); }
/** ** Do next replay */ static void DoNextReplay() { Assert(ReplayStep != 0); NextLogCycle = ReplayStep->GameCycle; if (NextLogCycle != GameCycle) { return; } const int unitSlot = ReplayStep->UnitNumber; const char *action = ReplayStep->Action.c_str(); const int flags = ReplayStep->Flush; const Vec2i pos(ReplayStep->PosX, ReplayStep->PosY); const int arg1 = ReplayStep->PosX; const int arg2 = ReplayStep->PosY; CUnit *unit = unitSlot != -1 ? &UnitManager.GetSlotUnit(unitSlot) : NULL; CUnit *dunit = (ReplayStep->DestUnitNumber != -1 ? &UnitManager.GetSlotUnit(ReplayStep->DestUnitNumber) : NULL); const char *val = ReplayStep->Value.c_str(); const int num = ReplayStep->Num; Assert(unitSlot == -1 || ReplayStep->UnitIdent == unit->Type->Ident); if (SyncRandSeed != ReplayStep->SyncRandSeed) { #ifdef DEBUG if (!ReplayStep->SyncRandSeed) { // Replay without the 'sync info ThisPlayer->Notify("%s", _("No sync info for this replay !")); } else { ThisPlayer->Notify(_("Replay got out of sync (%lu) !"), GameCycle); DebugPrint("OUT OF SYNC %u != %u\n" _C_ SyncRandSeed _C_ ReplayStep->SyncRandSeed); DebugPrint("OUT OF SYNC GameCycle %lu \n" _C_ GameCycle); Assert(0); // ReplayStep = 0; // NextLogCycle = ~0UL; // return; } #else ThisPlayer->Notify("%s", _("Replay got out of sync !")); ReplayStep = 0; NextLogCycle = ~0UL; return; #endif } if (!strcmp(action, "stop")) { SendCommandStopUnit(*unit); } else if (!strcmp(action, "stand-ground")) { SendCommandStandGround(*unit, flags); } else if (!strcmp(action, "defend")) { SendCommandDefend(*unit, *dunit, flags); } else if (!strcmp(action, "follow")) { SendCommandFollow(*unit, *dunit, flags); } else if (!strcmp(action, "move")) { SendCommandMove(*unit, pos, flags); //Wyrmgus start } else if (!strcmp(action, "pick-up")) { SendCommandPickUp(*unit, *dunit, flags); //Wyrmgus end } else if (!strcmp(action, "repair")) { SendCommandRepair(*unit, pos, dunit, flags); } else if (!strcmp(action, "auto-repair")) { SendCommandAutoRepair(*unit, arg1); } else if (!strcmp(action, "attack")) { SendCommandAttack(*unit, pos, dunit, flags); } else if (!strcmp(action, "attack-ground")) { SendCommandAttackGround(*unit, pos, flags); //Wyrmgus start } else if (!strcmp(action, "use")) { SendCommandUse(*unit, *dunit, flags); } else if (!strcmp(action, "trade")) { SendCommandTrade(*unit, *dunit, flags); //Wyrmgus end } else if (!strcmp(action, "patrol")) { SendCommandPatrol(*unit, pos, flags); } else if (!strcmp(action, "board")) { SendCommandBoard(*unit, *dunit, flags); } else if (!strcmp(action, "unload")) { SendCommandUnload(*unit, pos, dunit, flags); } else if (!strcmp(action, "build")) { SendCommandBuildBuilding(*unit, pos, *UnitTypeByIdent(val), flags); } else if (!strcmp(action, "dismiss")) { SendCommandDismiss(*unit); } else if (!strcmp(action, "resource-loc")) { SendCommandResourceLoc(*unit, pos, flags); } else if (!strcmp(action, "resource")) { SendCommandResource(*unit, *dunit, flags); } else if (!strcmp(action, "return")) { SendCommandReturnGoods(*unit, dunit, flags); } else if (!strcmp(action, "train")) { //Wyrmgus start // SendCommandTrainUnit(*unit, *UnitTypeByIdent(val), flags); SendCommandTrainUnit(*unit, *UnitTypeByIdent(val), num, flags); //Wyrmgus end } else if (!strcmp(action, "cancel-train")) { SendCommandCancelTraining(*unit, num, (val && *val) ? UnitTypeByIdent(val) : NULL); } else if (!strcmp(action, "upgrade-to")) { SendCommandUpgradeTo(*unit, *UnitTypeByIdent(val), flags); } else if (!strcmp(action, "cancel-upgrade-to")) { SendCommandCancelUpgradeTo(*unit); //Wyrmgus start } else if (!strcmp(action, "transform-into")) { SendCommandTransformInto(*unit, *UnitTypeByIdent(val), flags); //Wyrmgus end } else if (!strcmp(action, "research")) { //Wyrmgus start // SendCommandResearch(*unit, *CUpgrade::Get(val), flags); SendCommandResearch(*unit, *CUpgrade::Get(val), num, flags); //Wyrmgus end } else if (!strcmp(action, "cancel-research")) { SendCommandCancelResearch(*unit); //Wyrmgus start } else if (!strcmp(action, "learn-ability")) { SendCommandLearnAbility(*unit, *CUpgrade::Get(val)); //Wyrmgus end } else if (!strcmp(action, "spell-cast")) { SendCommandSpellCast(*unit, pos, dunit, num, flags); } else if (!strcmp(action, "auto-spell-cast")) { SendCommandAutoSpellCast(*unit, num, arg1); //Wyrmgus start } else if (!strcmp(action, "rally-point")) { SendCommandRallyPoint(*unit, pos); } else if (!strcmp(action, "quest")) { SendCommandQuest(*unit, GetQuest(val)); } else if (!strcmp(action, "buy")) { SendCommandBuy(*unit, dunit, num); } else if (!strcmp(action, "produce-resource")) { SendCommandProduceResource(*unit, num); } else if (!strcmp(action, "sell-resource")) { SendCommandSellResource(*unit, arg1, num); } else if (!strcmp(action, "buy-resource")) { SendCommandBuyResource(*unit, arg1, num); //Wyrmgus end } else if (!strcmp(action, "diplomacy")) { int state; if (!strcmp(val, "neutral")) { state = DiplomacyNeutral; } else if (!strcmp(val, "allied")) { state = DiplomacyAllied; } else if (!strcmp(val, "enemy")) { state = DiplomacyEnemy; //Wyrmgus start } else if (!strcmp(val, "overlord")) { state = DiplomacyOverlord; } else if (!strcmp(val, "vassal")) { state = DiplomacyVassal; //Wyrmgus end } else if (!strcmp(val, "crazy")) { state = DiplomacyCrazy; } else { DebugPrint("Invalid diplomacy command: %s" _C_ val); state = -1; } SendCommandDiplomacy(arg1, state, arg2); } else if (!strcmp(action, "shared-vision")) { bool state; state = atoi(val) ? true : false; SendCommandSharedVision(arg1, state, arg2); } else if (!strcmp(action, "input")) { if (val[0] == '-') { CclCommand(val + 1, false); } else { HandleCheats(val); } } else if (!strcmp(action, "chat")) { SetMessage("%s", val); PlayGameSound(GameSounds.ChatMessage.Sound, MaxSampleVolume); } else if (!strcmp(action, "quit")) { CommandQuit(arg1); } else { DebugPrint("Invalid action: %s" _C_ action); } ReplayStep = ReplayStep->Next; NextLogCycle = ReplayStep ? (unsigned)ReplayStep->GameCycle : ~0UL; }
/** ** 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); }
static void GameLogicLoop() { // Can't find a better place. // FIXME: We need find better place! SaveGameLoading = false; // // Game logic part // if (!GamePaused && NetworkInSync && !SkipGameCycle) { SinglePlayerReplayEachCycle(); ++GameCycle; MultiPlayerReplayEachCycle(); NetworkCommands(); // Get network commands TriggersEachCycle();// handle triggers UnitActions(); // handle units MissileActions(); // handle missiles PlayersEachCycle(); // handle players UpdateTimer(); // update game timer // // Work todo each second. // Split into different frames, to reduce cpu time. // Increment mana of magic units. // Update mini-map. // Update map fog of war. // Call AI. // Check game goals. // Check rescue of units. // switch (GameCycle % CYCLES_PER_SECOND) { case 0: // At cycle 0, start all ai players... if (GameCycle == 0) { for (int player = 0; player < NumPlayers; ++player) { PlayersEachSecond(player); } } break; case 1: break; case 2: break; case 3: // minimap update UI.Minimap.UpdateCache = true; break; case 4: break; case 5: // forest grow Map.RegenerateForest(); break; case 6: // overtaking units RescueUnits(); break; default: { // FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7) int player = (GameCycle % CYCLES_PER_SECOND) - 7; Assert(player >= 0); if (player < NumPlayers) { PlayersEachSecond(player); } } } //Wyrmgus start if (GameCycle > 0 && GameCycle % (CYCLES_PER_SECOND * 10 * 3) == 0) { // every 10 seconds of gameplay = 1 hour for time of day calculations, change time of day every three hours if (!GameSettings.Inside) { // only change the time of the day if outdoors GameTimeOfDay += 1; if (GameTimeOfDay == MaxTimesOfDay) { GameTimeOfDay = 1; } } else { // indoors it is always dark (maybe would be better to allow a special setting to have bright indoor places? GameTimeOfDay = NoTimeOfDay; // make indoors have no time of day setting until it is possible to make light sources change their surrounding "time of day" } //update the sight of all units for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) { CUnit &unit = **it; if (!unit.Destroyed) { MapUnmarkUnitSight(unit); UpdateUnitSightRange(unit); MapMarkUnitSight(unit); } } } //Wyrmgus end //Wyrmgus start // if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && !GrandStrategy && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled //Wyrmgus end UI.StatusLine.Set(_("Autosave")); //Wyrmgus start // SaveGame("autosave.sav"); CclCommand("if (RunSaveGame ~= nil) then RunSaveGame(\"autosave.sav\") end;"); //Wyrmgus end } } UpdateMessages(); // update messages ParticleManager.update(); // handle particles CheckMusicFinished(); // Check for next song if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) { WaitEventsOneFrame(); } if (!NetworkInSync) { NetworkRecover(); // recover network } }
/** ** 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); }
static void GameLogicLoop() { // Can't find a better place. // FIXME: We need find better place! SaveGameLoading = false; #ifdef USE_OAML if (enableOAML && oaml) { // Time of day can change our main music loop, if the current playing track is set for this SetMusicCondition(OAML_CONDID_MAIN_LOOP, Map.TimeOfDay[CurrentMapLayer]); } #endif // // Game logic part // if (!GamePaused && NetworkInSync && !SkipGameCycle) { SinglePlayerReplayEachCycle(); ++GameCycle; MultiPlayerReplayEachCycle(); NetworkCommands(); // Get network commands TriggersEachCycle();// handle triggers UnitActions(); // handle units MissileActions(); // handle missiles PlayersEachCycle(); // handle players UpdateTimer(); // update game timer // // Work todo each second. // Split into different frames, to reduce cpu time. // Increment mana of magic units. // Update mini-map. // Update map fog of war. // Call AI. // Check game goals. // Check rescue of units. // switch (GameCycle % CYCLES_PER_SECOND) { case 0: // At cycle 0, start all ai players... if (GameCycle == 0) { for (int player = 0; player < NumPlayers; ++player) { PlayersEachSecond(player); } } break; case 1: break; case 2: break; case 3: // minimap update UI.Minimap.UpdateCache = true; break; case 4: break; case 5: // forest grow Map.RegenerateForest(); break; case 6: // overtaking units RescueUnits(); break; //Wyrmgus start /* default: { // FIXME: assume that NumPlayers < (CYCLES_PER_SECOND - 7) int player = (GameCycle % CYCLES_PER_SECOND) - 7; Assert(player >= 0); if (player < NumPlayers) { PlayersEachSecond(player); } } */ //Wyrmgus end } //Wyrmgus start int player = (GameCycle - 1) % CYCLES_PER_SECOND; Assert(player >= 0); if (player < NumPlayers) { PlayersEachSecond(player); if ((player + CYCLES_PER_SECOND) < NumPlayers) { PlayersEachSecond(player + CYCLES_PER_SECOND); } } player = (GameCycle - 1) % CYCLES_PER_MINUTE; Assert(player >= 0); if (player < NumPlayers) { PlayersEachMinute(player); } //Wyrmgus end //Wyrmgus start for (size_t z = 0; z < Map.Fields.size(); ++z) { if (GameSettings.Inside || GameSettings.NoTimeOfDay || !Map.TimeOfDaySeconds[z]) { // indoors it is always dark (maybe would be better to allow a special setting to have bright indoor places? Map.TimeOfDay[z] = NoTimeOfDay; // make indoors have no time of day setting until it is possible to make light sources change their surrounding "time of day" continue; } if (GameCycle > 0 && GameCycle % (CYCLES_PER_SECOND * Map.TimeOfDaySeconds[z]) == 0) { Map.TimeOfDay[z] += 1; if (Map.TimeOfDay[z] == MaxTimesOfDay) { Map.TimeOfDay[z] = 1; } #ifdef USE_OAML if (enableOAML && oaml && z == CurrentMapLayer) { // Time of day can change our main music loop, if the current playing track is set for this SetMusicCondition(OAML_CONDID_MAIN_LOOP, Map.TimeOfDay[z]); } #endif //update the sight of all units for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it) { CUnit *unit = *it; if ( unit && unit->IsAlive() && unit->MapLayer == z && ( ((Map.TimeOfDay[z] == MorningTimeOfDay || Map.TimeOfDay[z] == DuskTimeOfDay) && unit->Variable[DAYSIGHTRANGEBONUS_INDEX].Value != 0) // if has day sight bonus and is entering or exiting day || ((Map.TimeOfDay[z] == FirstWatchTimeOfDay || Map.TimeOfDay[z] == DawnTimeOfDay) && unit->Variable[NIGHTSIGHTRANGEBONUS_INDEX].Value != 0) // if has night sight bonus and is entering or exiting night ) ) { MapUnmarkUnitSight(*unit); UpdateUnitSightRange(*unit); MapMarkUnitSight(*unit); } } } } //Wyrmgus end //Wyrmgus start // if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && GameCycle > 0 && (GameCycle % (CYCLES_PER_SECOND * 60 * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled if (Preference.AutosaveMinutes != 0 && !IsNetworkGame() && !GrandStrategy && GameCycle > 0 && (GameCycle % (CYCLES_PER_MINUTE * Preference.AutosaveMinutes)) == 0) { // autosave every X minutes, if the option is enabled //Wyrmgus end UI.StatusLine.Set(_("Autosave")); //Wyrmgus start // SaveGame("autosave.sav"); CclCommand("if (RunSaveGame ~= nil) then RunSaveGame(\"autosave.sav\") end;"); //Wyrmgus end } } UpdateMessages(); // update messages ParticleManager.update(); // handle particles CheckMusicFinished(); // Check for next song if (FastForwardCycle <= GameCycle || !(GameCycle & 0x3f)) { WaitEventsOneFrame(); } if (!NetworkInSync) { NetworkRecover(); // recover network } }