Completed
Push — work-fleets ( 451000...e7900f )
by SuperNova.WS
06:16
created

UnitList::unitGetCount()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
/**
4
 * Class UnitList
5
 * Indexed by DB_ID - as it should be!
6
 *
7
 *
8
 *
9
 * Hints for IDE - inherited from ArrayAccessV2
10
 *
11
 * @method Unit offsetGet($offset)
12
 * @property Unit[] $_container
13
 *
14
 */
15
class UnitList extends ArrayAccessV2 implements IDbRow, ILocation {
16
17
18
  // Properties ********************************************************************************************************
19
20
  // ILocation implementation ==========================================================================================
21
22
  /**
23
   * Type of this location
24
   *
25
   * @var int $locationType
26
   */
27
  protected static $locationType = LOC_UNIT_LIST;
28
  /**
29
   * @var ILocation $locatedAt
30
   */
31
  protected $locatedAt = null;
32
33
34
  // New properties ====================================================================================================
35
36
  /**
37
   * @var Unit[] $mapUnitIdToDb
38
   */
39
  // Нужно для корректного сохранения новых юнитов. Их db_id = 0, поэтому при добавлении в контейнер они будут перезаписывать друг друга
40
  // Соответственно - при сохраненнии флота надо проходить dbSave именно по $mapUnitIdToDb
41
  protected $mapUnitIdToDb = array();
42
43
44
  // Methods ***********************************************************************************************************
45
46
  // ILocation implementation ==========================================================================================
47
48
  public function getPlayerOwnerId() {
49
    return is_object($this->locatedAt) ? $this->locatedAt->getPlayerOwnerId() : null;
50
  }
51
52
  public function getLocationType() {
53
    return is_object($this->locatedAt) ? $this->locatedAt->getLocationType() : LOC_NONE;
54
  }
55
56
  public function getLocationDbId() {
57
    return is_object($this->locatedAt) ? $this->locatedAt->getLocationDbId() : null;
58
  }
59
60
  // TODO - достаточно установить один раз Unit::LocatedAt на UnitList, что бы затем все юниты автоматически брали наиболее актуальный locatedAt
61
  public function setLocatedAt($location) {
62
    $this->locatedAt = $location;
63
    // TODO - по факту не нужно - достточно один раз поставить на $this
64
//    foreach($this->_container as $unit) {
65
//      $unit->setLocatedAt($this->locatedAt);
66
//    }
67
  }
68
69
  public function getLocatedAt() {
70
    return $this->locatedAt;
71
  }
72
73
  public function getLocatedAtType() {
74
    return is_object($this->locatedAt) ? $this->locatedAt->getLocationType() : LOC_NONE;
75
  }
76
77
  public function getLocatedAtDbId() {
78
    return is_object($this->locatedAt) ? $this->locatedAt->getLocationDbId() : 0;
79
  }
80
81
82
  // ArrayAccessV2 inheritance =========================================================================================
83
84
  /**
85
   * Adds link to unit object also to mapUnitIdToDb
86
   *
87
   * @param mixed $offset
88
   * @param Unit  $value
89
   */
90
  public function offsetSet($offset, $value) {
91
    if(isset($this->mapUnitIdToDb[$value->unitId])) {
92
      classSupernova::$debug->error('UnitList::offsetSet: Unit with UnitId ' . $value->unitId . ' already exists');
93
    }
94
    $this->mapUnitIdToDb[$value->unitId] = $value;
95
    parent::offsetSet($offset, $value);
96
  }
97
98
  public function offsetUnset($offset) {
99
    if(!empty($this[$offset]->unitId)) {
100
//      $unit_id = $this[$offset]->unitId;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
101
//      $this->mapUnitIdToDb[$unit_id] = null;
102
//      unset($this->mapUnitIdToDb[$unit_id]);
103
      unset($this->mapUnitIdToDb[$this[$offset]->unitId]);
104
    }
105
    parent::offsetUnset($offset);
106
  }
107
108
109
  // IDbRow implementation =============================================================================================
110
111
  /**
112
   * Loading object from DB by primary ID
113
   * Real location should be set before calling this method
114
   *
115
   * @param int $dbId - dbId is generally unused here. However it works as flag: 0 - just reset; (negative) - just reset; (positive) - proceed with loading
116
   */
117
  public function dbLoad($dbId, $lockSkip = false) {
118
//    $this->_reset();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
119
120
    if($dbId <= 0) {
121
      return;
122
    }
123
124
    if(!is_object($this->locatedAt)) {
125
      classSupernova::$debug->error('UnitList::dbLoad have no locatedAt field set');
126
    }
127
128
    $unit_array = classSupernova::db_get_unit_list_by_location(0, $this->getLocationType(), $this->getLocationDbId());
129
    if(!is_array($unit_array)) {
130
      return;
131
    }
132
133
    foreach($unit_array as $unit_db_row) {
134
      $unit = $this->_createElement();
135
      $unit->dbRowParse($unit_db_row);
136
137
      // TODO - сюда вставить разборку бонусов данного юнитлиста - тех бонусов, которые Grants данный юнит добавить в список бонусов юнит-листа
138
139
      $this[$unit->dbId] = $unit;
140
    }
141
142
    // TODO - Применить бонусы от location
143
    // Точнее - опустить бонусы с юнитлиста (те, которые Grants) на каждый юнит (те, которые receives)
144
    // Вообще-то Receives это будут параметры каждого юнита
145
  }
146
147
  public function dbSave() {
148
    if(!is_object($this->locatedAt)) {
149
      classSupernova::$debug->error('UnitList::dbSave have no locatedAt field set');
150
    }
151
152
    foreach($this->mapUnitIdToDb as $unit) {
153
      $unit_db_id = $unit->dbId;
154
      $unit->dbSave();
155
156
      if($unit->isEmpty()) {
157
        // Removing unit object
158
        // TODO - change when there will be common bus for all objects
159
        // ...or should I? If COUNT is empty - it means that object does not exists in DB. So it should be deleted from PHP memory and cache too
160
        unset($this[$unit_db_id]);
161
      } else {
162
        if($unit->dbId <= 0) {
163
          classSupernova::$debug->error('Error writing unit to DB');
164
        }
165
        // If unit is new then putting unit object to container
166
        if(empty($this->_container[$unit->dbId])) {
167
          $this->_container[$unit->dbId] = $unit;
168
        }
169
      }
170
    }
171
  }
172
173
174
175
176
177
  // Other =============================================================================================================
178
179
  /**
180
   * @return Unit
181
   *
182
   * @version 41a6.75
183
   */
184
  // TODO - Factory
185
  public function _createElement() {
186
    $unit = new Unit();
187
    $unit->setLocatedAt($this);
188
189
    return $unit;
190
  }
191
192
  /**
193
   * Set unit count of $unit_id to $unit_count
194
   * If there is no $unit_id - it will be created and saved to DB on dbSave
195
   *
196
   * @param int $unit_id
197
   * @param int $unit_count
198
   */
199
  public function unitSetCount($unit_id, $unit_count = 0) {
200
    $this->unitAdjustCount($unit_id, $unit_count, true);
201
  }
202
203
  public function unitGetCount($unit_id) {
204
    if(empty($this->mapUnitIdToDb[$unit_id])) {
205
      throw new Exception('Unit [' . $unit_id . '] is not exists in UnitList');
206
    }
207
    return $this->mapUnitIdToDb[$unit_id]->count;
208
  }
209
210
  /**
211
   * Adjust unit count of $unit_id by $unit_count - or just replace value
212
   * If there is no $unit_id - it will be created and saved to DB on dbSave
213
   *
214
   * @param int  $unit_id
215
   * @param int  $unit_count
216
   * @param bool $replace_value
217
   */
218
  public function unitAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
219
    if(empty($this->mapUnitIdToDb[$unit_id])) {
220
      // If unit not exists - creating one and setting all attributes
221
      $this->mapUnitIdToDb[$unit_id] = $this->_createElement();
222
      $this->mapUnitIdToDb[$unit_id]->setUnitId($unit_id);
223
      $this->mapUnitIdToDb[$unit_id]->setLocatedAt($this);
224
    }
225
226
    if($replace_value) {
227
      $this->mapUnitIdToDb[$unit_id]->count = $unit_count;
228
    } else {
229
      $this->mapUnitIdToDb[$unit_id]->adjustCount($unit_count);
230
    }
231
  }
