Ticket #3468: 3468.2.diff

File 3468.2.diff, 14.7 KB (added by Stan, 8 years ago)

Working version. You might notice that it overlays the capture bar. The only problems that will arise is with siege engines.

Line 
1Index: binaries/data/mods/public/gui/session/selection_details.js
2===================================================================
3--- binaries/data/mods/public/gui/session/selection_details.js (revision 17103)
4+++ binaries/data/mods/public/gui/session/selection_details.js (working copy)
5@@ -111,7 +111,23 @@
6 });
7 }
8
9- // TODO: Stamina
10+ // Stamina
11+ let player = Engine.GetPlayerID();
12+ if (entState.stamina && (entState.player == player || g_DevSettings.controlAll))
13+ {
14+ let unitStaminaBar = Engine.GetGUIObjectByName("staminaBar");
15+ let staminaSize = unitStaminaBar.size;
16+ staminaSize.rright = 100*Math.max(0, Math.min(1, entState.stamina.stamina / entState.stamina.maxStamina));
17+ unitStaminaBar.size = staminaSize;
18+
19+ Engine.GetGUIObjectByName("staminaStats").caption = sprintf(translate("%(stamina)s / %(maxStamina)s"), {
20+ stamina: Math.ceil(entState.stamina.stamina),
21+ maxStamina: entState.stamina.maxStamina
22+ });
23+ Engine.GetGUIObjectByName("staminaSection").hidden = false;
24+ }
25+ else
26+ Engine.GetGUIObjectByName("staminaSection").hidden = true;
27
28 // Experience
29 Engine.GetGUIObjectByName("experience").hidden = !entState.promotion;
30@@ -295,6 +311,8 @@
31 var maxCapturePoints = 0;
32 var capturePoints = (new Array(9)).fill(0);
33 var playerID = 0;
34+ let averageStamina = 0;
35+ let maxStamina = 0;
36
37 for (let i = 0; i < selection.length; i++)
38 {
39@@ -312,6 +330,11 @@
40 maxCapturePoints += entState.maxCapturePoints;
41 capturePoints = entState.capturePoints.map(function(v, i) { return v + capturePoints[i]; });
42 }
43+ if (entState.stamina)
44+ {
45+ averageStamina += entState.stamina.stamina;
46+ maxStamina += entState.stamina.maxStamina;
47+ }
48 }
49
50 Engine.GetGUIObjectByName("healthMultiple").hidden = averageHealth <= 0;
51@@ -357,8 +380,23 @@
52 Engine.GetGUIObjectByName("captureMultiple").tooltip = capturePointsTooltip;
53 }
54
55- // TODO: Stamina
56- // Engine.GetGUIObjectByName("staminaBarMultiple");
57+ if (averageStamina > 0)
58+ {
59+ let unitStaminaBar = Engine.GetGUIObjectByName("staminaBarMultiple");
60+ let staminaSize = unitStaminaBar.size;
61+ staminaSize.rtop = 100-100*Math.max(0, Math.min(1, averageStamina / maxStamina));
62+ unitStaminaBar.size = staminaSize;
63+
64+ let staminaLabel = "[font=\"sans-bold-13\"]" + translate("Stamina:") + "[/font]"
65+ let stamina = sprintf(translate("%(label)s %(current)s / %(max)s"), { label: staminaLabel, current: averageStamina, max: maxStamina });
66+ let staminaMultiple = Engine.GetGUIObjectByName("staminaMultiple");
67+ staminaMultiple.tooltip = stamina;
68+ staminaMultiple.hidden = false;
69+ }
70+ else
71+ {
72+ Engine.GetGUIObjectByName("staminaMultiple").hidden = true;
73+ }
74
75 Engine.GetGUIObjectByName("numberOfUnits").caption = selection.length;
76
77Index: binaries/data/mods/public/gui/session/selection_panels_middle/multiple_details_area.xml
78===================================================================
79--- binaries/data/mods/public/gui/session/selection_panels_middle/multiple_details_area.xml (revision 17103)
80+++ binaries/data/mods/public/gui/session/selection_panels_middle/multiple_details_area.xml (working copy)
81@@ -42,6 +42,14 @@
82 </repeat>
83 <object type="image" sprite="statsBarShaderVertical" ghost="true"/>
84 </object>
85+ <!-- Stamina bar -->
86+ <object size="15 0 22 100%" type="image" name="staminaMultiple" tooltip_style="sessionToolTipBold">
87+ <translatableAttribute id="tooltip">Stamina</translatableAttribute>
88+ <object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
89+ <object type="image" sprite="staminaBackground" ghost="true"/>
90+ <object type="image" sprite="staminaForeground" ghost="true" name="staminaBarMultiple"/>
91+ <object type="image" sprite="statsBarShaderVertical" ghost="true"/>
92+ </object>
93 </object>
94 </object>
95
96Index: binaries/data/mods/public/gui/session/selection_panels_middle/single_details_area.xml
97===================================================================
98--- binaries/data/mods/public/gui/session/selection_panels_middle/single_details_area.xml (revision 17103)
99+++ binaries/data/mods/public/gui/session/selection_panels_middle/single_details_area.xml (working copy)
100@@ -35,6 +35,20 @@
101 </object>
102 </object>
103
104+ <!-- Stamina bar -->
105+ <object size="88 28 100% 52" name="staminaSection">
106+ <object size="0 0 100% 16" name="staminaLabel" type="text" style="StatsTextLeft" ghost="true">
107+ <translatableAttribute id="tooltip">Stamina:</translatableAttribute>
108+ </object>
109+ <object size="0 0 100% 16" name="staminaStats" type="text" style="StatsTextRight" ghost="true"/>
110+ <object size="1 16 100% 23" name="stamina" type="image">
111+ <object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/>
112+ <object type="image" sprite="staminaBackground" ghost="true"/>
113+ <object type="image" sprite="staminaForeground" ghost="true" name="staminaBar"/>
114+ <object type="image" sprite="statsBarShaderHorizontal" ghost="true"/>
115+ </object>
116+ </object>
117+
118 <!-- Resource bar -->
119 <object size="88 28 100% 52" name="resourceSection">
120 <object size="0 0 100% 16" name="resourceLabel" type="text" style="StatsTextLeft" ghost="true"/>
121Index: binaries/data/mods/public/simulation/components/GuiInterface.js
122===================================================================
123--- binaries/data/mods/public/simulation/components/GuiInterface.js (revision 17103)
124+++ binaries/data/mods/public/simulation/components/GuiInterface.js (working copy)
125@@ -238,6 +238,7 @@
126 "rallyPoint": null,
127 "resourceCarrying": null,
128 "rotation": null,
129+ "stamina": null,
130 "trader": null,
131 "unitAI": null,
132 "visibility": null,
133@@ -410,7 +411,16 @@
134 "hasRaisedAlert": cmpAlertRaiser.HasRaisedAlert(),
135 };
136 }
137-
138+ var cmpStamina = Engine.QueryInterface(ent, IID_Stamina);
139+
140+ if (cmpStamina)
141+ {
142+ ret.stamina = {
143+ "stamina": cmpStamina.GetStamina(),
144+ "maxStamina": cmpStamina.GetMaxStamina(),
145+ };
146+ }
147+
148 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
149 ret.visibility = cmpRangeManager.GetLosVisibility(ent, player);
150
151Index: binaries/data/mods/public/simulation/components/interfaces/Stamina.js
152===================================================================
153--- binaries/data/mods/public/simulation/components/interfaces/Stamina.js (revision 17103)
154+++ binaries/data/mods/public/simulation/components/interfaces/Stamina.js (working copy)
155@@ -1 +1,6 @@
156 Engine.RegisterInterface("Stamina");
157+
158+
159+// Message of the form { "from": 100, "to", 90 },
160+// sent whenever stamina changes.
161+Engine.RegisterMessageType("StaminaChanged");
162\ No newline at end of file
163Index: binaries/data/mods/public/simulation/components/Stamina.js
164===================================================================
165--- binaries/data/mods/public/simulation/components/Stamina.js (revision 17103)
166+++ binaries/data/mods/public/simulation/components/Stamina.js (working copy)
167@@ -1,12 +1,99 @@
168 function Stamina() {}
169
170 Stamina.prototype.Schema =
171- "<element name='Max' a:help='Maximum stamina (msecs of running)'>" +
172- "<data type='positiveInteger'/>" +
173- "</element>";
174+ "<element name='Max' a:help='Maximum stamina'>" +
175+ "<ref name='nonNegativeDecimal'/>" +
176+ "</element>" +
177+ "<element name='RegenRate' a:help='Stamina regeneration rate per second.'>" +
178+ "<ref name='nonNegativeDecimal'/>" +
179+ "</element>" +
180+ "<optional>" +
181+ "<element name='Initial' a:help='Initial stamina. Default if unspecified is equal to 0'>" +
182+ "<ref name='nonNegativeDecimal'/>" +
183+ "</element>" +
184+ "</optional>";
185
186-/*
187- * TODO: this all needs to be designed and implemented
188- */
189-
190-Engine.RegisterComponentType(IID_Stamina, "Stamina", Stamina);
191+Stamina.prototype.Init = function()
192+{
193+ this.maxStamina = +this.template.Max;
194+ this.regenRate = +this.template.RegenRate;
195+
196+ this.stamina = +(this.template.Initial || 0);
197+
198+ this.CheckRegenTimer();
199+};
200+
201+Stamina.prototype.GetStamina = function()
202+{
203+ return this.stamina;
204+};
205+
206+Stamina.prototype.GetMaxStamina = function()
207+{
208+ return this.maxStamina;
209+};
210+
211+Stamina.prototype.CheckRegenTimer = function()
212+{
213+ if ((this.stamina == this.maxStamina && this.regenRate > 0) || (this.stamina == 0 && this.regenRate < 0))
214+ {
215+ // We don't need to regenerate stamina
216+ if (this.regenTimer)
217+ {
218+ var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
219+ cmpTimer.CancelTimer(this.regenTimer);
220+ this.regenTimer = undefined;
221+ }
222+ return;
223+ }
224+
225+ // We need to regenerate, enable a timer if one doesn't exist
226+ if (this.regenTimer)
227+ return;
228+
229+ var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
230+ this.regenTimer = cmpTimer.SetInterval(this.entity, IID_Stamina, "UpdateStamina", 1000, 1000, null);
231+};
232+
233+Stamina.prototype.ToggleStaminaConsumer = function(enabled, costRate)
234+{
235+ if (costRate >= 0)
236+ {
237+ warn("Activated stamina consumer with wrong cost");
238+ return;
239+ }
240+
241+ if (enabled)
242+ {
243+ if (this.regenRate > 0)
244+ this.regenRate = 0;
245+ this.regenRate += costRate;
246+ }
247+ else
248+ {
249+ this.regenRate -= costRate;
250+ if (this.regenRate >= 0)
251+ this.regenRate = +this.template.RegenRate;
252+ }
253+ this.CheckRegenTimer();
254+};
255+
256+Stamina.prototype.UpdateStamina = function()
257+{
258+ if (this.regenRate == 0)
259+ return;
260+
261+ let oldStamina = this.stamina;
262+ this.stamina += this.regenRate;
263+ if (this.stamina > this.maxStamina)
264+ this.stamina = this.maxStamina;
265+
266+ Engine.PostMessage(this.entity, MT_StaminaChanged, { "from": oldStamina, "to": this.stamina });
267+};
268+
269+Stamina.prototype.OnStaminaChanged = function(msg)
270+{
271+ this.CheckRegenTimer();
272+};
273+
274+Engine.RegisterComponentType(IID_Stamina, "Stamina", Stamina);
275Index: binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml
276===================================================================
277--- binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml (revision 17103)
278+++ binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml (working copy)
279@@ -91,6 +91,8 @@
280 </Sound>
281 <Stamina>
282 <Max>2000</Max>
283+ <RegenRate>20</RegenRate>
284+ <Initial>1000</Initial>
285 </Stamina>
286 <StatusBars>
287 <HeightOffset>6.5</HeightOffset>
288Index: binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry.xml
289===================================================================
290--- binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry.xml (revision 17103)
291+++ binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry.xml (working copy)
292@@ -55,7 +55,9 @@
293 </SoundGroups>
294 </Sound>
295 <Stamina>
296+ <RegenRate>20</RegenRate>
297+ <Initial>1000</Initial>
298 </Stamina>
299 <StatusBars>
300 <HeightOffset>6.5</HeightOffset>
301Index: binaries/data/mods/public/simulation/templates/template_unit_champion_elephant.xml
302===================================================================
303--- binaries/data/mods/public/simulation/templates/template_unit_champion_elephant.xml (revision 17103)
304+++ binaries/data/mods/public/simulation/templates/template_unit_champion_elephant.xml (working copy)
305@@ -55,6 +55,8 @@
306 </Sound>
307 <Stamina>
308 <Max>2500</Max>
309+ <RegenRate>20</RegenRate>
310+ <Initial>1000</Initial>
311 </Stamina>
312 <StatusBars>
313 <HeightOffset>6.5</HeightOffset>
314Index: binaries/data/mods/public/simulation/templates/template_unit_champion_infantry.xml
315===================================================================
316--- binaries/data/mods/public/simulation/templates/template_unit_champion_infantry.xml (revision 17103)
317+++ binaries/data/mods/public/simulation/templates/template_unit_champion_infantry.xml (working copy)
318@@ -46,6 +46,7 @@
319 </Sound>
320 <Stamina>
321 <Max>1500</Max>
322+ <RegenRate>20</RegenRate>
323 </Stamina>
324 <UnitMotion>
325 <WalkSpeed>8.5</WalkSpeed>
326Index: binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry.xml
327===================================================================
328--- binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry.xml (revision 17103)
329+++ binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry.xml (working copy)
330@@ -47,6 +47,8 @@
331 </Sound>
332 <Stamina>
333 <Max>2500</Max>
334+ <RegenRate>20</RegenRate>
335+ <Initial>1000</Initial>
336 </Stamina>
337 <StatusBars>
338 <HeightOffset>6.5</HeightOffset>
339Index: binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_pikeman.xml
340===================================================================
341--- binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_pikeman.xml (revision 17103)
342+++ binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_pikeman.xml (working copy)
343@@ -33,9 +33,6 @@
344 <wood>10</wood>
345 <metal>10</metal>
346 </Loot>
347- <Stamina>
348- <Max>1200</Max>
349- </Stamina>
350 <UnitMotion>
351 <WalkSpeed>8.5</WalkSpeed>
352 <Run>
353Index: binaries/data/mods/public/simulation/templates/template_unit_infantry.xml
354===================================================================
355--- binaries/data/mods/public/simulation/templates/template_unit_infantry.xml (revision 17103)
356+++ binaries/data/mods/public/simulation/templates/template_unit_infantry.xml (working copy)
357@@ -120,6 +120,7 @@
358 </Sound>
359 <Stamina>
360 <Max>1000</Max>
361+ <RegenRate>15</RegenRate>
362 </Stamina>
363 <UnitMotion>
364 <WalkSpeed>9</WalkSpeed>
365Index: binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
366===================================================================
367--- binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml (revision 17103)
368+++ binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml (working copy)
369@@ -95,6 +95,7 @@
370 </Sound>
371 <Stamina>
372 <Max>500</Max>
373+ <RegenRate>5</RegenRate>
374 </Stamina>
375 <UnitAI>
376 <AlertReactiveLevel>1</AlertReactiveLevel>