1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace eXpansion\Bundle\WidgetBestCheckpoints\Plugins\Gui; |
4
|
|
|
|
5
|
|
|
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface; |
6
|
|
|
use eXpansion\Framework\Core\Model\Gui\Widget; |
7
|
|
|
use eXpansion\Framework\Core\Model\Gui\WidgetFactoryContext; |
8
|
|
|
use eXpansion\Framework\Core\Plugins\Gui\WidgetFactory; |
9
|
|
|
use eXpansion\Framework\Gui\Components\Label; |
10
|
|
|
use FML\Controls\Frame; |
11
|
|
|
use FML\Controls\Quad; |
12
|
|
|
use FML\Script\ScriptLabel; |
13
|
|
|
|
14
|
|
|
class BestCheckpointsWidgetFactory extends WidgetFactory |
15
|
|
|
{ |
16
|
|
|
const rowCount = 2; |
17
|
|
|
const columnCount = 10; |
18
|
|
|
|
19
|
|
|
/** @var UpdaterWidgetFactory */ |
20
|
|
|
protected $updaterWidgetFactory; |
21
|
|
|
|
22
|
|
|
/*** |
23
|
|
|
* MenuFactory constructor. |
24
|
|
|
* |
25
|
|
|
* @param $name |
26
|
|
|
* @param $sizeX |
27
|
|
|
* @param $sizeY |
28
|
|
|
* @param null $posX |
29
|
|
|
* @param null $posY |
30
|
|
|
* @param WidgetFactoryContext $context |
31
|
|
|
* @param UpdaterWidgetFactory $updaterWidgetFactory |
32
|
|
|
*/ |
33
|
|
|
public function __construct( |
34
|
|
|
$name, |
35
|
|
|
$sizeX, |
36
|
|
|
$sizeY, |
37
|
|
|
$posX, |
38
|
|
|
$posY, |
39
|
|
|
WidgetFactoryContext $context, |
40
|
|
|
UpdaterWidgetFactory $updaterWidgetFactory |
41
|
|
|
) { |
42
|
|
|
parent::__construct($name, $sizeX, $sizeY, $posX, $posY, $context); |
43
|
|
|
|
44
|
|
|
$this->updaterWidgetFactory = $updaterWidgetFactory; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @param Widget|ManialinkInterface $manialink |
49
|
|
|
*/ |
50
|
|
|
protected function createContent(ManialinkInterface $manialink) |
51
|
|
|
{ |
52
|
|
|
$elementCount = 0; |
53
|
|
|
$rows = $this->uiFactory->createLayoutRow(0, 0, [], 0.5); |
54
|
|
|
$localVariable = $this->updaterWidgetFactory->getVariable('LocalRecordCheckpoints')->getVariableName(); |
55
|
|
|
$dediVariable = $this->updaterWidgetFactory->getVariable('DedimaniaCheckpoints')->getVariableName(); |
56
|
|
|
$localHolder = $this->updaterWidgetFactory->getVariable('LocalRecordHolder')->getVariableName(); |
57
|
|
|
$dediHolder = $this->updaterWidgetFactory->getVariable('DedimaniaHolder')->getVariableName(); |
58
|
|
|
|
59
|
|
|
for ($i = 0; $i < self::rowCount; $i++) { |
60
|
|
|
$elements = []; |
61
|
|
|
for ($c = 0; $c < self::columnCount; $c++) { |
62
|
|
|
if ($elementCount == 0) { |
63
|
|
|
$dropdown = $this->uiFactory->createDropdown("select", [ |
64
|
|
|
"Live 1" => "1", |
65
|
|
|
"Local 1" => "2", |
66
|
|
|
"Dedi 1" => "3", |
67
|
|
|
], |
68
|
|
|
0, |
69
|
|
|
false); |
70
|
|
|
$dropdown->setWidth(18)->setId("uiDropdown"); |
71
|
|
|
$elements[] = $dropdown; |
72
|
|
|
$elements[] = $this->createNickBox(); |
73
|
|
|
} else { |
74
|
|
|
$elements[] = $this->createColumnBox($elementCount); |
75
|
|
|
} |
76
|
|
|
$elementCount++; |
77
|
|
|
} |
78
|
|
|
$line = $this->uiFactory->createLayoutRow(0, 0, $elements, 0.5); |
79
|
|
|
|
80
|
|
|
$rows->addChild($line); |
81
|
|
|
} |
82
|
|
|
$manialink->addChild($rows); |
83
|
|
|
|
84
|
|
|
$elementCount -= 1; |
85
|
|
|
/** |
86
|
|
|
* Functions |
87
|
|
|
*/ |
88
|
|
|
$manialink->getFmlManialink()->getScript()->addScriptFunction("", |
89
|
|
|
<<<EOL |
90
|
|
|
|
91
|
|
|
***onSelectDropdown*** |
92
|
|
|
*** |
93
|
|
|
declare Integer BestCp_Mode for LocalUser = 0; |
94
|
|
|
BestCp_Mode = TextLib::ToInteger(uiDropdown.DataAttributeGet("selected")); |
95
|
|
|
Refresh(); |
96
|
|
|
*** |
97
|
|
|
|
98
|
|
|
|
99
|
|
|
Text FormatSec(Real sec, Text color, Text highlite) { |
100
|
|
|
if (sec > 10.) { |
101
|
|
|
return highlite ^ TextLib::FormatReal(sec,3,False,False); |
102
|
|
|
} |
103
|
|
|
return color ^ 0 ^ highlite ^ TextLib::FormatReal(sec,3,False,False); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
Text TimeToText(Integer intime) { |
107
|
|
|
declare Text highlite = "\$eff"; |
108
|
|
|
declare Text color = "\$bcc"; |
109
|
|
|
declare time = MathLib::Abs(intime); |
110
|
|
|
declare Integer cent = time % 1000; |
111
|
|
|
declare Integer sec2 = (time / 1000) % 60; |
112
|
|
|
declare Real sec = 1. * sec2 + cent * 0.001; |
113
|
|
|
declare Integer min = (time / 60000) % 60; |
114
|
|
|
declare Integer hour = time / 3600000; |
115
|
|
|
declare Text sign = ""; |
116
|
|
|
if (intime < 0) { |
117
|
|
|
sign = "-"; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
if (hour > 0) { |
121
|
|
|
return highlite ^ sign ^ hour ^ "'" ^ TextLib::FormatInteger(min,2) ^ ":" ^ FormatSec(sec, highlite,highlite); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
if (min == 0) { |
125
|
|
|
return color ^ sign ^ "00:" ^ FormatSec(sec, color, highlite); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
if (min > 10) { |
129
|
|
|
return highlite ^ sign ^ min ^ ":" ^ FormatSec(sec, highlite, highlite); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
return color ^ sign ^ 0 ^ highlite ^ min ^ ":" ^ FormatSec(sec, highlite, highlite); |
133
|
|
|
|
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
|
137
|
|
|
Void UpdateCp(Integer _Index, Integer _Score, Boolean _Animate) { |
138
|
|
|
declare Integer ElementCount for Page = $elementCount; |
139
|
|
|
if (_Index > ElementCount) { |
140
|
|
|
return; |
141
|
|
|
} |
142
|
|
|
{$this->updaterWidgetFactory->getScriptInitialization()} |
143
|
|
|
declare Integer[Integer] MapBestCheckpoints for Page = Integer[Integer]; |
144
|
|
|
declare CMlLabel Label <=> (Page.GetFirstChild("Cp_"^ (_Index+1)) as CMlLabel); |
145
|
|
|
declare CMlQuad Bg <=> (Page.GetFirstChild("Bg_"^ (_Index+1)) as CMlQuad); |
146
|
|
|
declare CMlLabel HolderLabel <=> (Page.GetFirstChild("RecordHolder") as CMlLabel); |
147
|
|
|
declare Integer BestCp_Mode for LocalUser = 0; |
148
|
|
|
declare Text Color = "\$fff"; |
149
|
|
|
Bg.BgColor = TextLib::ToColor("000"); |
150
|
|
|
|
151
|
|
|
declare Integer Compare = 99999999; |
152
|
|
|
|
153
|
|
|
switch (BestCp_Mode) { |
154
|
|
|
case 0: { |
155
|
|
|
if (Scores[0].BestLap.Time > -1) { |
156
|
|
|
HolderLabel.Value = Scores[0].User.Name; |
157
|
|
|
} else { |
158
|
|
|
HolderLabel.Value = "-"; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
if (MapBestCheckpoints.existskey(_Index)) { |
162
|
|
|
Compare = MapBestCheckpoints[_Index]; |
163
|
|
|
} else { |
164
|
|
|
Compare = 99999999; |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
case 1: { |
168
|
|
|
HolderLabel.Value = $localHolder; |
169
|
|
|
if ($localVariable.existskey(_Index)) { |
170
|
|
|
Compare = {$localVariable}[_Index]; |
171
|
|
|
} else { |
172
|
|
|
Compare = 99999999; |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
case 2: { |
176
|
|
|
HolderLabel.Value = $dediHolder; |
177
|
|
|
if ($dediVariable.existskey(_Index)) { |
178
|
|
|
Compare = {$dediVariable}[_Index]; |
179
|
|
|
} else { |
180
|
|
|
Compare = 99999999; |
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
if (_Score == 99999999) { |
186
|
|
|
if ( Compare > 0 && Compare != 99999999 ) { |
187
|
|
|
Label.Value = "\$fff\$o" ^ (_Index+1) ^ " \$o\$bcc" ^ TimeToText(Compare); |
188
|
|
|
} else { |
189
|
|
|
Label.Value = "\$fff\$o" ^ (_Index+1) ^ " \$o\$bcc --:--.---"; |
190
|
|
|
} |
191
|
|
|
} else { |
192
|
|
|
if (_Score < Compare) { |
193
|
|
|
Bg.BgColor = TextLib::ToColor("00f"); |
194
|
|
|
Color = "\$fff"; |
195
|
|
|
} else { |
196
|
|
|
Bg.BgColor = TextLib::ToColor("f00"); |
197
|
|
|
Color = "\$fff"; |
198
|
|
|
} |
199
|
|
|
// Label.Value = "\$fff\$o" ^ (_Index+1) ^ " \$o\$bcc" ^ TimeToText(Compare) ^ "\$fff" ^ " diff: " ^ Color ^ TimeToText(_Score - Compare); |
200
|
|
|
Label.Value = "\$fff\$o" ^ (_Index+1) ^ " \$o\$bcc" ^ TimeToText(_Score - Compare); |
201
|
|
|
} |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
Void Refresh() { |
205
|
|
|
{$this->updaterWidgetFactory->getScriptInitialization()} |
206
|
|
|
|
207
|
|
|
declare Integer ElementCount for Page = $elementCount; |
208
|
|
|
declare Integer[Integer] MyCheckpoints for Page = Integer[Integer]; |
209
|
|
|
declare Integer[Integer] MapBestCheckpoints for Page = Integer[Integer]; |
210
|
|
|
declare Integer BestCp_Mode for LocalUser = 0; |
211
|
|
|
|
212
|
|
|
for (k, 0, (ElementCount-1)) { |
213
|
|
|
if (MyCheckpoints.existskey(k)) { |
214
|
|
|
UpdateCp(k, MyCheckpoints[k], False); |
215
|
|
|
} else { |
216
|
|
|
UpdateCp(k, 99999999, False); |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
Void HideCp(Integer _Index) { |
223
|
|
|
(Page.GetFirstChild("Cp_"^ _Index) as CMlLabel).Hide(); |
224
|
|
|
(Page.GetFirstChild("Bg_"^ _Index) as CMlFrame).Hide(); |
225
|
|
|
} |
226
|
|
|
EOL |
227
|
|
|
|
228
|
|
|
); |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* ON INIT |
232
|
|
|
*/ |
233
|
|
|
$manialink->getFmlManialink()->getScript()->addCustomScriptLabel(ScriptLabel::OnInit, |
234
|
|
|
<<<EOL |
235
|
|
|
declare Integer ElementCount for Page = $elementCount; |
236
|
|
|
declare Integer BestCp_Mode for LocalUser = 0; |
237
|
|
|
declare CMlFrame Dropdown = (Page.GetFirstChild("uiDropdown") as CMlFrame); |
238
|
|
|
declare Integer[Integer] MyCheckpoints for Page = Integer[Integer]; |
239
|
|
|
declare Integer[Integer] MapBestCheckpoints for Page = Integer[Integer]; |
240
|
|
|
|
241
|
|
|
{$this->updaterWidgetFactory->getScriptInitialization()} |
242
|
|
|
|
243
|
|
|
declare Integer[Integer] CompareCheckpoints for Page = Integer[Integer]; |
244
|
|
|
declare Integer MapBestTime = 99999999; |
245
|
|
|
|
246
|
|
|
// clear |
247
|
|
|
for (i, 0, (ElementCount-1)) { |
248
|
|
|
MapBestCheckpoints[i] = 99999999; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
// hide checkpoints not needed |
252
|
|
|
for (i, (MapCheckpointPos.count+2), (ElementCount)) { |
253
|
|
|
HideCp(i); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
if (InputPlayer != Null) { |
257
|
|
|
foreach (k => i in InputPlayer.CurLap.Checkpoints) { |
258
|
|
|
MyCheckpoints[k] = i; |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
if (Scores.count > 0) { |
263
|
|
|
if (Scores[0].BestLap.Time != -1) { |
264
|
|
|
MapBestTime = Scores[0].BestLap.Time; |
265
|
|
|
foreach (k => i in Scores[0].BestLap.Checkpoints) { |
266
|
|
|
MapBestCheckpoints[k] = i; |
267
|
|
|
} |
268
|
|
|
} |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
Refresh(); |
272
|
|
|
|
273
|
|
|
Dropdown.DataAttributeSet("selected", ""^BestCp_Mode); |
274
|
|
|
uiRenderDropdown(Dropdown); |
275
|
|
|
|
276
|
|
|
EOL |
277
|
|
|
); |
278
|
|
|
|
279
|
|
|
/** |
280
|
|
|
* Loop |
281
|
|
|
*/ |
282
|
|
|
$manialink->getFmlManialink()->getScript()->addCustomScriptLabel(ScriptLabel::Loop, |
283
|
|
|
<<<EOL |
284
|
|
|
|
285
|
|
|
// handle new record |
286
|
|
|
{$this->updaterWidgetFactory->getScriptOnChange('Refresh();')} |
287
|
|
|
|
288
|
|
|
foreach (RaceEvent in RaceEvents) { |
289
|
|
|
if (GUIPlayer == RaceEvent.Player && RaceEvent.Type == CTmRaceClientEvent::EType::Respawn) { |
290
|
|
|
if (GUIPlayer.RaceState == CTmMlPlayer::ERaceState::BeforeStart) { |
291
|
|
|
MyCheckpoints = Integer[Integer]; |
292
|
|
|
Refresh(); |
293
|
|
|
} |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
if (RaceEvent.Type == CTmRaceClientEvent::EType::WayPoint) { |
297
|
|
|
|
298
|
|
|
if (RaceEvent.IsEndRace || RaceEvent.IsEndLap) { |
299
|
|
|
|
300
|
|
|
if (RaceEvent.LapTime < MapBestTime) { |
301
|
|
|
MapBestTime = RaceEvent.LapTime; |
302
|
|
|
if (GUIPlayer == RaceEvent.Player) { |
303
|
|
|
MyCheckpoints[RaceEvent.CheckpointInLap] = RaceEvent.LapTime; |
304
|
|
|
MapBestCheckpoints = MyCheckpoints; |
305
|
|
|
MyCheckpoints = Integer[Integer]; |
306
|
|
|
Refresh(); |
307
|
|
|
} else { |
308
|
|
|
foreach (k => i in RaceEvent.Player.Score.BestLap.Checkpoints) { |
309
|
|
|
MapBestCheckpoints[k] = i; |
310
|
|
|
} |
311
|
|
|
Refresh(); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
|
315
|
|
|
} else { |
316
|
|
|
if (GUIPlayer == RaceEvent.Player && $localVariable.count > 0 && |
317
|
|
|
MapBestTime != 99999999) { |
318
|
|
|
if (RaceEvent.IsEndLap && RaceEvent.IsEndRace == False) { |
319
|
|
|
MyCheckpoints = Integer[Integer]; |
320
|
|
|
Refresh(); |
321
|
|
|
} else { |
322
|
|
|
UpdateCp(RaceEvent.CheckpointInLap, RaceEvent.LapTime, True); |
323
|
|
|
} |
324
|
|
|
} |
325
|
|
|
} |
326
|
|
|
} else { |
327
|
|
|
if (GUIPlayer == RaceEvent.Player && RaceEvent.CheckpointInLap < ElementCount) { |
328
|
|
|
MyCheckpoints[RaceEvent.CheckpointInLap] = RaceEvent.LapTime; |
329
|
|
|
|
330
|
|
|
switch (BestCp_Mode) { |
331
|
|
|
case 0: { |
332
|
|
|
|
333
|
|
|
if (MapBestTime != 99999999) { |
334
|
|
|
UpdateCp(RaceEvent.CheckpointInLap, RaceEvent.LapTime, True); |
335
|
|
|
} |
336
|
|
|
} |
337
|
|
|
case 1: { |
338
|
|
|
if ($localVariable.count > 0) { |
339
|
|
|
UpdateCp(RaceEvent.CheckpointInLap, RaceEvent.LapTime, True); |
340
|
|
|
} |
341
|
|
|
} |
342
|
|
|
case 2: { |
343
|
|
|
if ($dediVariable.count > 0) { |
344
|
|
|
UpdateCp(RaceEvent.CheckpointInLap, RaceEvent.LapTime, True); |
345
|
|
|
} |
346
|
|
|
} |
347
|
|
|
} |
348
|
|
|
} |
349
|
|
|
} |
350
|
|
|
} |
351
|
|
|
} |
352
|
|
|
EOL |
353
|
|
|
); |
354
|
|
|
|
355
|
|
|
|
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
/** |
359
|
|
|
* @param int $index |
360
|
|
|
* @return Frame |
361
|
|
|
*/ |
362
|
|
View Code Duplication |
private function createColumnBox($index) |
|
|
|
|
363
|
|
|
{ |
364
|
|
|
$width = 18; |
365
|
|
|
$height = 4; |
366
|
|
|
|
367
|
|
|
$frame = Frame::create(); |
368
|
|
|
|
369
|
|
|
$label = $this->uiFactory->createLabel(); |
370
|
|
|
$label->setAlign("left", "center2"); |
371
|
|
|
$label->setTextSize(1)->setPosition(1, -($height / 2)); |
372
|
|
|
$label->setSize($width, $height) |
373
|
|
|
->setId("Cp_".$index); |
374
|
|
|
$frame->addChild($label); |
375
|
|
|
|
376
|
|
|
$background = Quad::create("Bg_".$index); |
377
|
|
|
$background->setSize($width, $height) |
378
|
|
|
->setBackgroundColor("001")->setOpacity(0.3); |
379
|
|
|
$frame->addChild($background); |
380
|
|
|
|
381
|
|
|
$frame->setSize($width, $height); |
382
|
|
|
|
383
|
|
|
return $frame; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* @param int $index |
|
|
|
|
388
|
|
|
* @return Frame |
389
|
|
|
*/ |
390
|
|
View Code Duplication |
private function createNickBox() |
|
|
|
|
391
|
|
|
{ |
392
|
|
|
$width = 18; |
393
|
|
|
$height = 4; |
394
|
|
|
|
395
|
|
|
$frame = Frame::create(); |
396
|
|
|
|
397
|
|
|
$label = $this->uiFactory->createLabel(); |
398
|
|
|
$label->setAlign("left", "center2"); |
399
|
|
|
$label->setTextSize(1)->setPosition(1, -($height / 2)); |
400
|
|
|
$label->setSize($width, $height) |
401
|
|
|
->setId("RecordHolder"); |
402
|
|
|
$frame->addChild($label); |
403
|
|
|
|
404
|
|
|
$background = Quad::create(); |
405
|
|
|
$background->setSize($width, $height) |
406
|
|
|
->setBackgroundColor("001")->setOpacity(0.3); |
407
|
|
|
$frame->addChild($background); |
408
|
|
|
|
409
|
|
|
$frame->setSize($width, $height); |
410
|
|
|
|
411
|
|
|
return $frame; |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
protected function updateContent(ManialinkInterface $manialink) |
415
|
|
|
{ |
416
|
|
|
parent::updateContent($manialink); |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
|
420
|
|
|
} |
421
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.