232
233
  /**
234
   * Get unit list in array as $unit_id => $unit_count
235
   *
236
   * @return array
237
   */
238
  public function unitsGetArray() {
239
    $result = array();
240
    foreach($this->mapUnitIdToDb as $unit) {
241
      $result[$unit->unitId] = $unit->count;
242
    }
243
244
    return $result;
245
  }
246
247
  public function unitsCountApplyLossMultiplier($ships_lost_multiplier) {
248
    foreach($this->mapUnitIdToDb as $unit_id => $unit) {
249
      $unit->count = floor($unit->count * $ships_lost_multiplier);
250
    }
251
  }
252
253
  public function unitsCount() {
254
    return $this->unitsPropertySumById(0, 'count');
255
  }
256
257
  public function unitsCapacity() {
258
    return $this->unitsPropertySumById(0, 'capacity');
259
  }
260
261
  /**
262
   * Get count of units in UnitList by unit_id (or all units if unit_id == 0)
263
   *
264
   * @param int $unit_id - 0 - all units
265
   *
266
   * @return int
267
   */
268
  public function unitsCountById($unit_id = 0) {
269
    return $this->unitsPropertySumById($unit_id, 'count');
270
  }
271
272
  public function unitsPropertySumById($unit_id = 0, $propertyName = 'count') {
273
    $result = 0;
274
    foreach($this->mapUnitIdToDb as $unit) {
275
      if(!$unit_id || $unit->unitId == $unit_id) {
276
        $result += $unit->$propertyName;
277
      }
278
    }
279
280
    return $result;
281
  }
