Advertisement
Guest User

Untitled

a guest
May 21st, 2016
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.17 KB | None | 0 0
  1. Index: binaries/data/mods/public/gui/session/input.js
  2. ===================================================================
  3. --- binaries/data/mods/public/gui/session/input.js (revision 18212)
  4. +++ binaries/data/mods/public/gui/session/input.js (working copy)
  5. @@ -38,6 +38,9 @@
  6. var mouseY = 0;
  7. var mouseIsOverObject = false;
  8.  
  9. + // used for remembering mouse coordinates at start of drag operations
  10. +var dragStart;
  11. +
  12. // Number of pixels the mouse can move before the action is considered a drag
  13. var maxDragDelta = 4;
  14.  
  15. @@ -53,36 +56,48 @@
  16. var doublePressTimer = 0;
  17. var prevHotkey = 0;
  18.  
  19. +// Camera jumping: when the user presses a hotkey the current camera location is marked.
  20. +// When they press another hotkey the camera jumps back to that position. If the camera is already roughly at that location,
  21. +// jump back to where it was previously.
  22. +var jumpCameraPositions = [];
  23. +var jumpCameraLast;
  24. +var jumpCameraDistanceThreshold = Engine.ConfigDB_GetValue("user", "gui.session.camerajump.threshold");
  25. +
  26. +// Batch training:
  27. +// When the user shift-clicks, we set these variables and switch to INPUT_BATCHTRAINING
  28. +// When the user releases shift, or clicks on a different training button, we create the batched units
  29. +var batchTrainingEntities;
  30. +var batchTrainingType;
  31. +var batchTrainingCount;
  32. +var batchTrainingEntityAllowedCount;
  33. +const batchIncrementSize = 5;
  34. +
  35. +var lastIdleUnit = 0;
  36. +var currIdleClass = 0;
  37. +var lastIdleType = undefined;
  38. +
  39. function updateCursorAndTooltip()
  40. {
  41. - var cursorSet = false;
  42. - var tooltipSet = false;
  43. - var informationTooltip = Engine.GetGUIObjectByName("informationTooltip");
  44. - if (!mouseIsOverObject && (inputState == INPUT_NORMAL || inputState == INPUT_PRESELECTEDACTION))
  45. +
  46. + let informationTooltip = Engine.GetGUIObjectByName("informationTooltip");
  47. +
  48. + let action = determineAction(mouseX, mouseY);
  49. + if (action && action.cursor && !mouseIsOverObject &&
  50. + (inputState == INPUT_NORMAL || inputState == INPUT_PRESELECTEDACTION))
  51. + Engine.SetCursor(action.cursor);
  52. + else
  53. + Engine.SetCursor("arrow-default");
  54. +
  55. + if (action && action.tooltip && !mouseIsOverObject &&
  56. + (inputState == INPUT_NORMAL || inputState == INPUT_PRESELECTEDACTION))
  57. {
  58. - let action = determineAction(mouseX, mouseY);
  59. - if (action)
  60. - {
  61. - if (action.cursor)
  62. - {
  63. - Engine.SetCursor(action.cursor);
  64. - cursorSet = true;
  65. - }
  66. - if (action.tooltip)
  67. - {
  68. - tooltipSet = true;
  69. - informationTooltip.caption = action.tooltip;
  70. - informationTooltip.hidden = false;
  71. - }
  72. - }
  73. + informationTooltip.caption = action.tooltip;
  74. + informationTooltip.hidden = false;
  75. }
  76. -
  77. - if (!cursorSet)
  78. - Engine.SetCursor("arrow-default");
  79. - if (!tooltipSet)
  80. + else
  81. informationTooltip.hidden = true;
  82.  
  83. - var placementTooltip = Engine.GetGUIObjectByName("placementTooltip");
  84. + let placementTooltip = Engine.GetGUIObjectByName("placementTooltip");
  85. if (placementSupport.tooltipMessage)
  86. placementTooltip.sprite = placementSupport.tooltipError ? "BackgroundErrorTooltip" : "BackgroundInformationTooltip";
  87.  
  88. @@ -100,7 +115,7 @@
  89. {
  90. if (placementSupport.template && placementSupport.position)
  91. {
  92. - var result = Engine.GuiInterfaceCall("SetBuildingPlacementPreview", {
  93. + let result = Engine.GuiInterfaceCall("SetBuildingPlacementPreview", {
  94. "template": placementSupport.template,
  95. "x": placementSupport.position.x,
  96. "z": placementSupport.position.z,
  97. @@ -116,13 +131,13 @@
  98. {
  99. if (result.message && result.parameters)
  100. {
  101. - var message = result.message;
  102. + let message = result.message;
  103. if (result.translateMessage)
  104. if (result.pluralMessage)
  105. - message = translatePlural(result.message, result.pluralMessage, result.pluralCount);
  106. + message = translatePlural(message, result.pluralMessage, result.pluralCount);
  107. else
  108. message = translate(message);
  109. - var parameters = result.parameters;
  110. + let parameters = result.parameters;
  111. if (result.translateParameters)
  112. translateObjectKeys(parameters, result.translateParameters);
  113. placementSupport.tooltipMessage = sprintf(message, parameters);
  114. @@ -134,14 +149,14 @@
  115. {
  116. // building can be placed here, and has an attack
  117. // show the range advantage in the tooltip
  118. - var cmd = {
  119. + let cmd = {
  120. "x": placementSupport.position.x,
  121. "z": placementSupport.position.z,
  122. "range": placementSupport.attack.Ranged.maxRange,
  123. "elevationBonus": placementSupport.attack.Ranged.elevationBonus,
  124. };
  125. - var averageRange = Math.round(Engine.GuiInterfaceCall("GetAverageRangeForBuildings", cmd) - cmd.range);
  126. - var range = Math.round(cmd.range);
  127. + let averageRange = Math.round(Engine.GuiInterfaceCall("GetAverageRangeForBuildings", cmd) - cmd.range);
  128. + let range = Math.round(cmd.range);
  129. placementSupport.tooltipMessage = sprintf(translatePlural("Basic range: %(range)s meter", "Basic range: %(range)s meters", range), { "range": range }) + "\n" +
  130. sprintf(translatePlural("Average bonus range: %(range)s meter", "Average bonus range: %(range)s meters", averageRange), { "range": averageRange });
  131. }
  132. @@ -156,8 +171,8 @@
  133. placementSupport.wallSnapEntities = Engine.PickSimilarPlayerEntities(
  134. placementSupport.wallSet.templates.tower,
  135. placementSupport.wallSnapEntitiesIncludeOffscreen,
  136. - true, // require exact template match
  137. - true // include foundations
  138. + true, // require exact template match
  139. + true // include foundations
  140. );
  141.  
  142. return Engine.GuiInterfaceCall("SetWallPlacementPreview", {
  143. @@ -174,7 +189,7 @@
  144.  
  145. function findGatherType(gatherer, supply)
  146. {
  147. - if (!("resourceGatherRates" in gatherer) || !gatherer.resourceGatherRates || !supply)
  148. + if (!gatherer.resourceGatherRates || !supply)
  149. return undefined;
  150. if (gatherer.resourceGatherRates[supply.type.generic+"."+supply.type.specific])
  151. return supply.type.specific;
  152. @@ -185,11 +200,11 @@
  153.  
  154. function getActionInfo(action, target)
  155. {
  156. - var simState = GetSimState();
  157. - var selection = g_Selection.toList();
  158. + let simState = GetSimState();
  159. + let selection = g_Selection.toList();
  160.  
  161. // If the selection doesn't exist, no action
  162. - var entState = GetEntityState(selection[0]);
  163. + let entState = GetEntityState(selection[0]);
  164. if (!entState)
  165. return { "possible": false };
  166.  
  167. @@ -197,8 +212,8 @@
  168. {
  169. if (action == "set-rallypoint")
  170. {
  171. - var cursor = "";
  172. - var data = { "command": "walk" };
  173. + let cursor = "";
  174. + let data = { "command": "walk" };
  175. if (Engine.HotkeyIsPressed("session.attackmove"))
  176. {
  177. data.command = "attack-walk";
  178. @@ -214,21 +229,21 @@
  179. // Look at the first targeted entity
  180. // (TODO: maybe we eventually want to look at more, and be more context-sensitive?
  181. // e.g. prefer to attack an enemy unit, even if some friendly units are closer to the mouse)
  182. - var targetState = GetExtendedEntityState(target);
  183. + let targetState = GetExtendedEntityState(target);
  184.  
  185. // Check if the target entity is a resource, dropsite, foundation, or enemy unit.
  186. // Check if any entities in the selection can gather the requested resource,
  187. // can return to the dropsite, can build the foundation, or can attack the enemy
  188. - for each (var entityID in selection)
  189. + for (let entityID of selection)
  190. {
  191. - var entState = GetExtendedEntityState(entityID);
  192. + let entState = GetExtendedEntityState(entityID);
  193. if (!entState)
  194. continue;
  195.  
  196. if (unitActions[action] && unitActions[action].getActionInfo)
  197. {
  198. - var r = unitActions[action].getActionInfo(entState, targetState, simState);
  199. - if (r) // return true if it's possible for one of the entities
  200. + let r = unitActions[action].getActionInfo(entState, targetState, simState);
  201. + if (r && r.possible) // return true if it's possible for one of the entities
  202. return r;
  203. }
  204. }
  205. @@ -240,7 +255,7 @@
  206. */
  207. function determineAction(x, y, fromMinimap)
  208. {
  209. - var selection = g_Selection.toList();
  210. + let selection = g_Selection.toList();
  211.  
  212. // No action if there's no selection
  213. if (!selection.length)
  214. @@ -250,13 +265,13 @@
  215. }
  216.  
  217. // If the selection doesn't exist, no action
  218. - var entState = GetEntityState(selection[0]);
  219. + let entState = GetEntityState(selection[0]);
  220. if (!entState)
  221. return undefined;
  222.  
  223. // If the selection isn't friendly units, no action
  224. - var allOwnedByPlayer = selection.every(function(ent) {
  225. - var entState = GetEntityState(ent);
  226. + let allOwnedByPlayer = selection.every(function(ent) {
  227. + let entState = GetEntityState(ent);
  228. return entState && entState.player == g_ViewedPlayer;
  229. });
  230.  
  231. @@ -263,10 +278,10 @@
  232. if (!g_DevSettings.controlAll && !allOwnedByPlayer)
  233. return undefined;
  234.  
  235. - var target = undefined;
  236. + let target = undefined;
  237. if (!fromMinimap)
  238. {
  239. - var ent = Engine.PickEntityAtPoint(x, y);
  240. + let ent = Engine.PickEntityAtPoint(x, y);
  241. if (ent != INVALID_ENTITY)
  242. target = ent;
  243. }
  244. @@ -274,17 +289,17 @@
  245. // decide between the following ordered actions
  246. // if two actions are possible, the first one is taken
  247. // so the most specific should appear first
  248. - var actions = Object.keys(unitActions).slice();
  249. + let actions = Object.keys(unitActions).slice();
  250. actions.sort((a, b) => unitActions[a].specificness - unitActions[b].specificness);
  251.  
  252. - var actionInfo = undefined;
  253. + let actionInfo = undefined;
  254. if (preSelectedAction != ACTION_NONE)
  255. {
  256. - for (var action of actions)
  257. + for (let action of actions)
  258. {
  259. if (unitActions[action].preSelectedActionCheck)
  260. {
  261. - var r = unitActions[action].preSelectedActionCheck(target, selection);
  262. + let r = unitActions[action].preSelectedActionCheck(target, selection);
  263. if (r)
  264. return r;
  265. }
  266. @@ -292,21 +307,21 @@
  267. return { "type": "none", "cursor": "", "target": target };
  268. }
  269.  
  270. - for (var action of actions)
  271. + for (let action of actions)
  272. {
  273. if (unitActions[action].hotkeyActionCheck)
  274. {
  275. - var r = unitActions[action].hotkeyActionCheck(target, selection);
  276. + let r = unitActions[action].hotkeyActionCheck(target, selection);
  277. if (r)
  278. return r;
  279. }
  280. }
  281.  
  282. - for (var action of actions)
  283. + for (let action of actions)
  284. {
  285. if (unitActions[action].actionCheck)
  286. {
  287. - var r = unitActions[action].actionCheck(target, selection);
  288. + let r = unitActions[action].actionCheck(target, selection);
  289. if (r)
  290. return r;
  291. }
  292. @@ -315,9 +330,6 @@
  293. return { "type": "none", "cursor": "", "target": target };
  294. }
  295.  
  296. -
  297. -var dragStart; // used for remembering mouse coordinates at start of drag operations
  298. -
  299. function tryPlaceBuilding(queued)
  300. {
  301. if (placementSupport.mode !== "building")
  302. @@ -337,7 +349,7 @@
  303. return false;
  304. }
  305.  
  306. - var selection = g_Selection.toList();
  307. + let selection = g_Selection.toList();
  308.  
  309. // Start the construction
  310. Engine.PostNetworkCommand({
  311. @@ -373,7 +385,7 @@
  312. return false;
  313. }
  314.  
  315. - var wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...)
  316. + let wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...)
  317. if (!(wallPlacementInfo === false || typeof(wallPlacementInfo) === "object"))
  318. {
  319. error(sprintf("[%(functionName)s] Unexpected return value from %(function2Name)s: '%(value)s'; expected either 'false' or 'object'", {
  320. @@ -387,8 +399,8 @@
  321. if (!wallPlacementInfo)
  322. return false;
  323.  
  324. - var selection = g_Selection.toList();
  325. - var cmd = {
  326. + let selection = g_Selection.toList();
  327. + let cmd = {
  328. "type": "construct-wall",
  329. "autorepair": true,
  330. "autocontinue": true,
  331. @@ -403,22 +415,15 @@
  332. // make sure that there's at least one non-tower entity getting built, to prevent silly edge cases where the start and end
  333. // point are too close together for the algorithm to place a wall segment inbetween, and only the towers are being previewed
  334. // (this is somewhat non-ideal and hardcode-ish)
  335. - var hasWallSegment = false;
  336. for (let piece of cmd.pieces)
  337. {
  338. if (piece.template != cmd.wallSet.templates.tower) // TODO: hardcode-ish :(
  339. {
  340. - hasWallSegment = true;
  341. - break;
  342. + Engine.PostNetworkCommand(cmd);
  343. + Engine.GuiInterfaceCall("PlaySound", { "name": "order_repair", "entity": selection[0] });
  344. + return true;
  345. }
  346. }
  347. -
  348. - if (hasWallSegment)
  349. - {
  350. - Engine.PostNetworkCommand(cmd);
  351. - Engine.GuiInterfaceCall("PlaySound", { "name": "order_repair", "entity": selection[0] });
  352. - }
  353. -
  354. return true;
  355. }
  356.  
  357. @@ -426,13 +431,10 @@
  358. // The coordinates [x0, y0, x1, y1] are returned for further use.
  359. function updateBandbox(bandbox, ev, hidden)
  360. {
  361. - var x0 = dragStart[0];
  362. - var y0 = dragStart[1];
  363. - var x1 = ev.x;
  364. - var y1 = ev.y;
  365. - // normalize the orientation of the rectangle
  366. - if (x0 > x1) { let t = x0; x0 = x1; x1 = t; }
  367. - if (y0 > y1) { let t = y0; y0 = y1; y1 = t; }
  368. + let x0 = Math.min(dragStart[0], ev.x);
  369. + let y0 = Math.min(dragStart[1], ev.y);
  370. + let x1 = Math.max(dragStart[0], ev.x);
  371. + let y1 = Math.max(dragStart[1], ev.y);
  372.  
  373. bandbox.size = [x0, y0, x1, y1].join(" ");
  374. bandbox.hidden = hidden;
  375. @@ -443,25 +445,25 @@
  376. // Define some useful unit filters for getPreferredEntities
  377. var unitFilters = {
  378. "isUnit": function (entity) {
  379. - var entState = GetEntityState(entity);
  380. + let entState = GetEntityState(entity);
  381. if (!entState)
  382. return false;
  383. return hasClass(entState, "Unit");
  384. },
  385. "isDefensive": function (entity) {
  386. - var entState = GetEntityState(entity);
  387. + let entState = GetEntityState(entity);
  388. if (!entState)
  389. return false;
  390. return hasClass(entState, "Defensive");
  391. },
  392. "isNotSupport": function (entity) {
  393. - var entState = GetEntityState(entity);
  394. + let entState = GetEntityState(entity);
  395. if (!entState)
  396. return false;
  397. return hasClass(entState, "Unit") && !hasClass(entState, "Support") && !hasClass(entState, "Domestic");
  398. },
  399. "isIdle": function (entity) {
  400. - var entState = GetEntityState(entity);
  401. + let entState = GetEntityState(entity);
  402. if (!entState)
  403. return false;
  404. return hasClass(entState, "Unit") && entState.unitAI && entState.unitAI.isIdle;
  405. @@ -476,7 +478,7 @@
  406. function getPreferredEntities(ents)
  407. {
  408. // Default filters
  409. - var filters = [unitFilters.isUnit, unitFilters.isDefensive, unitFilters.isAnything];
  410. + let filters = [unitFilters.isUnit, unitFilters.isDefensive, unitFilters.isAnything];
  411.  
  412. // Handle hotkeys
  413. if (Engine.HotkeyIsPressed("selection.milonly"))
  414. @@ -484,8 +486,8 @@
  415. if (Engine.HotkeyIsPressed("selection.idleonly"))
  416. filters = [unitFilters.isIdle];
  417.  
  418. - var preferredEnts = [];
  419. - for (var i = 0; i < filters.length; ++i)
  420. + let preferredEnts = [];
  421. + for (let i = 0; i < filters.length; ++i)
  422. {
  423. preferredEnts = ents.filter(filters[i]);
  424. if (preferredEnts.length > 0)
  425. @@ -528,14 +530,14 @@
  426. switch (inputState)
  427. {
  428. case INPUT_BANDBOXING:
  429. - var bandbox = Engine.GetGUIObjectByName("bandbox");
  430. + let bandbox = Engine.GetGUIObjectByName("bandbox");
  431. switch (ev.type)
  432. {
  433. case "mousemotion":
  434. - var rect = updateBandbox(bandbox, ev, false);
  435. + let rect = updateBandbox(bandbox, ev, false);
  436.  
  437. - var ents = Engine.PickPlayerEntitiesInRect(rect[0], rect[1], rect[2], rect[3], g_IsObserver ? -1 : Engine.GetPlayerID());
  438. - var preferredEntities = getPreferredEntities(ents);
  439. + let ents = Engine.PickPlayerEntitiesInRect(rect[0], rect[1], rect[2], rect[3], g_IsObserver ? -1 : Engine.GetPlayerID());
  440. + let preferredEntities = getPreferredEntities(ents);
  441. g_Selection.setHighlightList(preferredEntities);
  442.  
  443. return false;
  444. @@ -543,10 +545,10 @@
  445. case "mousebuttonup":
  446. if (ev.button == SDL_BUTTON_LEFT)
  447. {
  448. - var rect = updateBandbox(bandbox, ev, true);
  449. + let rect = updateBandbox(bandbox, ev, true);
  450.  
  451. // Get list of entities limited to preferred entities
  452. - var ents = getPreferredEntities(Engine.PickPlayerEntitiesInRect(rect[0], rect[1], rect[2], rect[3], g_IsObserver ? -1 : Engine.GetPlayerID()));
  453. + let ents = getPreferredEntities(Engine.PickPlayerEntitiesInRect(rect[0], rect[1], rect[2], rect[3], g_IsObserver ? -1 : Engine.GetPlayerID()));
  454.  
  455. // Remove the bandbox hover highlighting
  456. g_Selection.setHighlightList([]);
  457. @@ -553,13 +555,9 @@
  458.  
  459. // Update the list of selected units
  460. if (Engine.HotkeyIsPressed("selection.add"))
  461. - {
  462. g_Selection.addList(ents);
  463. - }
  464. else if (Engine.HotkeyIsPressed("selection.remove"))
  465. - {
  466. g_Selection.removeList(ents);
  467. - }
  468. else
  469. {
  470. g_Selection.reset();
  471. @@ -579,9 +577,9 @@
  472. inputState = INPUT_NORMAL;
  473. return true;
  474. }
  475. - break;
  476. + return false;
  477. }
  478. - break;
  479. + return false;
  480.  
  481. case INPUT_BUILDING_CLICK:
  482. switch (ev.type)
  483. @@ -589,21 +587,18 @@
  484. case "mousemotion":
  485. // If the mouse moved far enough from the original click location,
  486. // then switch to drag-orientation mode
  487. - var dragDeltaX = ev.x - dragStart[0];
  488. - var dragDeltaY = ev.y - dragStart[1];
  489. - var maxDragDelta = 16;
  490. + let dragDeltaX = ev.x - dragStart[0];
  491. + let dragDeltaY = ev.y - dragStart[1];
  492. + let maxDragDelta = 16;
  493. if (Math.abs(dragDeltaX) >= maxDragDelta || Math.abs(dragDeltaY) >= maxDragDelta)
  494. - {
  495. inputState = INPUT_BUILDING_DRAG;
  496. - return false;
  497. - }
  498. - break;
  499. + return false;
  500.  
  501. case "mousebuttonup":
  502. if (ev.button == SDL_BUTTON_LEFT)
  503. {
  504. // If shift is down, let the player continue placing another of the same building
  505. - var queued = Engine.HotkeyIsPressed("session.queue");
  506. + let queued = Engine.HotkeyIsPressed("session.queue");
  507. if (tryPlaceBuilding(queued))
  508. {
  509. if (queued)
  510. @@ -612,12 +607,10 @@
  511. inputState = INPUT_NORMAL;
  512. }
  513. else
  514. - {
  515. inputState = INPUT_BUILDING_PLACEMENT;
  516. - }
  517. return true;
  518. }
  519. - break;
  520. + return false;
  521.  
  522. case "mousebuttondown":
  523. if (ev.button == SDL_BUTTON_RIGHT)
  524. @@ -627,9 +620,9 @@
  525. inputState = INPUT_NORMAL;
  526. return true;
  527. }
  528. - break;
  529. + return false;
  530. }
  531. - break;
  532. + return false;
  533.  
  534. case INPUT_BUILDING_WALL_CLICK:
  535. // User is mid-click in choosing a starting point for building a wall. The build process can still be cancelled at this point
  536. @@ -642,7 +635,7 @@
  537. inputState = INPUT_BUILDING_WALL_PATHING;
  538. return true;
  539. }
  540. - break;
  541. + return false;
  542.  
  543. case "mousebuttondown":
  544. if (ev.button == SDL_BUTTON_RIGHT)
  545. @@ -654,9 +647,9 @@
  546. inputState = INPUT_NORMAL;
  547. return true;
  548. }
  549. - break;
  550. + return false;
  551. }
  552. - break;
  553. + return false;
  554.  
  555. case INPUT_BUILDING_WALL_PATHING:
  556. // User has chosen a starting point for constructing the wall, and is now looking to set the endpoint.
  557. @@ -665,97 +658,93 @@
  558. // user to continue building walls.
  559. switch (ev.type)
  560. {
  561. - case "mousemotion":
  562. - placementSupport.wallEndPosition = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
  563. + case "mousemotion":
  564. + placementSupport.wallEndPosition = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
  565.  
  566. - // Update the building placement preview, and by extension, the list of snapping candidate entities for both (!)
  567. - // the ending point and the starting point to snap to.
  568. - //
  569. - // TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
  570. - // where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
  571. - // foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
  572. - // the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
  573. - // in them. Might be useful to query only for entities within a certain range around the starting point and ending
  574. - // points.
  575. + // Update the building placement preview, and by extension, the list of snapping candidate entities for both (!)
  576. + // the ending point and the starting point to snap to.
  577. + //
  578. + // TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
  579. + // where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
  580. + // foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
  581. + // the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
  582. + // in them. Might be useful to query only for entities within a certain range around the starting point and ending
  583. + // points.
  584.  
  585. - placementSupport.wallSnapEntitiesIncludeOffscreen = true;
  586. - var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
  587. + placementSupport.wallSnapEntitiesIncludeOffscreen = true;
  588. + let result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
  589. + if (result && result.cost)
  590. + {
  591. + placementSupport.tooltipMessage = getEntityCostTooltip(result);
  592. + let neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
  593. + if (neededResources)
  594. + placementSupport.tooltipMessage += getNeededResourcesTooltip(neededResources);
  595. + }
  596.  
  597. - if (result && result.cost)
  598. - {
  599. - placementSupport.tooltipMessage = getEntityCostTooltip(result);
  600. - var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
  601. - if (neededResources)
  602. - placementSupport.tooltipMessage += getNeededResourcesTooltip(neededResources);
  603. - }
  604. + return false;
  605.  
  606. - break;
  607. -
  608. - case "mousebuttondown":
  609. - if (ev.button == SDL_BUTTON_LEFT)
  610. + case "mousebuttondown":
  611. + if (ev.button == SDL_BUTTON_LEFT)
  612. + {
  613. + let queued = Engine.HotkeyIsPressed("session.queue");
  614. + if (tryPlaceWall(queued))
  615. {
  616. - var queued = Engine.HotkeyIsPressed("session.queue");
  617. - if (tryPlaceWall(queued))
  618. + if (queued)
  619. {
  620. - if (queued)
  621. - {
  622. - // continue building, just set a new starting position where we left off
  623. - placementSupport.position = placementSupport.wallEndPosition;
  624. - placementSupport.wallEndPosition = undefined;
  625. + // continue building, just set a new starting position where we left off
  626. + placementSupport.position = placementSupport.wallEndPosition;
  627. + placementSupport.wallEndPosition = undefined;
  628.  
  629. - inputState = INPUT_BUILDING_WALL_CLICK;
  630. - }
  631. - else
  632. - {
  633. - placementSupport.Reset();
  634. - inputState = INPUT_NORMAL;
  635. - }
  636. + inputState = INPUT_BUILDING_WALL_CLICK;
  637. }
  638. else
  639. {
  640. - placementSupport.tooltipMessage = translate("Cannot build wall here!");
  641. + placementSupport.Reset();
  642. + inputState = INPUT_NORMAL;
  643. }
  644. -
  645. - updateBuildingPlacementPreview();
  646. - return true;
  647. }
  648. - else if (ev.button == SDL_BUTTON_RIGHT)
  649. - {
  650. - // reset to normal input mode
  651. - placementSupport.Reset();
  652. - updateBuildingPlacementPreview();
  653. + else
  654. + placementSupport.tooltipMessage = translate("Cannot build wall here!");
  655.  
  656. - inputState = INPUT_NORMAL;
  657. - return true;
  658. - }
  659. - break;
  660. + updateBuildingPlacementPreview();
  661. + return true;
  662. + }
  663. + else if (ev.button == SDL_BUTTON_RIGHT)
  664. + {
  665. + // reset to normal input mode
  666. + placementSupport.Reset();
  667. + updateBuildingPlacementPreview();
  668. +
  669. + inputState = INPUT_NORMAL;
  670. + return true;
  671. + }
  672. + return false;
  673. }
  674. - break;
  675. + return false;
  676.  
  677. case INPUT_BUILDING_DRAG:
  678. switch (ev.type)
  679. {
  680. case "mousemotion":
  681. - var dragDeltaX = ev.x - dragStart[0];
  682. - var dragDeltaY = ev.y - dragStart[1];
  683. - var maxDragDelta = 16;
  684. + let dragDeltaX = ev.x - dragStart[0];
  685. + let dragDeltaY = ev.y - dragStart[1];
  686. + let maxDragDelta = 16;
  687. if (Math.abs(dragDeltaX) >= maxDragDelta || Math.abs(dragDeltaY) >= maxDragDelta)
  688. {
  689. // Rotate in the direction of the mouse
  690. - var target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
  691. + let target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
  692. placementSupport.angle = Math.atan2(target.x - placementSupport.position.x, target.z - placementSupport.position.z);
  693. }
  694. + // If the mouse is near the center, snap back to the default orientation
  695. else
  696. - {
  697. - // If the mouse is near the center, snap back to the default orientation
  698. placementSupport.SetDefaultAngle();
  699. - }
  700.  
  701. - var snapData = Engine.GuiInterfaceCall("GetFoundationSnapData", {
  702. + let snapData = Engine.GuiInterfaceCall("GetFoundationSnapData", {
  703. "template": placementSupport.template,
  704. "x": placementSupport.position.x,
  705. "z": placementSupport.position.z
  706. });
  707. +
  708. if (snapData)
  709. {
  710. placementSupport.angle = snapData.angle;
  711. @@ -764,13 +753,13 @@
  712. }
  713.  
  714. updateBuildingPlacementPreview();
  715. - break;
  716. + return false;
  717.  
  718. case "mousebuttonup":
  719. if (ev.button == SDL_BUTTON_LEFT)
  720. {
  721. // If shift is down, let the player continue placing another of the same building
  722. - var queued = Engine.HotkeyIsPressed("session.queue");
  723. + let queued = Engine.HotkeyIsPressed("session.queue");
  724. if (tryPlaceBuilding(queued))
  725. {
  726. if (queued)
  727. @@ -779,12 +768,10 @@
  728. inputState = INPUT_NORMAL;
  729. }
  730. else
  731. - {
  732. inputState = INPUT_BUILDING_PLACEMENT;
  733. - }
  734. return true;
  735. }
  736. - break;
  737. + return false;
  738.  
  739. case "mousebuttondown":
  740. if (ev.button == SDL_BUTTON_RIGHT)
  741. @@ -794,9 +781,9 @@
  742. inputState = INPUT_NORMAL;
  743. return true;
  744. }
  745. - break;
  746. + return false;
  747. }
  748. - break;
  749. + return false;
  750.  
  751. case INPUT_MASSTRIBUTING:
  752. if (ev.type == "hotkeyup" && ev.hotkey == "session.masstribute")
  753. @@ -804,7 +791,7 @@
  754. g_FlushTributing();
  755. inputState = INPUT_NORMAL;
  756. }
  757. - break;
  758. + return false;
  759.  
  760. case INPUT_BATCHTRAINING:
  761. if (ev.type == "hotkeyup" && ev.hotkey == "session.batchtrain")
  762. @@ -812,7 +799,7 @@
  763. flushTrainingBatch();
  764. inputState = INPUT_NORMAL;
  765. }
  766. - break;
  767. + return false;
  768. }
  769.  
  770. return false;
  771. @@ -859,7 +846,7 @@
  772. {
  773. case "mousemotion":
  774. // Highlight the first hovered entity (if any)
  775. - var ent = Engine.PickEntityAtPoint(ev.x, ev.y);
  776. + let ent = Engine.PickEntityAtPoint(ev.x, ev.y);
  777. if (ent != INVALID_ENTITY)
  778. g_Selection.setHighlightList([ent]);
  779. else
  780. @@ -876,37 +863,37 @@
  781. }
  782. else if (ev.button == SDL_BUTTON_RIGHT)
  783. {
  784. - var action = determineAction(ev.x, ev.y);
  785. + let action = determineAction(ev.x, ev.y);
  786. if (!action)
  787. - break;
  788. + return false;
  789. return doAction(action, ev);
  790. }
  791. - break;
  792. + return false;
  793.  
  794. case "hotkeydown":
  795. - if (ev.hotkey.indexOf("selection.group.") == 0)
  796. + if (ev.hotkey.indexOf("selection.group.") == 0)
  797. + {
  798. + let now = new Date();
  799. + if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey))
  800. {
  801. - var now = new Date();
  802. - if ((now.getTime() - doublePressTimer < doublePressTime) && (ev.hotkey == prevHotkey))
  803. + if (ev.hotkey.indexOf("selection.group.select.") == 0)
  804. {
  805. - if (ev.hotkey.indexOf("selection.group.select.") == 0)
  806. - {
  807. - var sptr = ev.hotkey.split(".");
  808. - performGroup("snap", sptr[3]);
  809. - }
  810. + let sptr = ev.hotkey.split(".");
  811. + performGroup("snap", sptr[3]);
  812. }
  813. - else
  814. - {
  815. - var sptr = ev.hotkey.split(".");
  816. - performGroup(sptr[2], sptr[3]);
  817. + }
  818. + else
  819. + {
  820. + let sptr = ev.hotkey.split(".");
  821. + performGroup(sptr[2], sptr[3]);
  822.  
  823. - doublePressTimer = now.getTime();
  824. - prevHotkey = ev.hotkey;
  825. - }
  826. + doublePressTimer = now.getTime();
  827. + prevHotkey = ev.hotkey;
  828. }
  829. - break;
  830. + }
  831. + return false;
  832. }
  833. - break;
  834. + return false;
  835.  
  836. case INPUT_PRESELECTEDACTION:
  837. switch (ev.type)
  838. @@ -913,7 +900,7 @@
  839. {
  840. case "mousemotion":
  841. // Highlight the first hovered entity (if any)
  842. - var ent = Engine.PickEntityAtPoint(ev.x, ev.y);
  843. + let ent = Engine.PickEntityAtPoint(ev.x, ev.y);
  844. if (ent != INVALID_ENTITY)
  845. g_Selection.setHighlightList([ent]);
  846. else
  847. @@ -924,9 +911,9 @@
  848. case "mousebuttondown":
  849. if (ev.button == SDL_BUTTON_LEFT && preSelectedAction != ACTION_NONE)
  850. {
  851. - var action = determineAction(ev.x, ev.y);
  852. + let action = determineAction(ev.x, ev.y);
  853. if (!action)
  854. - break;
  855. + return false;
  856. preSelectedAction = ACTION_NONE;
  857. inputState = INPUT_NORMAL;
  858. return doAction(action, ev);
  859. @@ -935,7 +922,7 @@
  860. {
  861. preSelectedAction = ACTION_NONE;
  862. inputState = INPUT_NORMAL;
  863. - break;
  864. + return false;
  865. }
  866. // else
  867. default:
  868. @@ -944,10 +931,10 @@
  869. {
  870. preSelectedAction = ACTION_NONE;
  871. inputState = INPUT_NORMAL;
  872. - break;
  873. + return false;
  874. }
  875. }
  876. - break;
  877. + return false;
  878.  
  879. case INPUT_SELECTING:
  880. switch (ev.type)
  881. @@ -954,8 +941,8 @@
  882. {
  883. case "mousemotion":
  884. // If the mouse moved further than a limit, switch to bandbox mode
  885. - var dragDeltaX = ev.x - dragStart[0];
  886. - var dragDeltaY = ev.y - dragStart[1];
  887. + let dragDeltaX = ev.x - dragStart[0];
  888. + let dragDeltaY = ev.y - dragStart[1];
  889.  
  890. if (Math.abs(dragDeltaX) >= maxDragDelta || Math.abs(dragDeltaY) >= maxDragDelta)
  891. {
  892. @@ -963,7 +950,7 @@
  893. return false;
  894. }
  895.  
  896. - var ent = Engine.PickEntityAtPoint(ev.x, ev.y);
  897. + let ent = Engine.PickEntityAtPoint(ev.x, ev.y);
  898. if (ent != INVALID_ENTITY)
  899. g_Selection.setHighlightList([ent]);
  900. else
  901. @@ -973,8 +960,8 @@
  902. case "mousebuttonup":
  903. if (ev.button == SDL_BUTTON_LEFT)
  904. {
  905. - var ents = [];
  906. - var selectedEntity = Engine.PickEntityAtPoint(ev.x, ev.y);
  907. + let ents = [];
  908. + let selectedEntity = Engine.PickEntityAtPoint(ev.x, ev.y);
  909. if (selectedEntity == INVALID_ENTITY)
  910. {
  911. if (!Engine.HotkeyIsPressed("selection.add") && !Engine.HotkeyIsPressed("selection.remove"))
  912. @@ -986,20 +973,18 @@
  913. return true;
  914. }
  915.  
  916. - var now = new Date();
  917. + let now = new Date();
  918.  
  919. // If camera following and we select different unit, stop
  920. if (Engine.GetFollowedEntity() != selectedEntity)
  921. - {
  922. Engine.CameraFollow(0);
  923. - }
  924.  
  925. if ((now.getTime() - doubleClickTimer < doubleClickTime) && (selectedEntity == prevClickedEntity))
  926. {
  927. // Double click or triple click has occurred
  928. - var showOffscreen = Engine.HotkeyIsPressed("selection.offscreen");
  929. - var matchRank = true;
  930. - var templateToMatch;
  931. + let showOffscreen = Engine.HotkeyIsPressed("selection.offscreen");
  932. + let matchRank = true;
  933. + let templateToMatch;
  934.  
  935. // Check for double click or triple click
  936. if (!doubleClicked)
  937. @@ -1008,24 +993,19 @@
  938. // Select similar units regardless of rank
  939. templateToMatch = GetEntityState(selectedEntity).identity.selectionGroupName;
  940. if (templateToMatch)
  941. - {
  942. matchRank = false;
  943. - }
  944. + // No selection group name defined, so fall back to exact match
  945. else
  946. - { // No selection group name defined, so fall back to exact match
  947. templateToMatch = GetEntityState(selectedEntity).template;
  948. - }
  949.  
  950. doubleClicked = true;
  951. // Reset the timer so the user has an extra period 'doubleClickTimer' to do a triple-click
  952. doubleClickTimer = now.getTime();
  953. }
  954. + // Double click has already occurred, so this is a triple click.
  955. + // Select units matching exact template name (same rank)
  956. else
  957. - {
  958. - // Double click has already occurred, so this is a triple click.
  959. - // Select units matching exact template name (same rank)
  960. templateToMatch = GetEntityState(selectedEntity).template;
  961. - }
  962.  
  963. // TODO: Should we handle "control all units" here as well?
  964. ents = Engine.PickSimilarPlayerEntities(templateToMatch, showOffscreen, matchRank, false);
  965. @@ -1043,13 +1023,9 @@
  966.  
  967. // Update the list of selected units
  968. if (Engine.HotkeyIsPressed("selection.add"))
  969. - {
  970. g_Selection.addList(ents);
  971. - }
  972. else if (Engine.HotkeyIsPressed("selection.remove"))
  973. - {
  974. g_Selection.removeList(ents);
  975. - }
  976. else
  977. {
  978. g_Selection.reset();
  979. @@ -1059,9 +1035,9 @@
  980. inputState = INPUT_NORMAL;
  981. return true;
  982. }
  983. - break;
  984. + return false;
  985. }
  986. - break;
  987. + return false;
  988.  
  989. case INPUT_BUILDING_PLACEMENT:
  990. switch (ev.type)
  991. @@ -1070,13 +1046,11 @@
  992.  
  993. placementSupport.position = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
  994.  
  995. + // Including only the on-screen towers in the next snap candidate list is sufficient here, since the user is
  996. + // still selecting a starting point (which must necessarily be on-screen). (The update of the snap entities
  997. + // itself happens in the call to updateBuildingPlacementPreview below).
  998. if (placementSupport.mode === "wall")
  999. - {
  1000. - // Including only the on-screen towers in the next snap candidate list is sufficient here, since the user is
  1001. - // still selecting a starting point (which must necessarily be on-screen). (The update of the snap entities
  1002. - // itself happens in the call to updateBuildingPlacementPreview below).
  1003. placementSupport.wallSnapEntitiesIncludeOffscreen = false;
  1004. - }
  1005. else
  1006. {
  1007. // cancel if not enough resources
  1008. @@ -1087,11 +1061,12 @@
  1009. return true;
  1010. }
  1011.  
  1012. - var snapData = Engine.GuiInterfaceCall("GetFoundationSnapData", {
  1013. + let snapData = Engine.GuiInterfaceCall("GetFoundationSnapData", {
  1014. "template": placementSupport.template,
  1015. "x": placementSupport.position.x,
  1016. "z": placementSupport.position.z,
  1017. });
  1018. +
  1019. if (snapData)
  1020. {
  1021. placementSupport.angle = snapData.angle;
  1022. @@ -1108,7 +1083,7 @@
  1023. {
  1024. if (placementSupport.mode === "wall")
  1025. {
  1026. - var validPlacement = updateBuildingPlacementPreview();
  1027. + let validPlacement = updateBuildingPlacementPreview();
  1028. if (validPlacement !== false)
  1029. inputState = INPUT_BUILDING_WALL_CLICK;
  1030. }
  1031. @@ -1127,11 +1102,11 @@
  1032. inputState = INPUT_NORMAL;
  1033. return true;
  1034. }
  1035. - break;
  1036. + return false;
  1037.  
  1038. case "hotkeydown":
  1039.  
  1040. - var rotation_step = Math.PI / 12; // 24 clicks make a full rotation
  1041. + let rotation_step = Math.PI / 12; // 24 clicks make a full rotation
  1042.  
  1043. switch (ev.hotkey)
  1044. {
  1045. @@ -1138,16 +1113,16 @@
  1046. case "session.rotate.cw":
  1047. placementSupport.angle += rotation_step;
  1048. updateBuildingPlacementPreview();
  1049. - break;
  1050. + return false;
  1051. case "session.rotate.ccw":
  1052. placementSupport.angle -= rotation_step;
  1053. updateBuildingPlacementPreview();
  1054. - break;
  1055. + return false;
  1056. }
  1057. - break;
  1058. + return false;
  1059.  
  1060. }
  1061. - break;
  1062. + return false;
  1063. }
  1064. return false;
  1065. }
  1066. @@ -1154,12 +1129,12 @@
  1067.  
  1068. function doAction(action, ev)
  1069. {
  1070. - var selection = g_Selection.toList();
  1071. + let selection = g_Selection.toList();
  1072.  
  1073. // If shift is down, add the order to the unit's order queue instead
  1074. // of running it immediately
  1075. - var queued = Engine.HotkeyIsPressed("session.queue");
  1076. - var target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
  1077. + let queued = Engine.HotkeyIsPressed("session.queue");
  1078. + let target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
  1079.  
  1080. if (unitActions[action.type] && unitActions[action.type].execute)
  1081. return unitActions[action.type].execute(target, action, selection, queued);
  1082. @@ -1175,14 +1150,14 @@
  1083. if (inputState != INPUT_NORMAL)
  1084. return false;
  1085.  
  1086. - var fromMinimap = true;
  1087. - var action = determineAction(undefined, undefined, fromMinimap);
  1088. + let fromMinimap = true;
  1089. + let action = determineAction(undefined, undefined, fromMinimap);
  1090. if (!action)
  1091. return false;
  1092.  
  1093. - var selection = g_Selection.toList();
  1094. + let selection = g_Selection.toList();
  1095.  
  1096. - var queued = Engine.HotkeyIsPressed("session.queue");
  1097. + let queued = Engine.HotkeyIsPressed("session.queue");
  1098. if (unitActions[action.type] && unitActions[action.type].execute)
  1099. return unitActions[action.type].execute(target, action, selection, queued);
  1100. error("Invalid action.type "+action.type);
  1101. @@ -1193,7 +1168,7 @@
  1102. // @param buildTemplate Template name of the entity the user wants to build
  1103. function startBuildingPlacement(buildTemplate, playerState)
  1104. {
  1105. - if(getEntityLimitAndCount(playerState, buildTemplate).canBeAddedCount == 0)
  1106. + if (getEntityLimitAndCount(playerState, buildTemplate).canBeAddedCount == 0)
  1107. return;
  1108.  
  1109. // TODO: we should clear any highlight selection rings here. If the mouse was over an entity before going onto the GUI
  1110. @@ -1203,7 +1178,7 @@
  1111. placementSupport.Reset();
  1112.  
  1113. // find out if we're building a wall, and change the entity appropriately if so
  1114. - var templateData = GetTemplateData(buildTemplate);
  1115. + let templateData = GetTemplateData(buildTemplate);
  1116. if (templateData.wallSet)
  1117. {
  1118. placementSupport.mode = "wall";
  1119. @@ -1217,13 +1192,9 @@
  1120. inputState = INPUT_BUILDING_PLACEMENT;
  1121. }
  1122.  
  1123. - if (templateData.attack &&
  1124. - templateData.attack.Ranged &&
  1125. - templateData.attack.Ranged.maxRange)
  1126. - {
  1127. - // add attack information to display a good tooltip
  1128. + // add attack information to display a good tooltip
  1129. + if (templateData.attack && templateData.attack.Ranged && templateData.attack.Ranged.maxRange)
  1130. placementSupport.attack = templateData.attack;
  1131. - }
  1132. }
  1133.  
  1134. // Called by GUI when user changes required trading goods
  1135. @@ -1238,25 +1209,17 @@
  1136. Engine.PostNetworkCommand({ "type": "barter", "sell": command.sell, "buy": command.buy, "amount": command.amount });
  1137. }
  1138.  
  1139. -// Camera jumping: when the user presses a hotkey the current camera location is marked.
  1140. -// When they press another hotkey the camera jumps back to that position. If the camera is already roughly at that location,
  1141. -// jump back to where it was previously.
  1142. -var jumpCameraPositions = [];
  1143. -var jumpCameraLast;
  1144. -var jumpCameraDistanceThreshold = Engine.ConfigDB_GetValue("user", "gui.session.camerajump.threshold");
  1145. -
  1146. function jumpCamera(index)
  1147. {
  1148. - var position = jumpCameraPositions[index];
  1149. + let position = jumpCameraPositions[index];
  1150. if (position)
  1151. {
  1152. - if (jumpCameraLast &&
  1153. - Math.abs(Engine.CameraGetX() - position.x) < jumpCameraDistanceThreshold &&
  1154. - Math.abs(Engine.CameraGetZ() - position.z) < jumpCameraDistanceThreshold)
  1155. + if (jumpCameraLast && Math.abs(Engine.CameraGetX() - position.x) < jumpCameraDistanceThreshold &&
  1156. + Math.abs(Engine.CameraGetZ() - position.z) < jumpCameraDistanceThreshold)
  1157. Engine.CameraMoveTo(jumpCameraLast.x, jumpCameraLast.z);
  1158. else
  1159. {
  1160. - jumpCameraLast = {x: Engine.CameraGetX(), z: Engine.CameraGetZ()};
  1161. + jumpCameraLast = { x: Engine.CameraGetX(), z: Engine.CameraGetZ()};
  1162. Engine.CameraMoveTo(position.x, position.z);
  1163. }
  1164. }
  1165. @@ -1264,28 +1227,19 @@
  1166.  
  1167. function setJumpCamera(index)
  1168. {
  1169. - jumpCameraPositions[index] = {x: Engine.CameraGetX(), z: Engine.CameraGetZ()};
  1170. + jumpCameraPositions[index] = { x: Engine.CameraGetX(), z: Engine.CameraGetZ() };
  1171. }
  1172.  
  1173. -// Batch training:
  1174. -// When the user shift-clicks, we set these variables and switch to INPUT_BATCHTRAINING
  1175. -// When the user releases shift, or clicks on a different training button, we create the batched units
  1176. -var batchTrainingEntities;
  1177. -var batchTrainingType;
  1178. -var batchTrainingCount;
  1179. -var batchTrainingEntityAllowedCount;
  1180. -const batchIncrementSize = 5;
  1181. -
  1182. function flushTrainingBatch()
  1183. {
  1184. - var appropriateBuildings = getBuildingsWhichCanTrainEntity(batchTrainingEntities, batchTrainingType);
  1185. + let appropriateBuildings = getBuildingsWhichCanTrainEntity(batchTrainingEntities, batchTrainingType);
  1186. // If training limits don't allow us to train batchTrainingCount in each appropriate building
  1187. if (batchTrainingEntityAllowedCount !== undefined &&
  1188. batchTrainingEntityAllowedCount < batchTrainingCount * appropriateBuildings.length)
  1189. {
  1190. // Train as many full batches as we can
  1191. - var buildingsCountToTrainFullBatch = Math.floor(batchTrainingEntityAllowedCount / batchTrainingCount);
  1192. - var buildingsToTrainFullBatch = appropriateBuildings.slice(0, buildingsCountToTrainFullBatch);
  1193. + let buildingsCountToTrainFullBatch = Math.floor(batchTrainingEntityAllowedCount / batchTrainingCount);
  1194. + let buildingsToTrainFullBatch = appropriateBuildings.slice(0, buildingsCountToTrainFullBatch);
  1195. Engine.PostNetworkCommand({
  1196. "type": "train",
  1197. "entities": buildingsToTrainFullBatch,
  1198. @@ -1313,8 +1267,8 @@
  1199. function getBuildingsWhichCanTrainEntity(entitiesToCheck, trainEntType)
  1200. {
  1201. return entitiesToCheck.filter(function(entity) {
  1202. - var state = GetEntityState(entity);
  1203. - var canTrain = state && state.production && state.production.entities.length &&
  1204. + let state = GetEntityState(entity);
  1205. + let canTrain = state && state.production && state.production.entities.length &&
  1206. state.production.entities.indexOf(trainEntType) != -1;
  1207. return canTrain;
  1208. });
  1209. @@ -1322,7 +1276,7 @@
  1210.  
  1211. function getEntityLimitAndCount(playerState, entType)
  1212. {
  1213. - var r = {
  1214. + let r = {
  1215. "entLimit": undefined,
  1216. "entCount": undefined,
  1217. "entLimitChangers": undefined,
  1218. @@ -1330,8 +1284,9 @@
  1219. };
  1220. if (!playerState.entityLimits)
  1221. return r;
  1222. - var template = GetTemplateData(entType);
  1223. - var entCategory = null;
  1224. +
  1225. + let template = GetTemplateData(entType);
  1226. + let entCategory = null;
  1227. if (template.trainingRestrictions)
  1228. entCategory = template.trainingRestrictions.category;
  1229. else if (template.buildRestrictions)
  1230. @@ -1349,20 +1304,20 @@
  1231. // Add the unit shown at position to the training queue for all entities in the selection
  1232. function addTrainingByPosition(position)
  1233. {
  1234. - var simState = GetSimState();
  1235. - var playerState = simState.players[Engine.GetPlayerID()];
  1236. - var selection = g_Selection.toList();
  1237. + let simState = GetSimState();
  1238. + let playerState = simState.players[Engine.GetPlayerID()];
  1239. + let selection = g_Selection.toList();
  1240.  
  1241. if (!playerState || !selection.length)
  1242. return;
  1243.  
  1244. - var trainableEnts = getAllTrainableEntitiesFromSelection();
  1245. + let trainableEnts = getAllTrainableEntitiesFromSelection();
  1246.  
  1247. // Check if the position is valid
  1248. if (!trainableEnts.length || trainableEnts.length <= position)
  1249. return;
  1250.  
  1251. - var entToTrain = trainableEnts[position];
  1252. + let entToTrain = trainableEnts[position];
  1253.  
  1254. addTrainingToQueue(selection, entToTrain, playerState);
  1255. return;
  1256. @@ -1372,17 +1327,18 @@
  1257. function addTrainingToQueue(selection, trainEntType, playerState)
  1258. {
  1259. // Create list of buildings which can train trainEntType
  1260. - var appropriateBuildings = getBuildingsWhichCanTrainEntity(selection, trainEntType);
  1261. + let appropriateBuildings = getBuildingsWhichCanTrainEntity(selection, trainEntType);
  1262.  
  1263. // Check trainEntType entity limit and count
  1264. - var limits = getEntityLimitAndCount(playerState, trainEntType);
  1265. + let limits = getEntityLimitAndCount(playerState, trainEntType);
  1266.  
  1267. // Batch training possible if we can train at least 2 units
  1268. - var batchTrainingPossible = limits.canBeAddedCount == undefined || limits.canBeAddedCount > 1;
  1269. + let batchTrainingPossible = limits.canBeAddedCount == undefined || limits.canBeAddedCount > 1;
  1270.  
  1271. - var decrement = Engine.HotkeyIsPressed("selection.remove");
  1272. + let decrement = Engine.HotkeyIsPressed("selection.remove");
  1273. + let template;
  1274. if (!decrement)
  1275. - var template = GetTemplateData(trainEntType);
  1276. + template = GetTemplateData(trainEntType);
  1277.  
  1278. if (Engine.HotkeyIsPressed("session.batchtrain") && batchTrainingPossible)
  1279. {
  1280. @@ -1389,16 +1345,14 @@
  1281. if (inputState == INPUT_BATCHTRAINING)
  1282. {
  1283. // Check if we are training in the same building(s) as the last batch
  1284. - var sameEnts = false;
  1285. + let sameEnts = false;
  1286. if (batchTrainingEntities.length == selection.length)
  1287. {
  1288. // NOTE: We just check if the arrays are the same and if the order is the same
  1289. // If the order changed, we have a new selection and we should create a new batch.
  1290. - for (var i = 0; i < batchTrainingEntities.length; ++i)
  1291. - {
  1292. + for (let i = 0; i < batchTrainingEntities.length; ++i)
  1293. if (!(sameEnts = batchTrainingEntities[i] == selection[i]))
  1294. break;
  1295. - }
  1296. }
  1297. // If we're already creating a batch of this unit (in the same building(s)), then just extend it
  1298. // (if training limits allow)
  1299. @@ -1424,10 +1378,8 @@
  1300. }
  1301. // Otherwise start a new one
  1302. else if (!decrement)
  1303. - {
  1304. flushTrainingBatch();
  1305. - // fall through to create the new batch
  1306. - }
  1307. + // fall through to create the new batch
  1308. }
  1309.  
  1310. // Don't start a new batch if decrementing or unable to afford it.
  1311. @@ -1445,7 +1397,7 @@
  1312. {
  1313. // Non-batched - just create a single entity in each building
  1314. // (but no more than entity limit allows)
  1315. - var buildingsForTraining = appropriateBuildings;
  1316. + let buildingsForTraining = appropriateBuildings;
  1317. if (limits.entLimit)
  1318. buildingsForTraining = buildingsForTraining.slice(0, limits.canBeAddedCount);
  1319. Engine.PostNetworkCommand({
  1320. @@ -1467,25 +1419,23 @@
  1321. // the training button with shift down
  1322. function getTrainingBatchStatus(playerState, entity, trainEntType, selection)
  1323. {
  1324. - var appropriateBuildings = [entity];
  1325. + let appropriateBuildings = [entity];
  1326. if (selection && selection.indexOf(entity) != -1)
  1327. appropriateBuildings = getBuildingsWhichCanTrainEntity(selection, trainEntType);
  1328. - var nextBatchTrainingCount = 0;
  1329. - var currentBatchTrainingCount = 0;
  1330. + let nextBatchTrainingCount = 0;
  1331. + let currentBatchTrainingCount = 0;
  1332.  
  1333. + let limits;
  1334. if (inputState == INPUT_BATCHTRAINING && batchTrainingEntities.indexOf(entity) != -1 &&
  1335. batchTrainingType == trainEntType)
  1336. {
  1337. nextBatchTrainingCount = batchTrainingCount;
  1338. currentBatchTrainingCount = batchTrainingCount;
  1339. - var limits = {
  1340. - "canBeAddedCount": batchTrainingEntityAllowedCount
  1341. - };
  1342. + limits = { "canBeAddedCount": batchTrainingEntityAllowedCount };
  1343. }
  1344. else
  1345. - {
  1346. - var limits = getEntityLimitAndCount(playerState, trainEntType);
  1347. - }
  1348. + limits = getEntityLimitAndCount(playerState, trainEntType);
  1349. +
  1350. // We need to calculate count after the next increment if it's possible
  1351. if (limits.canBeAddedCount == undefined ||
  1352. limits.canBeAddedCount > nextBatchTrainingCount * appropriateBuildings.length)
  1353. @@ -1492,8 +1442,8 @@
  1354. nextBatchTrainingCount += batchIncrementSize;
  1355. // If training limits don't allow us to train batchTrainingCount in each appropriate building
  1356. // train as many full batches as we can and remainer in one more building.
  1357. - var buildingsCountToTrainFullBatch = appropriateBuildings.length;
  1358. - var remainderToTrain = 0;
  1359. + let buildingsCountToTrainFullBatch = appropriateBuildings.length;
  1360. + let remainderToTrain = 0;
  1361. if (limits.canBeAddedCount !== undefined &&
  1362. limits.canBeAddedCount < nextBatchTrainingCount * appropriateBuildings.length)
  1363. {
  1364. @@ -1520,7 +1470,7 @@
  1365. {
  1366. if (!entity)
  1367. return;
  1368. - var entState = GetExtendedEntityState(entity);
  1369. + let entState = GetExtendedEntityState(entity);
  1370.  
  1371. if (!controlsPlayer(entState.player))
  1372. return;
  1373. @@ -1534,9 +1484,9 @@
  1374. {
  1375. if (!entity)
  1376. return;
  1377. - var entState = GetExtendedEntityState(entity);
  1378. + let entState = GetExtendedEntityState(entity);
  1379.  
  1380. - var playerState = GetSimState().players[Engine.GetPlayerID()];
  1381. + let playerState = GetSimState().players[Engine.GetPlayerID()];
  1382. if (!playerState.isMutualAlly[entState.player] || g_IsObserver)
  1383. return;
  1384.  
  1385. @@ -1563,9 +1513,9 @@
  1386. case "snap":
  1387. case "select":
  1388. case "add":
  1389. - var toSelect = [];
  1390. + let toSelect = [];
  1391. g_Groups.update();
  1392. - for (var ent in g_Groups.groups[groupId].ents)
  1393. + for (let ent in g_Groups.groups[groupId].ents)
  1394. toSelect.push(+ent);
  1395.  
  1396. if (action != "add")
  1397. @@ -1580,7 +1530,7 @@
  1398. if (position && entState.visibility != "hidden")
  1399. Engine.CameraMoveTo(position.x, position.z);
  1400. }
  1401. - break;
  1402. + return;
  1403. case "save":
  1404. case "breakUp":
  1405. g_Groups.groups[groupId].reset();
  1406. @@ -1589,7 +1539,7 @@
  1407. g_Groups.addEntities(groupId, g_Selection.toList());
  1408.  
  1409. updateGroups();
  1410. - break;
  1411. + return;
  1412. }
  1413. }
  1414. // Performs the specified stance
  1415. @@ -1597,7 +1547,7 @@
  1416. {
  1417. if (entity)
  1418. {
  1419. - var selection = g_Selection.toList();
  1420. + let selection = g_Selection.toList();
  1421. Engine.PostNetworkCommand({
  1422. "type": "stance",
  1423. "entities": selection,
  1424. @@ -1609,7 +1559,7 @@
  1425. // Lock / Unlock the gate
  1426. function lockGate(lock)
  1427. {
  1428. - var selection = g_Selection.toList();
  1429. + let selection = g_Selection.toList();
  1430. Engine.PostNetworkCommand({
  1431. "type": "lock-gate",
  1432. "entities": selection,
  1433. @@ -1620,7 +1570,7 @@
  1434. // Pack / unpack unit(s)
  1435. function packUnit(pack)
  1436. {
  1437. - var selection = g_Selection.toList();
  1438. + let selection = g_Selection.toList();
  1439. Engine.PostNetworkCommand({
  1440. "type": "pack",
  1441. "entities": selection,
  1442. @@ -1632,7 +1582,7 @@
  1443. // Cancel un/packing unit(s)
  1444. function cancelPackUnit(pack)
  1445. {
  1446. - var selection = g_Selection.toList();
  1447. + let selection = g_Selection.toList();
  1448. Engine.PostNetworkCommand({
  1449. "type": "cancel-pack",
  1450. "entities": selection,
  1451. @@ -1644,7 +1594,7 @@
  1452. // Transform a wall to a gate
  1453. function transformWallToGate(template)
  1454. {
  1455. - var selection = g_Selection.toList();
  1456. + let selection = g_Selection.toList();
  1457. Engine.PostNetworkCommand({
  1458. "type": "wall-to-gate",
  1459. "entities": selection.filter( function(e) { return getWallGateTemplate(e) == template; } ),
  1460. @@ -1656,8 +1606,8 @@
  1461. function getWallGateTemplate(entity)
  1462. {
  1463. // TODO: find the gate template name in a better way
  1464. - var entState = GetEntityState(entity);
  1465. - var index;
  1466. + let entState = GetEntityState(entity);
  1467. + let index;
  1468.  
  1469. if (entState && !entState.foundation && hasClass(entState, "LongWall") && (index = entState.template.indexOf("long")) >= 0)
  1470. return entState.template.substr(0, index) + "gate";
  1471. @@ -1670,7 +1620,7 @@
  1472. // Follow the given entity if it's a unit
  1473. if (entity)
  1474. {
  1475. - var entState = GetEntityState(entity);
  1476. + let entState = GetEntityState(entity);
  1477. if (entState && hasClass(entState, "Unit"))
  1478. {
  1479. Engine.CameraFollow(entity);
  1480. @@ -1682,10 +1632,6 @@
  1481. Engine.CameraFollow(0);
  1482. }
  1483.  
  1484. -var lastIdleUnit = 0;
  1485. -var currIdleClassIndex = 0;
  1486. -var lastIdleClasses = [];
  1487. -
  1488. function resetIdleUnit()
  1489. {
  1490. lastIdleUnit = 0;
  1491. @@ -1695,8 +1641,8 @@
  1492.  
  1493. function findIdleUnit(classes)
  1494. {
  1495. - var append = Engine.HotkeyIsPressed("selection.add");
  1496. - var selectall = Engine.HotkeyIsPressed("selection.offscreen");
  1497. + let append = Engine.HotkeyIsPressed("selection.add");
  1498. + let selectall = Engine.HotkeyIsPressed("selection.offscreen");
  1499.  
  1500. // Reset the last idle unit, etc., if the selection type has changed.
  1501. if (selectall || classes.length != lastIdleClasses.length || !classes.every((v,i) => v === lastIdleClasses[i]))
  1502. @@ -1703,7 +1649,7 @@
  1503. resetIdleUnit();
  1504. lastIdleClasses = classes;
  1505.  
  1506. - var data = {
  1507. + let data = {
  1508. "viewedPlayer": g_ViewedPlayer,
  1509. "excludeUnits": append ? g_Selection.toList() : [],
  1510. // If the current idle class index is not 0, put the class at that index first.
  1511. @@ -1715,7 +1661,7 @@
  1512. data.prevUnit = lastIdleUnit;
  1513. }
  1514.  
  1515. - var idleUnits = Engine.GuiInterfaceCall("FindIdleUnits", data);
  1516. + let idleUnits = Engine.GuiInterfaceCall("FindIdleUnits", data);
  1517. if (!idleUnits.length)
  1518. {
  1519. // TODO: display a message or play a sound to indicate no more idle units, or something
  1520. @@ -1732,12 +1678,12 @@
  1521. return;
  1522.  
  1523. lastIdleUnit = idleUnits[0];
  1524. - var entityState = GetEntityState(lastIdleUnit);
  1525. - var position = entityState.position;
  1526. + let entityState = GetEntityState(lastIdleUnit);
  1527. + let position = entityState.position;
  1528. if (position)
  1529. Engine.CameraMoveTo(position.x, position.z);
  1530. // Move the idle class index to the first class an idle unit was found for.
  1531. - var indexChange = data.idleClasses.findIndex(elem => hasClass(entityState, elem));
  1532. + let indexChange = data.idleClasses.findIndex(elem => hasClass(entityState, elem));
  1533. currIdleClassIndex = (currIdleClassIndex + indexChange) % classes.length;
  1534. }
  1535.  
  1536. @@ -1757,8 +1703,8 @@
  1537. function unloadTemplate(template)
  1538. {
  1539. // Filter out all entities that aren't garrisonable.
  1540. - var garrisonHolders = g_Selection.toList().filter(function(e) {
  1541. - var state = GetEntityState(e);
  1542. + let garrisonHolders = g_Selection.toList().filter(function(e) {
  1543. + let state = GetEntityState(e);
  1544. if (state && state.garrisonHolder)
  1545. return true;
  1546. return false;
  1547. @@ -1774,11 +1720,11 @@
  1548.  
  1549. function unloadSelection()
  1550. {
  1551. - var parent = 0;
  1552. - var ents = [];
  1553. - for each (var ent in g_Selection.selected)
  1554. + let parent = 0;
  1555. + let ents = [];
  1556. + for (let ent of g_Selection.selected)
  1557. {
  1558. - var state = GetExtendedEntityState(ent);
  1559. + let state = GetExtendedEntityState(ent);
  1560. if (!state || !state.turretParent)
  1561. continue;
  1562. if (!parent)
  1563. @@ -1795,8 +1741,8 @@
  1564.  
  1565. function unloadAllByOwner()
  1566. {
  1567. - var garrisonHolders = g_Selection.toList().filter(function(e) {
  1568. - var state = GetEntityState(e);
  1569. + let garrisonHolders = g_Selection.toList().filter(function(e) {
  1570. + let state = GetEntityState(e);
  1571. return state && state.garrisonHolder;
  1572. });
  1573. Engine.PostNetworkCommand({ "type": "unload-all-by-owner", "garrisonHolders": garrisonHolders });
  1574. @@ -1805,8 +1751,8 @@
  1575. function unloadAll()
  1576. {
  1577. // Filter out all entities that aren't garrisonable.
  1578. - var garrisonHolders = g_Selection.toList().filter(function(e) {
  1579. - var state = GetEntityState(e);
  1580. + let garrisonHolders = g_Selection.toList().filter(function(e) {
  1581. + let state = GetEntityState(e);
  1582. if (state && state.garrisonHolder)
  1583. return true;
  1584. return false;
  1585. @@ -1818,8 +1764,8 @@
  1586. function backToWork()
  1587. {
  1588. // Filter out all entities that can't go back to work.
  1589. - var workers = g_Selection.toList().filter(function(e) {
  1590. - var state = GetEntityState(e);
  1591. + let workers = g_Selection.toList().filter(function(e) {
  1592. + let state = GetEntityState(e);
  1593. return (state && state.unitAI && state.unitAI.hasWorkOrders);
  1594. });
  1595.  
  1596. @@ -1829,8 +1775,8 @@
  1597. function removeGuard()
  1598. {
  1599. // Filter out all entities that are currently guarding/escorting.
  1600. - var entities = g_Selection.toList().filter(function(e) {
  1601. - var state = GetEntityState(e);
  1602. + let entities = g_Selection.toList().filter(function(e) {
  1603. + let state = GetEntityState(e);
  1604. return (state && state.unitAI && state.unitAI.isGuarding);
  1605. });
  1606.  
  1607. @@ -1839,8 +1785,8 @@
  1608.  
  1609. function increaseAlertLevel()
  1610. {
  1611. - var entities = g_Selection.toList().filter(function(e) {
  1612. - var state = GetEntityState(e);
  1613. + let entities = g_Selection.toList().filter(function(e) {
  1614. + let state = GetEntityState(e);
  1615. return (state && state.alertRaiser && state.alertRaiser.canIncreaseLevel);
  1616. });
  1617.  
  1618. @@ -1849,8 +1795,8 @@
  1619.  
  1620. function endOfAlert()
  1621. {
  1622. - var entities = g_Selection.toList().filter(function(e) {
  1623. - var state = GetEntityState(e);
  1624. + let entities = g_Selection.toList().filter(function(e) {
  1625. + let state = GetEntityState(e);
  1626. return (state && state.alertRaiser && state.alertRaiser.hasRaisedAlert);
  1627. });
  1628.  
  1629. @@ -1875,28 +1821,29 @@
  1630. */
  1631. function getTrainingQueueItems(selection)
  1632. {
  1633. - var entStates = [];
  1634. - for (var ent of selection)
  1635. + let entStates = [];
  1636. + for (let ent of selection)
  1637. {
  1638. - var entState = GetEntityState(ent);
  1639. + let entState = GetEntityState(ent);
  1640. if (entState.production)
  1641. entStates.push(entState);
  1642. }
  1643. - var queue = [];
  1644. - var i = 0;
  1645. + let queue = [];
  1646. + let i = 0;
  1647. + let foundNewItems;
  1648. do
  1649. {
  1650. - var foundNewItems = false;
  1651. - for (entState of entStates)
  1652. + foundNewItems = false;
  1653. + for (let entState of entStates)
  1654. {
  1655. if (!entState.production.queue[i])
  1656. continue;
  1657. - var item = entState.production.queue[i];
  1658. + let item = entState.production.queue[i];
  1659. item.producingEnt = entState.id;
  1660. queue.push(item);
  1661. foundNewItems = true;
  1662. }
  1663. - i++;
  1664. + ++i;
  1665. }
  1666. while (foundNewItems);
  1667. return queue;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement