Ticket #9: visualreplay-WIP-r15054.patch
File visualreplay-WIP-r15054.patch, 16.2 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/gui/session/selection_details.js
360 360 } 361 361 362 362 // Updates middle entity Selection Details Panel 363 function updateSelectionDetails( )363 function updateSelectionDetails(replay) 364 364 { 365 365 var supplementalDetailsPanel = Engine.GetGUIObjectByName("supplementalSelectionDetails"); 366 366 var detailsPanel = Engine.GetGUIObjectByName("selectionDetails"); … … 408 408 else 409 409 { 410 410 // Fill out commands panel for specific unit selected (or first unit of primary group) 411 updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection );411 updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection, replay); 412 412 // Show panels 413 413 supplementalDetailsPanel.hidden = false; 414 414 commandsPanel.hidden = false; -
binaries/data/mods/public/gui/session/unit_commands.js
824 824 trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch; 825 825 button_disableable = !Engine.HotkeyIsPressed("selection.remove"); 826 826 } 827 Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (batchTrainingCount > 0) ? batchTrainingCount : ""; 827 var batchOverlayText = Engine.GetGUIObjectByName("unit" + guiName + "Count[" + i + "]"); 828 if (batchOverlayText) 829 batchOverlayText.caption = (batchTrainingCount > 0) ? batchTrainingCount : ""; 828 830 } 829 831 830 832 // Walls have no cost defined. … … 1046 1048 * @param commandsPanel Reference to the "commandsPanel" GUI Object 1047 1049 * @param selection Array of currently selected entity IDs. 1048 1050 */ 1049 function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection )1051 function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection, replay) 1050 1052 { 1051 1053 // Panels that are active 1052 1054 var usedPanels = {}; … … 1059 1061 var simState = GetSimState(); 1060 1062 var playerState = simState.players[player]; 1061 1063 1062 if ( entState.player == player || g_DevSettings.controlAll)1064 if (replay || entState.player == player || g_DevSettings.controlAll) 1063 1065 { 1064 1066 if (selection.length > 1) 1065 1067 setupUnitPanel(SELECTION, usedPanels, entState, playerState, g_Selection.groups.getTemplateNames(), 1066 1068 function (entType, rightPressed) { changePrimarySelectionGroup(entType, rightPressed); } ); 1067 1069 1068 var commands = getEntityCommandsList(entState); 1069 if (commands.length) 1070 setupUnitPanel(COMMAND, usedPanels, entState, playerState, commands, 1071 function (item) { performCommand(entState.id, item.name); } ); 1070 if (!replay) 1071 { 1072 var commands = getEntityCommandsList(entState); 1073 if (commands.length) 1074 setupUnitPanel(COMMAND, usedPanels, entState, playerState, commands, 1075 function (item) { performCommand(entState.id, item.name); } ); 1076 } 1072 1077 1073 1078 if (entState.garrisonHolder) 1074 1079 { … … 1314 1319 var panel = Engine.GetGUIObjectByName("unit" + panelName + "Panel"); 1315 1320 if (usedPanels[panelName]) 1316 1321 panel.hidden = false; 1317 else 1322 else if (panel) 1318 1323 panel.hidden = true; 1319 1324 } 1320 1325 } … … 1323 1328 function hideUnitCommands() 1324 1329 { 1325 1330 for each (var panelName in g_unitPanels) 1326 Engine.GetGUIObjectByName("unit" + panelName + "Panel").hidden = true; 1331 { 1332 var panel = Engine.GetGUIObjectByName("unit" + panelName + "Panel"); 1333 if (panel) 1334 panel.hidden = true; 1335 } 1327 1336 } 1328 1337 1329 1338 // Get all of the available entities which can be trained by the selected entities -
source/gui/scripting/ScriptFunctions.cpp
150 150 return EntitySelection::PickEntitiesAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetPlayerID(), false, range); 151 151 } 152 152 153 std::vector<entity_id_t> PickEntitiesInRect(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x0, int y0, int x1, int y1) 154 { 155 return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, INVALID_PLAYER, false); 156 } 157 153 158 std::vector<entity_id_t> PickFriendlyEntitiesInRect(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x0, int y0, int x1, int y1, int player) 154 159 { 155 160 return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false); 156 161 } 157 162 163 std::vector<entity_id_t> PickEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate) 164 { 165 return PickEntitiesInRect(pCxPrivate, 0, 0, g_xres, g_yres); 166 } 167 158 168 std::vector<entity_id_t> PickFriendlyEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate, int player) 159 169 { 160 170 return PickFriendlyEntitiesInRect(pCxPrivate, 0, 0, g_xres, g_yres, player); 161 171 } 162 172 173 std::vector<entity_id_t> PickSimilarEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) 174 { 175 return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, INVALID_PLAYER, includeOffScreen, matchRank, false, allowFoundations); 176 } 177 163 178 std::vector<entity_id_t> PickSimilarFriendlyEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) 164 179 { 165 180 return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetPlayerID(), includeOffScreen, matchRank, false, allowFoundations); … … 867 882 868 883 // Entity picking 869 884 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, &PickEntitiesAtPoint>("PickEntitiesAtPoint"); 885 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, int, &PickEntitiesInRect>("PickEntitiesInRect"); 870 886 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, int, int, int, int, &PickFriendlyEntitiesInRect>("PickFriendlyEntitiesInRect"); 887 scriptInterface.RegisterFunction<std::vector<entity_id_t>, &PickEntitiesOnScreen>("PickEntitiesOnScreen"); 871 888 scriptInterface.RegisterFunction<std::vector<entity_id_t>, int, &PickFriendlyEntitiesOnScreen>("PickFriendlyEntitiesOnScreen"); 889 scriptInterface.RegisterFunction<std::vector<entity_id_t>, std::string, bool, bool, bool, &PickSimilarEntities>("PickSimilarEntities"); 872 890 scriptInterface.RegisterFunction<std::vector<entity_id_t>, std::string, bool, bool, bool, &PickSimilarFriendlyEntities>("PickSimilarFriendlyEntities"); 873 891 scriptInterface.RegisterFunction<CFixedVector3D, int, int, &GetTerrainAtScreenPoint>("GetTerrainAtScreenPoint"); 874 892 -
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 … … 469 469 470 470 471 471 472 CNetReplayTurnManager::CNetReplayTurnManager(CSimulation2& simulation, IReplayLogger& replay) : 473 CNetLocalTurnManager(simulation, replay) 474 { 475 } 476 477 void CNetReplayTurnManager::StoreReplayCommand(u32 turn, int player, const std::string& command) 478 { 479 m_ReplayCommands[turn][player].push_back(command); 480 } 481 482 void CNetReplayTurnManager::NotifyFinishedUpdate(u32 turn) 483 { 484 DoTurn(turn); 485 } 486 487 void CNetReplayTurnManager::DoTurn(u32 turn) 488 { 489 std::map<int, std::vector<std::string> > playerCommands = m_ReplayCommands[turn]; 490 std::map<int, std::vector<std::string> >::iterator it; 491 for (it = playerCommands.begin(); it != playerCommands.end(); ++it) 492 { 493 int player = it->first; 494 for (size_t i = 0; i < it->second.size(); ++i) 495 { 496 CScriptValRooted data = m_Simulation2.GetScriptInterface().ParseJSON(it->second[i]); 497 AddCommand(m_ClientId, player, data, m_CurrentTurn + 1); 498 } 499 } 500 } 501 502 503 504 472 505 CNetServerTurnManager::CNetServerTurnManager(CNetServerWorker& server) : 473 506 m_NetServer(server), m_ReadyTurn(1), m_TurnLength(DEFAULT_TURN_LENGTH_MP) 474 507 { -
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; … … 232 233 virtual void NotifyFinishedUpdate(u32 turn); 233 234 }; 234 235 236 /** 237 * Implementation of CNetTurnManager for replay games. 238 */ 239 class CNetReplayTurnManager : public CNetLocalTurnManager 240 { 241 public: 242 CNetReplayTurnManager(CSimulation2& simulation, IReplayLogger& replay); 235 243 244 void StoreReplayCommand(u32 turn, int player, const std::string& command); 245 246 protected: 247 virtual void NotifyFinishedUpdate(u32 turn); 248 249 void DoTurn(u32 turn); 250 251 std::map<u32, std::map<int, std::vector<std::string> > > m_ReplayCommands; 252 }; 253 254 236 255 /** 237 256 * The server-side counterpart to CNetClientTurnManager. 238 257 * 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
850 850 } 851 851 852 852 bool Autostart(const CmdLineArgs& args); 853 bool VisualReplay(const CmdLineArgs& args); 853 854 854 855 void Init(const CmdLineArgs& args, int flags) 855 856 { … … 1017 1018 1018 1019 try 1019 1020 { 1020 if (! Autostart(args))1021 if (!VisualReplay(args) && !Autostart(args)) 1021 1022 { 1022 1023 const bool setup_gui = ((flags & INIT_NO_GUI) == 0); 1023 1024 // We only want to display the splash screen at startup … … 1059 1060 g_DoRenderCursor = RenderingState; 1060 1061 } 1061 1062 1063 bool VisualReplay(const CmdLineArgs& args) 1064 { 1065 CStr replayPath = args.Get("replay-visual"); 1066 if (!replayPath.empty()) 1067 { 1068 g_Game = new CGame(false, false); 1069 1070 g_Game->SetPlayerID(1); 1071 g_Game->StartReplay(replayPath); 1072 1073 // TODO: Non progressive load can fail - need a decent way to handle this 1074 LDR_NonprogressiveLoad(); 1075 1076 PSRETURN ret = g_Game->ReallyStartGame(); 1077 ENSURE(ret == PSRETURN_OK); 1078 1079 InitPs(true, L"page_replay.xml", g_GUI->GetScriptInterface().get(), JSVAL_VOID); 1080 return true; 1081 } 1082 1083 return false; 1084 } 1085 1062 1086 bool Autostart(const CmdLineArgs& args) 1063 1087 { 1064 1088 /* -
source/ps/Replay.cpp
129 129 g_ProfileViewer.AddRootTable(g_ScriptStatsTable); 130 130 g_ScriptRuntime = ScriptInterface::CreateRuntime(384 * 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'