282
283
  /**
284
   * @param $page
285
   * @param $fleet
286
   * @param template $template
287
   *
288
   * @throws Exception
289
   */
290
  public function unitsRender(&$page, &$fleet, &$template) {
291
    /**
292
     * @var Fleet $objFleet
293
     */
294
    $objFleet = $this->getLocatedAt();
295
    if(empty($objFleet)) {
296
      throw new Exception('No fleet owner on UnitList::unitsRender() in ' . __FILE__ . '@' . __LINE__);
297
    }
298
299
    foreach($this->mapUnitIdToDb as $unit) {
300
      $ship_id = $unit->unitId;
301
      $ship_count = $unit->count;
302
      if(!UnitShip::is_in_group($ship_id) || $ship_count <= 0) {
303
        continue;
304
      }
305
306
      if($ship_count > mrc_get_level($objFleet->dbOwnerRow, $objFleet->dbSourcePlanetRow, $ship_id, false, true)) {
307
        $page .= classLocale::$lang['fl_noenought'];
308
      } else {
309
        $fleet['fleetarray'][$ship_id] = $ship_count;
310
      }
311
312
      $ship_info = get_unit_param($ship_id);
313
      $fleet['capacity'] += $ship_info[P_CAPACITY] * $ship_count;
314
      $ship_base_data = get_ship_data($ship_id, $objFleet->dbOwnerRow);
315
      $template->assign_block_vars('fleets.ships', array(
316
        'ID'          => $ship_id,
317
        'AMOUNT'      => $ship_count,
318
        'AMOUNT_TEXT' => pretty_number($ship_count),
319
        'CONSUMPTION' => $ship_base_data['consumption'],
320
        'SPEED'       => $ship_base_data['speed'],
321
        'NAME'        => classLocale::$lang['tech'][$ship_id],
322
      ));
323
    }
324
325
    $fleet['amount'] += $this->unitsCount();
326
  }
