Ticket #3826: patch.patch
File patch.patch, 10.6 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/gui/session/input.js
From d2e8ad2998691cbf531ba3a5b31d7d0924379fc3 Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" <clockwork-muse@outlook.com> Date: Sun, 1 May 2016 15:18:29 +0900 Subject: [PATCH] Improve FindIdleUnits --- binaries/data/mods/public/gui/session/input.js | 89 ++++++++------------ binaries/data/mods/public/gui/session/session.js | 15 +--- .../public/simulation/components/GuiInterface.js | 98 +++++++++++++++++----- 3 files changed, 119 insertions(+), 83 deletions(-) diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js index 9ef4ee6..9357ca0 100644
a b function setCameraFollow(entity) 1683 1683 } 1684 1684 1685 1685 var lastIdleUnit = 0; 1686 var currIdleClass = 0;1687 var lastIdle Type = undefined;1686 var currIdleClassIndex = 0; 1687 var lastIdleClasses = []; 1688 1688 1689 1689 function resetIdleUnit() 1690 1690 { 1691 1691 lastIdleUnit = 0; 1692 currIdleClass = 0;1693 lastIdle Type = undefined;1692 currIdleClassIndex = 0; 1693 lastIdleClasses = []; 1694 1694 } 1695 1695 1696 1696 function findIdleUnit(classes) … … function findIdleUnit(classes) 1699 1699 var selectall = Engine.HotkeyIsPressed("selection.offscreen"); 1700 1700 1701 1701 // Reset the last idle unit, etc., if the selection type has changed. 1702 var type = classes.join(); 1703 if (selectall || type != lastIdleType) 1702 if (selectall || classes.length != lastIdleClasses.length || !classes.every((v,i) => v === lastIdleClasses[i])) 1704 1703 resetIdleUnit(); 1705 lastIdle Type = type;1704 lastIdleClasses = classes; 1706 1705 1707 // If selectall is true, there is no limit and it's necessary to iterate 1708 // over all of the classes, resetting only when the first match is found. 1709 var matched = false; 1710 1711 for (var i = 0; i < classes.length; ++i) 1706 var data = { 1707 "viewedPlayer": g_ViewedPlayer, 1708 "excludeUnits": append ? g_Selection.toList() : [], 1709 // If the current idle class index is not 0, put the class at that index first. 1710 "idleClasses": classes.slice(currIdleClassIndex, classes.length).concat(classes.slice(0, currIdleClassIndex)) 1711 }; 1712 if (!selectall) 1712 1713 { 1713 var data = { 1714 "idleClass": classes[currIdleClass], 1715 "prevUnit": lastIdleUnit, 1716 "limit": 1, 1717 "excludeUnits": [] 1718 }; 1719 1720 if (append) 1721 data.excludeUnits = g_Selection.toList(); 1722 1723 if (selectall) 1724 data = { "idleClass": classes[currIdleClass] }; 1725 1726 data.viewedPlayer = g_ViewedPlayer; 1727 1728 // Check if we have new valid entity 1729 var idleUnits = Engine.GuiInterfaceCall("FindIdleUnits", data); 1730 if (idleUnits.length && idleUnits[0] != lastIdleUnit) 1731 { 1732 lastIdleUnit = idleUnits[0]; 1733 if (!append && (!selectall || selectall && !matched)) 1734 g_Selection.reset(); 1714 data.limit = 1; 1715 data.prevUnit = lastIdleUnit; 1716 } 1735 1717 1736 if (selectall) 1737 g_Selection.addList(idleUnits); 1738 else 1739 { 1740 g_Selection.addList([lastIdleUnit]); 1741 var position = GetEntityState(lastIdleUnit).position; 1742 if (position) 1743 Engine.CameraMoveTo(position.x, position.z); 1744 return; 1745 } 1718 var idleUnits = Engine.GuiInterfaceCall("FindIdleUnits", data); 1719 if (!idleUnits.length) 1720 { 1721 // TODO: display a message or play a sound to indicate no more idle units, or something 1722 // Reset for next cycle 1723 resetIdleUnit(); 1724 return; 1725 } 1746 1726 1747 matched = true; 1748 } 1727 if (!append) 1728 g_Selection.reset(); 1729 g_Selection.addList(idleUnits); 1749 1730 1750 lastIdleUnit = 0; 1751 currIdleClass = (currIdleClass + 1) % classes.length; 1752 } 1731 if (selectall) 1732 return; 1753 1733 1754 // TODO: display a message or play a sound to indicate no more idle units, or something 1755 // Reset for next cycle 1756 resetIdleUnit(); 1734 lastIdleUnit = idleUnits[0]; 1735 var entityState = GetEntityState(lastIdleUnit); 1736 var position = entityState.position; 1737 if (position) 1738 Engine.CameraMoveTo(position.x, position.z); 1739 // Move the idle class index to the first class an idle unit was found for. 1740 var indexChange = data.idleClasses.findIndex(elem => hasClass(entityState, elem)); 1741 currIdleClassIndex = (currIdleClassIndex + indexChange) % classes.length; 1757 1742 } 1758 1743 1759 1744 function stopUnits(entities) -
binaries/data/mods/public/gui/session/session.js
diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index 8b23cb3..5d6cb18 100644
a b function changeGameSpeed(speed) 650 650 651 651 function hasIdleWorker() 652 652 { 653 for (let workerType of g_WorkerTypes) 654 { 655 let idleUnits = Engine.GuiInterfaceCall("FindIdleUnits", { 653 return Engine.GuiInterfaceCall("HasIdleUnits", { 656 654 "viewedPlayer": g_ViewedPlayer, 657 "idleClass": workerType, 658 "prevUnit": undefined, 659 "limit": 1, 655 "idleClasses": g_WorkerTypes, 660 656 "excludeUnits": [] 661 }); 662 663 if (idleUnits.length > 0) 664 return true; 665 } 666 return false; 657 }); 667 658 } 668 659 669 660 function updateIdleWorkerButton() -
binaries/data/mods/public/simulation/components/GuiInterface.js
diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js index e4b7300..8aeff3f 100644
a b GuiInterface.prototype.PlaySound = function(player, data) 1645 1645 PlaySound(data.name, data.entity); 1646 1646 }; 1647 1647 1648 /** 1649 * Find any idle units. 1650 * 1651 * @param data.viewedPlayer The player for which to find idle units. 1652 * @param data.idleClasses Array of class names to include. 1653 * @param data.prevUnit The previous idle unit, if calling a second time to iterate through units. May be left undefined. 1654 * @param data.limit The number of idle units to return. May be left undefined (will return all idle units). 1655 * @param data.excludeUnits Array of units to exclude. 1656 * 1657 * Returns an array of idle units. 1658 * If multiple classes were supplied, and multiple items will be returned, the items will be sorted by class. 1659 */ 1648 1660 GuiInterface.prototype.FindIdleUnits = function(player, data) 1649 1661 { 1662 let idleUnits = []; 1663 // The general case is that only the 'first' idle unit is required; filtering would examine every unit. 1664 // This loop imitates a grouping/aggregation on the first matching idle class. 1650 1665 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 1651 let playerEntities = cmpRangeManager.GetEntitiesByPlayer(data.viewedPlayer).filter(entity => { 1666 for (let entity of cmpRangeManager.GetEntitiesByPlayer(data.viewedPlayer)) 1667 { 1668 let filtered = this.IdleUnitFilter(entity, data.idleClasses, data.excludeUnits); 1669 if (!filtered.idle) 1670 continue; 1652 1671 1653 let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); 1654 if (!cmpUnitAI || !cmpUnitAI.IsIdle() || cmpUnitAI.IsGarrisoned()) 1655 return false; 1672 // If the entity is in the 'current' (first, 0) bucket on a resumed search, it must be after the "previous" unit, if any. 1673 // By adding to the 'end', there is no pause if the series of units loops. 1674 var bucket = filtered.bucket; 1675 if(bucket == 0 && data.prevUnit && entity <= data.prevUnit) 1676 bucket = data.idleClasses.length; 1656 1677 1657 let cmpIdentity = Engine.QueryInterface(entity, IID_Identity);1658 if (!cmpIdentity || !cmpIdentity.HasClass(data.idleClass))1659 return false;1678 if (!idleUnits[bucket]) 1679 idleUnits[bucket] = []; 1680 idleUnits[bucket].push(entity); 1660 1681 1661 return true; 1662 }); 1682 // If enough units have been collected in the first bucket, go ahead and return them. 1683 if (data.limit && bucket == 0 && idleUnits[0].length == data.limit) 1684 return idleUnits[0]; 1685 } 1663 1686 1664 let idleUnits = []; 1687 let reduced = idleUnits.reduce((prev, curr) => prev.concat(curr), []); 1688 if (data.limit && reduced.length > data.limit) 1689 return reduced.slice(0, data.limit); 1665 1690 1666 for (let ent of playerEntities) 1667 { 1668 if (ent <= data.prevUnit|0 || data.excludeUnits.indexOf(ent) > -1) 1669 continue; 1670 idleUnits.push(ent); 1671 if (data.limit && idleUnits.length >= data.limit) 1672 break; 1673 } 1691 return reduced; 1692 }; 1693 1694 /** 1695 * Discover if the player has idle units. 1696 * 1697 * @param data.viewedPlayer The player for which to find idle units. 1698 * @param data.idleClasses Array of class names to include. 1699 * @param data.excludeUnits Array of units to exclude. 1700 * 1701 * Returns a boolean of whether the player has any idle units 1702 */ 1703 GuiInterface.prototype.HasIdleUnits = function(player, data) 1704 { 1705 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 1706 return cmpRangeManager.GetEntitiesByPlayer(data.viewedPlayer).some(unit => this.IdleUnitFilter(unit, data.idleClasses, data.excludeUnits).idle); 1707 }; 1708 1709 /** 1710 * Whether to filter an idle unit 1711 * 1712 * @param unit The unit to filter. 1713 * @param idleclasses Array of class names to include. 1714 * @param excludeUnits Array of units to exclude. 1715 * 1716 * Returns an object with the following fields: 1717 * - idle - true if the unit is considered idle by the filter, false otherwise. 1718 * - bucket - if idle, set to the index of the first matching idle class, undefined otherwise. 1719 */ 1720 GuiInterface.prototype.IdleUnitFilter = function(unit, idleClasses, excludeUnits) 1721 { 1722 let cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI); 1723 if (!cmpUnitAI || !cmpUnitAI.IsIdle() || cmpUnitAI.IsGarrisoned()) 1724 return { "idle": false }; 1725 1726 let cmpIdentity = Engine.QueryInterface(unit, IID_Identity); 1727 if(!cmpIdentity) 1728 return { "idle": false }; 1729 1730 let bucket = idleClasses.findIndex(elem => cmpIdentity.HasClass(elem)); 1731 if (bucket == -1 || excludeUnits.some(elem => elem == unit)) 1732 return { "idle": false }; 1674 1733 1675 return idleUnits;1734 return { "idle": true, "bucket": bucket }; 1676 1735 }; 1677 1736 1678 1737 GuiInterface.prototype.GetTradingRouteGain = function(player, data) … … let exposedFunctions = { 1899 1958 "GetFoundationSnapData": 1, 1900 1959 "PlaySound": 1, 1901 1960 "FindIdleUnits": 1, 1961 "HasIdleUnits": 1, 1902 1962 "GetTradingRouteGain": 1, 1903 1963 "GetTradingDetails": 1, 1904 1964 "CanCapture": 1, -
binaries/data/mods/public/gui/credits/texts/programming.json
-- 1.9.5.msysgit.0 From 4d2d7326216fe9242ab61ffeeb18c86b2c0cc122 Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" <clockwork-muse@outlook.com> Date: Sun, 1 May 2016 15:17:29 +0900 Subject: [PATCH] Add contribution credit. --- binaries/data/mods/public/gui/credits/texts/programming.json | 1 + 1 file changed, 1 insertion(+) diff --git a/binaries/data/mods/public/gui/credits/texts/programming.json b/binaries/data/mods/public/gui/credits/texts/programming.json index d7cb950..86dae45 100644
a b 39 39 {"nick": "Calvinh", "name": "Carl-Johan Höiby"}, 40 40 {"name": "Cédric Houbart"}, 41 41 {"nick": "Chakakhan", "name": "Kenny Long"}, 42 {"nick": "Clockwork-Muse", "name": "Stephen A. Imhoff"}, 42 43 {"nick": "Cracker78", "name": "Chad Heim"}, 43 44 {"nick": "Crynux", "name": "Stephen J. Fewer"}, 44 45 {"nick": "cwprogger"},