Ticket #9: visualreplay-WIP-r14723.patch
File visualreplay-WIP-r14723.patch, 16.2 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/gui/session/selection_details.js
298 298 } 299 299 300 300 // Updates middle entity Selection Details Panel 301 function updateSelectionDetails( )301 function updateSelectionDetails(replay) 302 302 { 303 303 var supplementalDetailsPanel = Engine.GetGUIObjectByName("supplementalSelectionDetails"); 304 304 var detailsPanel = Engine.GetGUIObjectByName("selectionDetails"); … … 340 340 commandsPanel.hidden = false; 341 341 342 342 // Fill out commands panel for specific unit selected (or first unit of primary group) 343 updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection );343 updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection, replay); 344 344 } -
binaries/data/mods/public/gui/session/unit_commands.js
779 779 trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch; 780 780 button_disableable = !Engine.HotkeyIsPressed("selection.remove"); 781 781 } 782 Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (batchTrainingCount > 0) ? batchTrainingCount : ""; 782 var batchOverlayText = Engine.GetGUIObjectByName("unit" + guiName + "Count[" + i + "]"); 783 if (batchOverlayText) 784 batchOverlayText.caption = (batchTrainingCount > 0) ? batchTrainingCount : ""; 783 785 } 784 786 785 787 // Walls have no cost defined. … … 1001 1003 * @param commandsPanel Reference to the "commandsPanel" GUI Object 1002 1004 * @param selection Array of currently selected entity IDs. 1003 1005 */ 1004 function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection )1006 function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection, replay) 1005 1007 { 1006 1008 // Panels that are active 1007 1009 var usedPanels = {}; … … 1014 1016 var simState = GetSimState(); 1015 1017 var playerState = simState.players[player]; 1016 1018 1017 if ( entState.player == player || g_DevSettings.controlAll)1019 if (replay || entState.player == player || g_DevSettings.controlAll) 1018 1020 { 1019 1021 if (selection.length > 1) 1020 1022 setupUnitPanel(SELECTION, usedPanels, entState, playerState, g_Selection.groups.getTemplateNames(), 1021 1023 function (entType, rightPressed) { changePrimarySelectionGroup(entType, rightPressed); } ); 1022 1024 1023 var commands = getEntityCommandsList(entState); 1024 if (commands.length) 1025 setupUnitPanel(COMMAND, usedPanels, entState, playerState, commands, 1026 function (item) { performCommand(entState.id, item.name); } ); 1025 if (!replay) 1026 { 1027 var commands = getEntityCommandsList(entState); 1028 if (commands.length) 1029 setupUnitPanel(COMMAND, usedPanels, entState, playerState, commands, 1030 function (item) { performCommand(entState.id, item.name); } ); 1031 } 1027 1032 1028 1033 if (entState.garrisonHolder) 1029 1034 { … … 1236 1241 var panel = Engine.GetGUIObjectByName("unit" + panelName + "Panel"); 1237 1242 if (usedPanels[panelName]) 1238 1243 panel.hidden = false; 1239 else 1244 else if (panel) 1240 1245 panel.hidden = true; 1241 1246 } 1242 1247 } … … 1245 1250 function hideUnitCommands() 1246 1251 { 1247 1252 for each (var panelName in g_unitPanels) 1248 Engine.GetGUIObjectByName("unit" + panelName + "Panel").hidden = true; 1253 { 1254 var panel = Engine.GetGUIObjectByName("unit" + panelName + "Panel"); 1255 if (panel) 1256 panel.hidden = true; 1257 } 1249 1258 } 1250 1259 1251 1260 // Get all of the available entities which can be trained by the selected entities -
source/gui/scripting/ScriptFunctions.cpp
153 153 return EntitySelection::PickEntitiesAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetPlayerID(), false, range); 154 154 } 155 155 156 std::vector<entity_id_t> PickEntitiesInRect(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x0, int y0, int x1, int y1) 157 { 158 return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, INVALID_PLAYER, false); 159 } 160 156 161 std::vector<entity_id_t> PickFriendlyEntitiesInRect(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x0, int y0, int x1, int y1, int player) 157 162 { 158 163 return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false); 159 164 } 160 165 166 std::vector<entity_id_t> PickEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate) 167 { 168 return PickEntitiesInRect(pCxPrivate, 0, 0, g_xres, g_yres); 169 } 170 161 171 std::vector<entity_id_t> PickFriendlyEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate, int player) 162 172 { 163 173 return PickFriendlyEntitiesInRect(pCxPrivate, 0, 0, g_xres, g_yres, player); 164 174 } 165 175 176 std::vector<entity_id_t> PickSimilarEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) 177 { 178 return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, INVALID_PLAYER, includeOffScreen, matchRank, false, allowFoundations); 179 } 180 166 181 std::vector<entity_id_t> PickSimilarFriendlyEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) 167 182 { 168 183 return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetPlayerID(), includeOffScreen, matchRank, false, allowFoundations); … … 810 825 811 826 // Entity picking 812 827 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, &PickEntitiesAtPoint>("PickEntitiesAtPoint"); 828 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, int, &PickEntitiesInRect>("PickEntitiesInRect"); 813 829 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, int, int, &PickFriendlyEntitiesInRect>("PickFriendlyEntitiesInRect"); 830 scriptInterface.RegisterFunction<std::vector<entity_id_t>, &PickEntitiesOnScreen>("PickEntitiesOnScreen"); 814 831 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, &PickFriendlyEntitiesOnScreen>("PickFriendlyEntitiesOnScreen"); 832 scriptInterface.RegisterFunction<std::vector<entity_id_t>, std::string, bool, bool, bool, &PickSimilarEntities>("PickSimilarEntities"); 815 833 scriptInterface.RegisterFunction<std::vector<entity_id_t>, std::string, bool, bool, bool, &PickSimilarFriendlyEntities>("PickSimilarFriendlyEntities"); 816 834 scriptInterface.RegisterFunction<CFixedVector3D, int, int, &GetTerrainAtScreenPoint>("GetTerrainAtScreenPoint"); 817 835 -
source/network/NetTurnManager.cpp
38 38 #include <iomanip> 39 39 40 40 static const int DEFAULT_TURN_LENGTH_MP = 500; 41 static const int DEFAULT_TURN_LENGTH_SP = 200;41 static const int DEFAULT_TURN_LENGTH_SP = 500; 42 42 43 43 static const int COMMAND_DELAY = 2; 44 44 … … 464 464 465 465 466 466 467 CNetReplayTurnManager::CNetReplayTurnManager(CSimulation2& simulation, IReplayLogger& replay) : 468 CNetLocalTurnManager(simulation, replay) 469 { 470 } 471 472 void CNetReplayTurnManager::StoreReplayCommand(u32 turn, int player, const std::string& command) 473 { 474 m_ReplayCommands[turn][player].push_back(command); 475 } 476 477 void CNetReplayTurnManager::NotifyFinishedUpdate(u32 turn) 478 { 479 DoTurn(turn); 480 } 481 482 void CNetReplayTurnManager::DoTurn(u32 turn) 483 { 484 std::map<int, std::vector<std::string> > playerCommands = m_ReplayCommands[turn]; 485 std::map<int, std::vector<std::string> >::iterator it; 486 for (it = playerCommands.begin(); it != playerCommands.end(); ++it) 487 { 488 int player = it->first; 489 for (size_t i = 0; i < it->second.size(); ++i) 490 { 491 CScriptValRooted data = m_Simulation2.GetScriptInterface().ParseJSON(it->second[i]); 492 AddCommand(m_ClientId, player, data, m_CurrentTurn + 1); 493 } 494 } 495 } 496 497 498 499 467 500 CNetServerTurnManager::CNetServerTurnManager(CNetServerWorker& server) : 468 501 m_NetServer(server), m_ReadyTurn(1), m_TurnLength(DEFAULT_TURN_LENGTH_MP) 469 502 { -
source/network/NetTurnManager.h
22 22 23 23 #include <list> 24 24 #include <map> 25 #include <vector> 25 26 26 27 class CNetServerWorker; 27 28 class CNetClient; … … 227 228 virtual void NotifyFinishedUpdate(u32 turn); 228 229 }; 229 230 231 /** 232 * Implementation of CNetTurnManager for replay games. 233 */ 234 class CNetReplayTurnManager : public CNetLocalTurnManager 235 { 236 public: 237 CNetReplayTurnManager(CSimulation2& simulation, IReplayLogger& replay); 230 238 239 void StoreReplayCommand(u32 turn, int player, const std::string& command); 240 241 protected: 242 virtual void NotifyFinishedUpdate(u32 turn); 243 244 void DoTurn(u32 turn); 245 246 std::map<u32, std::map<int, std::vector<std::string> > > m_ReplayCommands; 247 }; 248 249 231 250 /** 232 251 * The server-side counterpart to CNetClientTurnManager. 233 252 * Records the turn state of each client, and sends turn advancement messages -
source/ps/Game.cpp
62 62 * Constructor 63 63 * 64 64 **/ 65 CGame::CGame(bool disableGraphics ):65 CGame::CGame(bool disableGraphics, bool replayLog): 66 66 m_World(new CWorld(this)), 67 67 m_Simulation2(new CSimulation2(&m_World->GetUnitManager(), g_ScriptRuntime, m_World->GetTerrain())), 68 68 m_GameView(disableGraphics ? NULL : new CGameView(this)), … … 70 70 m_Paused(false), 71 71 m_SimRate(1.0f), 72 72 m_PlayerID(-1), 73 m_IsSavedGame(false) 73 m_IsSavedGame(false), 74 m_IsReplay(false), 75 m_ReplayStream(NULL) 74 76 { 75 m_ReplayLogger = new CReplayLogger(m_Simulation2->GetScriptInterface());76 77 // TODO: should use CDummyReplayLogger unless activated by cmd-line arg, perhaps? 78 if (replayLog) 79 m_ReplayLogger = new CReplayLogger(m_Simulation2->GetScriptInterface()); 80 else 81 m_ReplayLogger = new CDummyReplayLogger(); 77 82 78 83 // Need to set the CObjectManager references after various objects have 79 84 // been initialised, so do it here rather than via the initialisers above. … … 100 105 delete m_Simulation2; 101 106 delete m_World; 102 107 delete m_ReplayLogger; 108 delete m_ReplayStream; 103 109 } 104 110 105 111 void CGame::SetTurnManager(CNetTurnManager* turnManager) … … 170 176 if (m_IsSavedGame) 171 177 RegMemFun(this, &CGame::LoadInitialState, L"Loading game", 1000); 172 178 179 if (m_IsReplay) 180 RegMemFun(this, &CGame::LoadReplayData, L"Loading replay data", 1000); 181 173 182 LDR_EndRegistering(); 174 183 } 175 184 … … 193 202 return 0; 194 203 } 195 204 205 int CGame::LoadReplayData() 206 { 207 ENSURE(m_IsReplay); 208 ENSURE(!m_ReplayPath.empty()); 209 210 CNetReplayTurnManager* replayTurnMgr = static_cast<CNetReplayTurnManager*>(GetTurnManager()); 211 212 u32 currentTurn = 0; 213 std::string type; 214 while ((*m_ReplayStream >> type).good()) 215 { 216 if (type == "turn") 217 { 218 u32 turn = 0; 219 u32 turnLength = 0; 220 *m_ReplayStream >> turn >> turnLength; 221 ENSURE(turn == currentTurn); 222 } 223 else if (type == "cmd") 224 { 225 int player; 226 *m_ReplayStream >> player; 227 228 std::string line; 229 std::getline(*m_ReplayStream, line); 230 replayTurnMgr->StoreReplayCommand(currentTurn, player, line); 231 } 232 else if (type == "hash" || type == "hash-quick") 233 { 234 // Ignored for now 235 std::string replayHash; 236 *m_ReplayStream >> replayHash; 237 } 238 else if (type == "end") 239 { 240 currentTurn++; 241 } 242 else 243 { 244 CancelLoad(L"Failed to load replay data (unrecognized content)"); 245 } 246 } 247 m_FinalReplayTurn = currentTurn + 1; 248 249 return 0; 250 } 251 252 void CGame::StartReplay(const std::string& replayPath) 253 { 254 m_IsReplay = true; 255 256 SetTurnManager(new CNetReplayTurnManager(*m_Simulation2, GetReplayLogger())); 257 258 m_ReplayPath = replayPath; 259 m_ReplayStream = new std::ifstream(m_ReplayPath.c_str()); 260 ENSURE(m_ReplayStream->good()); 261 262 std::string type; 263 ENSURE((*m_ReplayStream >> type).good() && type == "start"); 264 265 std::string line; 266 std::getline(*m_ReplayStream, line); 267 CScriptValRooted attribs = m_Simulation2->GetScriptInterface().ParseJSON(line); 268 StartGame(attribs, ""); 269 } 270 196 271 /** 197 272 * Game initialization has been completed. Set game started flag and start the session. 198 273 * … … 306 381 g_GUI->SendEventToAll("SimulationUpdate"); 307 382 } 308 383 384 if (m_IsReplay && m_TurnManager->GetCurrentTurn() == m_FinalReplayTurn) 385 g_GUI->SendEventToAll("ReplayFinished"); 386 309 387 GetView()->GetLOSTexture().MakeDirty(); 310 388 } 311 389 -
source/ps/Game.h
19 19 #define INCLUDED_GAME 20 20 21 21 #include "ps/Errors.h" 22 #include <map> 22 23 #include <vector> 23 24 24 25 #include "scriptinterface/ScriptVal.h" … … 65 66 CNetTurnManager* m_TurnManager; 66 67 67 68 public: 68 CGame(bool disableGraphics = false );69 CGame(bool disableGraphics = false, bool replayLog = true); 69 70 ~CGame(); 70 71 71 72 /** … … 76 77 void StartGame(const CScriptValRooted& attribs, const std::string& savedState); 77 78 PSRETURN ReallyStartGame(); 78 79 80 void StartReplay(const std::string& replayPath); 81 79 82 /** 80 83 * Periodic heartbeat that controls the process. performs all per-frame updates. 81 84 * Simulation update is called and game status update is called. … … 171 174 int LoadInitialState(); 172 175 std::string m_InitialSavedState; // valid between RegisterInit and LoadInitialState 173 176 bool m_IsSavedGame; // true if loading a saved game; false for a new game 177 178 int LoadReplayData(); 179 std::string m_ReplayPath; 180 bool m_IsReplay; 181 std::istream* m_ReplayStream; 182 u32 m_FinalReplayTurn; 174 183 }; 175 184 176 185 extern CGame *g_Game; -
source/ps/GameSetup/GameSetup.cpp
843 843 } 844 844 845 845 bool Autostart(const CmdLineArgs& args); 846 bool VisualReplay(const CmdLineArgs& args); 846 847 847 848 void Init(const CmdLineArgs& args, int flags) 848 849 { … … 1012 1013 1013 1014 try 1014 1015 { 1015 if (! Autostart(args))1016 if (!VisualReplay(args) && !Autostart(args)) 1016 1017 { 1017 1018 const bool setup_gui = ((flags & INIT_NO_GUI) == 0); 1018 1019 // We only want to display the splash screen at startup … … 1054 1055 g_DoRenderCursor = RenderingState; 1055 1056 } 1056 1057 1058 bool VisualReplay(const CmdLineArgs& args) 1059 { 1060 CStr replayPath = args.Get("replay-visual"); 1061 if (!replayPath.empty()) 1062 { 1063 g_Game = new CGame(false, false); 1064 1065 g_Game->SetPlayerID(1); 1066 g_Game->StartReplay(replayPath); 1067 1068 // TODO: Non progressive load can fail - need a decent way to handle this 1069 LDR_NonprogressiveLoad(); 1070 1071 PSRETURN ret = g_Game->ReallyStartGame(); 1072 ENSURE(ret == PSRETURN_OK); 1073 1074 InitPs(true, L"page_replay.xml", g_GUI->GetScriptInterface().get(), JSVAL_VOID); 1075 return true; 1076 } 1077 1078 return false; 1079 } 1080 1057 1081 bool Autostart(const CmdLineArgs& args) 1058 1082 { 1059 1083 /* -
source/ps/Replay.cpp
129 129 g_ProfileViewer.AddRootTable(g_ScriptStatsTable); 130 130 g_ScriptRuntime = ScriptInterface::CreateRuntime(128 * 1024 * 1024); 131 131 132 CGame game(true );132 CGame game(true, false); 133 133 g_Game = &game; 134 134 135 135 // Need some stuff for terrain movement costs: -
source/simulation2/helpers/Selection.cpp
212 212 213 213 // Ignore entities hidden by LOS (or otherwise hidden, e.g. when not IsInWorld) 214 214 // In this case, the checking is done to avoid selecting garrisoned units 215 if ( cmpRangeManager->GetLosVisibility(handle, owner) == ICmpRangeManager::VIS_HIDDEN)215 if (owner != INVALID_PLAYER && cmpRangeManager->GetLosVisibility(handle, owner) == ICmpRangeManager::VIS_HIDDEN) 216 216 continue; 217 217 218 218 // Ignore entities not owned by 'owner'