327
328
329
//  // TODO - revise it later
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
330
//  public function _reset() {
331
//    //if(!empty($this->mapUnitIdToDb)) {
332
//    //  foreach($this->mapUnitIdToDb as $unit_id => $object) {
333
//    //    unset($this->mapUnitIdToDb[$unit_id]);
334
//    //  }
335
//    //}
336
//    unset($this->mapUnitIdToDb);
337
//    $this->mapUnitIdToDb = array();
338
//
339
//    //if(!empty($this->_container)) {
340
//    //  foreach($this->_container as $unit_db_id => $object) {
341
//    //    unset($this->_container[$unit_db_id]);
342
//    //  }
343
//    //}
344
//    unset($this->_container);
345
//    $this->_container = array();
346
//  }
347
348
349
  // TODO - DEBUG - REMOVE =============================================================================================
350
  public function _dump() {
351
    print(__FILE__ . ':' . __LINE__ . "<br />");
352
    print("Located at " . $this->getLocationDbId() . " type " . $this->getLocationType() . "<br />");
353
354
    print('<table border="1">');
355
    print('<tr>');
356
357
    print('<th>');
358
    print('dbId');
359
    print('</th>');
360
361
    print('<th>');
362
    print('type');
363
    print('</th>');
364
365
    print('<th>');
366
    print('unitId');
367
    print('</th>');
368
369
    print('<th>');
370
    print('count');
371
    print('</th>');
372
373
    print('<th>');
374
    print('playerOwnerId');
375
    print('</th>');
376
377
    print('<th>');
378
    print('location');
379
    print('</th>');
380
381
    print('<th>');
382
    print('locationType');
383
    print('</th>');
384
385
    print('<th>');
386
    print('locationDbId');
387
    print('</th>');
388
389
    print('<th>');
390
    print('timeStart');
391
    print('</th>');
392
393
    print('<th>');
394
    print('timeFinish');
395
    print('</th>');
396
397
    print('</tr>');
398
399
    foreach($this->mapUnitIdToDb as $unit) {
400
      print('<tr>');
401
402
      print('<td>');
403
      print($unit->dbId);
404
      print('</td>');
405
406
      print('<td>');
407
      $type = $unit->getType();
408
      print("[{$type}] " . classLocale::$lang['tech'][$type]);
409
      print('</td>');
410
411
      print('<td>');
412
      print("[{$unit->unitId}] " . classLocale::$lang['tech'][$unit->unitId]);
413
      print('</td>');
414
415
      print('<td>');
416
      print($unit->count);
417
      print('</td>');
418
419
      print('<td>');
420
      print($unit->getPlayerOwnerId());
421
      print('</td>');
422
423
      print('<td>');
424
//      print($unit->location);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
425
      print('</td>');
426
427
      print('<td>');
428
      print($unit->getLocationType());
429
      print('</td>');
430
431
      print('<td>');
432
      print($unit->getLocationDbId());
433
      print('</td>');
434
435
      print('<td>');
436
      print($unit->getTimeStart());
437
      print('</td>');
438
439
      print('<td>');
440
      print($unit->getTimeFinish());
441
      print('</td>');
442
443
      print('</tr>');
444
    }
445
    print('</table>');
446
  }
447
448
449
  public function unitZeroDbId() {
450
    foreach($this->mapUnitIdToDb as $unit) {
451
      $unit->zeroDbId();
452
    }
453
  }
454
455
456
  public function unitZeroCount() {
457
    foreach($this->mapUnitIdToDb as $unit) {
458
      $unit->count = 0;
459
    }
460
  }
461
462
}
463