Ticket #1802: hero_button.3.patch

File hero_button.3.patch, 9.0 KB (added by alpha123, 11 years ago)

Fix a couple of little bugs with the hotkey. Should be very solid now.

Line 
1Index: binaries/data/mods/public/gui/common/global.xml
2
3===================================================================
4
5--- binaries/data/mods/public/gui/common/global.xml (revision 13276)
6
7+++ binaries/data/mods/public/gui/common/global.xml (working copy)
8
9@@ -26,7 +26,7 @@
10
11 sprite="colour: 0 0 0 200"
12
13 font="mono-stroke-10"
14
15 textcolor="white"
16
17- size="5 35 80 55"
18
19+ size="100%-80 70 100%-10 90"
20
21 z="199"
22
23 >
24
25 <action on="Tick"><![CDATA[
26
27Index: binaries/data/mods/public/gui/session/session.js
28
29===================================================================
30
31--- binaries/data/mods/public/gui/session/session.js (revision 13276)
32
33+++ binaries/data/mods/public/gui/session/session.js (working copy)
34
35@@ -369,6 +369,7 @@
36
37 if (g_ShowAllStatusBars)
38
39 recalculateStatusBarDisplay();
40
41
42
43+ updateHero(simState);
44
45 updateGroups();
46
47 updateDebug(simState);
48
49 updatePlayerDisplay(simState);
50
51@@ -383,6 +384,48 @@
52
53 global.music.setState(global.music.states[battleState]);
54
55 }
56
57
58
59+function updateHero(simState)
60
61+{
62
63+ var playerState = simState.players[Engine.GetPlayerID()];
64
65+
66
67+ if (playerState.heroes.length > 0)
68
69+ {
70
71+ var heroImage = getGUIObjectByName("unitHeroImage");
72
73+ var heroState = Engine.GuiInterfaceCall("GetEntityState", playerState.heroes[0]);
74
75+ var template = GetTemplateData(heroState.template);
76
77+ heroImage.sprite = "stretched:session/portraits/" + template.icon;
78
79+
80
81+ var heroButton = getGUIObjectByName("unitHeroButton");
82
83+ heroButton.onpress = (function(e) { return function() { g_Selection.reset(); g_Selection.addList([e]); } })(playerState.heroes[0]);
84
85+ heroButton.ondoublepress = (function(e) { return function() { selectAndMoveTo(e) }; })(playerState.heroes[0]);
86
87+ heroButton.hidden = false;
88
89+
90
91+ // Setup tooltip
92
93+
94
95+ var name = "[font=\"serif-bold-16\"]" + template.name.specific + "[/font] ";
96
97+ var health = "[font=\"serif-bold-13\"]Health:[/font] " + heroState.hitpoints + "/" + heroState.maxHitpoints;
98
99+
100
101+ var type = "";
102
103+ if (heroState.attack)
104
105+ type = heroState.attack.type + " ";
106
107+ var attack = "[font=\"serif-bold-13\"]" + type + "Attack:[/font] " + damageTypeDetails(heroState.attack);
108
109+ // Show max attack range if ranged attack, also convert to tiles (4m per tile)
110
111+ if (heroState.attack && heroState.attack.type == "Ranged")
112
113+ attack += ", [font=\"serif-bold-13\"]Range:[/font] " + Math.round(heroState.attack.maxRange/4);
114
115+
116
117+ var armor = "[font=\"serif-bold-13\"]Armor:[/font] " + damageTypeDetails(heroState.armour);
118
119+ var extra = template.tooltip;
120
121+
122
123+ heroButton.tooltip = name + "\n" + health + "\n" + attack + "\n" + armor + "\n" + extra;
124
125+ }
126
127+ else
128
129+ {
130
131+ var heroButton = getGUIObjectByName("unitHeroButton");
132
133+ heroButton.hidden = true;
134
135+ }
136
137+
138
139+};
140
141+
142
143 function updateGroups()
144
145 {
146
147 var guiName = "Group";
148
149Index: binaries/data/mods/public/gui/session/session.xml
150
151===================================================================
152
153--- binaries/data/mods/public/gui/session/session.xml (revision 13327)
154
155+++ binaries/data/mods/public/gui/session/session.xml (working copy)
156
157@@ -132,11 +218,16 @@
158
159 <action on="Press">addTrainingByPosition(6);</action>
160 </object>
161
162- <!-- Find idle warrior - TODO: Potentially move this to own UI button? -->
163+ <!-- Find idle warrior - TODO: Potentially move this to own UI button? -->
164 <object hotkey="selection.idlewarrior">
165 <action on="Press">findIdleUnit(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action>
166 </object>
167
168+ <!-- Cycle through living heroes. -->
169+ <object hotkey="selection.hero">
170+ <action on="Press">cycleHeroes();</action>
171+ </object>
172+
173 <!-- ================================ ================================ -->
174 <!-- Developer / Debug items -->
175 <!-- ================================ ================================ -->
176@@ -666,6 +757,20 @@
177 </object>
178
179 <!-- ================================ ================================ -->
180+ <!-- Hero Selection -->
181+ <!-- ================================ ================================ -->
182+ <object
183+ name="unitHeroPanel"
184+ size="0% 5% 0%+50 5%+50"
185+ >
186+ <object name="unitHeroButton" size="0 0 50 50" type="button" hidden="false" style="iconButton"
187+ tooltip_style="sessionToolTip" tooltip="Attack and Armor">
188+ <object name="unitHeroImage" size="5 5 100%-5 100%-5" type="image" ghost="true"/>
189+ </object>
190+
191+ </object>
192+
193+ <!-- ================================ ================================ -->
194 <!-- Unit Selection Groups -->
195 <!-- ================================ ================================ -->
196 <objectIndex: binaries/data/mods/public/simulation/components/GuiInterface.js
197===================================================================
198--- binaries/data/mods/public/simulation/components/GuiInterface.js (revision 13276)
199+++ binaries/data/mods/public/simulation/components/GuiInterface.js (working copy)
200@@ -79,6 +79,7 @@
201 "popCount": cmpPlayer.GetPopulationCount(),
202 "popLimit": cmpPlayer.GetPopulationLimit(),
203 "popMax": cmpPlayer.GetMaxPopulation(),
204+ "heroes": cmpPlayer.GetHeroes(),
205 "resourceCounts": cmpPlayer.GetResourceCounts(),
206 "trainingBlocked": cmpPlayer.IsTrainingBlocked(),
207 "state": cmpPlayer.GetState(),
208Index: binaries/data/mods/public/simulation/components/Player.js
209===================================================================
210--- binaries/data/mods/public/simulation/components/Player.js (revision 13276)
211+++ binaries/data/mods/public/simulation/components/Player.js (working copy)
212@@ -19,7 +19,7 @@
213 "metal": 300,
214 "stone": 300
215 };
216-
217+
218 this.team = -1; // team number of the player, players on the same team will always have ally diplomatic status - also this is useful for team emblems, scoring, etc.
219 this.teamsLocked = false;
220 this.state = "active"; // game state - one of "active", "defeated", "won"
221@@ -32,6 +32,7 @@
222 this.isAI = false;
223 this.cheatsEnabled = true;
224 this.cheatTimeMultiplier = 1;
225+ this.heroes = [];
226 };
227
228 Player.prototype.SetPlayerID = function(id)
229@@ -109,6 +110,11 @@
230 return Math.round(ApplyTechModificationsToPlayer("Player/MaxPopulation", this.maxPop, this.entity));
231 };
232
233+Player.prototype.GetHeroes = function()
234+{
235+ return this.heroes;
236+};
237+
238 Player.prototype.IsTrainingBlocked = function()
239 {
240 return this.trainingBlocked;
241@@ -446,10 +452,11 @@
242 Player.prototype.OnGlobalOwnershipChanged = function(msg)
243 {
244 var isConquestCritical = false;
245+ var cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity);
246+
247 // Load class list only if we're going to need it
248 if (msg.from == this.playerID || msg.to == this.playerID)
249 {
250- var cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity);
251 if (cmpIdentity)
252 {
253 isConquestCritical = cmpIdentity.HasClass("ConquestCritical");
254@@ -465,6 +472,21 @@
255 this.popUsed -= cost.GetPopCost();
256 this.popBonuses -= cost.GetPopBonus();
257 }
258+
259+ if (cmpIdentity && cmpIdentity.HasClass("Hero"))
260+ {
261+ //Remove from Heroes list
262+ var index = this.heroes.indexOf(msg.entity);
263+ if (index >= 0)
264+ {
265+ this.heroes.splice(index, 1);
266+ }
267+ else
268+ {
269+ // Why is not the Hero in the list?
270+ }
271+ }
272+
273 }
274 if (msg.to == this.playerID)
275 {
276@@ -476,6 +498,11 @@
277 this.popUsed += cost.GetPopCost();
278 this.popBonuses += cost.GetPopBonus();
279 }
280+
281+ if (cmpIdentity && cmpIdentity.HasClass("Hero"))
282+ {
283+ this.heroes.push(msg.entity);
284+ }
285 }
286 };
287
288Index: binaries/data/mods/public/gui/session/input.js
289===================================================================
290--- binaries/data/mods/public/gui/session/input.js (revision 13327)
291+++ binaries/data/mods/public/gui/session/input.js (working copy)
292@@ -1982,6 +2009,37 @@
293 resetIdleUnit();
294 }
295
296+function cycleHeroes() {
297+ var playerState = Engine.GuiInterfaceCall("GetSimulationState").players[Engine.GetPlayerID()];
298+ if (playerState.heroes.length < 1)
299+ return;
300+
301+ var append = Engine.HotkeyIsPressed("selection.add"), selectall = Engine.HotkeyIsPressed("selection.offscreen"),
302+ selection = g_Selection.toList(), currentIndex, newIndex = 0, newList = [];
303+
304+ if (selectall)
305+ newList = playerState.heroes;
306+ else if (append)
307+ {
308+ // Find the first hero not in the selection.
309+ newIndex = playerState.heroes.indexOf(
310+ Math.min.apply(Math, playerState.heroes.filter(function(hero) selection.indexOf(hero) == -1)));
311+ }
312+ else if (selection.length == 1 && (currentIndex = playerState.heroes.indexOf(selection[0])) > -1)
313+ {
314+ newIndex = Math.min(currentIndex + 1, playerState.heroes.length);
315+ if (newIndex == playerState.heroes.length)
316+ newIndex = 0;
317+ }
318+
319+ if (!newList.length && newIndex > -1)
320+ newList = [playerState.heroes[newIndex]];
321+
322+ if (!append)
323+ g_Selection.reset();
324+ g_Selection.addList(newList);
325+}
326+
327 function stopUnits(entities)
328 {
329 Engine.PostNetworkCommand({ "type": "stop", "entities": entities, "queued": false });