Issues (1369)

classes/Planet/Planet.php (4 issues)

1
<?php
2
3
/**
4
 * Created by Gorlum 08.01.2018 14:30
5
 */
6
7
namespace Planet;
8
9
10
use Core\EntityDb;
11
use DBAL\db_mysql;
12
use Unit\Governor;
13
use Exception;
14
use HelperString;
15
use SN;
16
17
/**
18
 * Class Planet
19
 * @package Planet
20
 *
21
 * @method bool insert()
22
 *
23
 * @property int|string $id        - Record ID name would be normalized to 'id'
24
 * @property string     $name
25
 * @property int|float  $id_owner
26
 * @property int        $galaxy
27
 * @property int        $system
28
 * @property int        $planet
29
 * @property int        $planet_type
30
 * @property int|float  $metal
31
 * @property int|float  $crystal
32
 * @property int|float  $deuterium
33
 * property int|float $energy_max
34
 * property int|float $energy_used
35
 * property int $last_jump_time
36
 * property int $metal_perhour
37
 * property int $crystal_perhour
38
 * property int $deuterium_perhour
39
 * property int $metal_mine_porcent
40
 * property int $crystal_mine_porcent
41
 * property int $deuterium_sintetizer_porcent
42
 * property int $solar_plant_porcent
43
 * property int $fusion_plant_porcent
44
 * property int $solar_satelit_porcent
45
 * property int $last_update
46
 * property int $que_processed
47
 * @property string $image
48
 * property int|float $points
49
 * property int|float $ranks
50
 * property int $id_level
51
 * property int $destruyed
52
 * property int $diameter
53
 * @property int        $field_max - maximum allowed number of fields
54
 * property int $field_current
55
 * property int $temp_min
56
 * property int $temp_max
57
 * property int|float $metal_max
58
 * property int|float $crystal_max
59
 * property int|float $deuterium_max
60
 * property int|float $parent_planet
61
 * @property int|float  $debris_metal
62
 * @property int|float  $debris_crystal
63
 * @property int        $PLANET_GOVERNOR_ID
64
 * @property int        $PLANET_GOVERNOR_LEVEL
65
 * property int       $planet_teleport_next
66
 * property int $ship_sattelite_sloth_porcent
67
 * @property int        $density
68
 * @property int        $density_index
69
 * property int $position_original
70
 * property int $field_max_original
71
 * property int $temp_min_original
72
 * property int $temp_max_original
73
 */
74
class Planet extends EntityDb {
75
76
  /**
77
   * @var string $_activeClass
78
   */
79
  protected $_activeClass = '\\Planet\\RecordPlanet';
80
81
  /**
82
   * @var RecordPlanet $_container
83
   */
84
  protected $_container;
85
86
  /**
87
   * @var float[] $resources
88
   */
89
  protected $resources = [
90
    RES_METAL     => 0,
91
    RES_CRYSTAL   => 0,
92
    RES_DEUTERIUM => 0,
93
  ];
94
95
  /**
96
   * @var Governor $governor
97
   */
98
  protected $governor;
99
100
  /**
101
   * Planet constructor.
102
   */
103
  public function __construct() {
104
    parent::__construct();
105
  }
106
107
  public function getGovernor() {
108
    if (empty($this->governor)) {
109
      $this->governor = new Governor();
110
      $this->governor->setPlanet($this);
111
    }
112
113
    return $this->governor;
114
  }
115
116
  public function governorHire($hireId) {
117
    $this->getGovernor()->hire($hireId);
118
  }
119
120
  /**
121
   * @param string $redirect
122
   *
123
   * @deprecated
124
   * TODO - change saveing
125
   */
126
  public function sn_sys_sector_buy($redirect = 'overview.php') {
127
    if (!sys_get_param_str('sector_buy') || $this->planet_type != PT_PLANET) {
128
      return;
129
    }
130
131
    db_mysql::db_transaction_start();
132
    $user = db_user_by_id($this->id_owner, true);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

132
    $user = /** @scrutinizer ignore-deprecated */ db_user_by_id($this->id_owner, true);
Loading history...
133
    $this->setForUpdate()->dbLoadRecord($this->id);
134
135
    $sector_cost = eco_get_build_data($user, $this->asArray(), UNIT_SECTOR, mrc_get_level($user, $this->asArray(), UNIT_SECTOR), true);
136
    $sector_cost = $sector_cost[BUILD_CREATE][RES_DARK_MATTER];
137
    if ($sector_cost <= mrc_get_level($user, [], RES_DARK_MATTER)) {
138
      $planet_name_text = uni_render_planet($this->asArray());
139
      if (rpg_points_change($user['id'], RPG_SECTOR, -$sector_cost,
140
        sprintf(
141
          SN::$lang['sys_sector_purchase_log'],
142
          $user['username'],
143
          $user['id'],
144
          $planet_name_text,
145
          SN::$lang['sys_planet_type'][$this->planet_type],
146
          $this->id,
147
          $sector_cost
148
        )
149
      )) {
150
        $this->field_max++;
151
        $this->update();
152
      } else {
153
        db_mysql::db_transaction_rollback();
154
      }
155
    }
156
    db_mysql::db_transaction_commit();
157
158
    sys_redirect($redirect);
159
  }
160
161
  /**
162
   * @param $user
163
   *
164
   * @return array
165
   *
166
   * @deprecated
167
   * TODO - change saveing
168
   */
169
  public function sn_sys_planet_core_transmute(&$user) {
170
    if (!sys_get_param_str('transmute')) {
171
      return array();
172
    }
173
174
    try {
175
      if ($this->planet_type != PT_PLANET) {
176
        throw new exception(SN::$lang['ov_core_err_not_a_planet'], ERR_ERROR);
177
      }
178
179
      if ($this->density_index == ($new_density_index = sys_get_param_id('density_type'))) {
180
        throw new exception(SN::$lang['ov_core_err_same_density'], ERR_WARNING);
181
      }
182
183
      db_mysql::db_transaction_start();
184
      $user = db_user_by_id($user['id'], true);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

184
      $user = /** @scrutinizer ignore-deprecated */ db_user_by_id($user['id'], true);
Loading history...
185
      $this->setForUpdate()->dbLoadRecord($this->id);
186
187
      $planet_density_index = $this->density_index;
188
      $density_price_chart = $this->planet_density_price_chart();
189
190
      if (!isset($density_price_chart[$new_density_index])) {
191
        // Hack attempt
192
        throw new exception(SN::$lang['ov_core_err_denisty_type_wrong'], ERR_ERROR);
193
      }
194
195
      $user_dark_matter = mrc_get_level($user, false, RES_DARK_MATTER);
196
      $transmute_cost = $density_price_chart[$new_density_index];
197
      if ($user_dark_matter < $transmute_cost) {
198
        throw new exception(SN::$lang['ov_core_err_no_dark_matter'], ERR_ERROR);
199
      }
200
201
      $sn_data_planet_density = sn_get_groups('planet_density');
202
      foreach ($sn_data_planet_density as $key => $value) {
203
        if ($key == $new_density_index) {
204
          break;
205
        }
206
        $prev_density_index = $key;
207
      }
208
209
      $new_density = round(($sn_data_planet_density[$new_density_index][UNIT_PLANET_DENSITY] + $sn_data_planet_density[$prev_density_index][UNIT_PLANET_DENSITY]) / 2);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $prev_density_index seems to be defined by a foreach iteration on line 202. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
210
211
      rpg_points_change($user['id'], RPG_PLANET_DENSITY_CHANGE, -$transmute_cost,
212
        array(
213
          'Planet %1$s ID %2$d at coordinates %3$s changed density type from %4$d "%5$s" to %6$d "%7$s". New density is %8$d kg/m3',
214
          $this->name,
215
          $this->id,
216
          uni_render_coordinates($this->asArray()),
217
          $planet_density_index,
218
          SN::$lang['uni_planet_density_types'][$planet_density_index],
219
          $new_density_index,
220
          SN::$lang['uni_planet_density_types'][$new_density_index],
221
          $new_density
222
        )
223
      );
224
225
      DBStaticPlanet::db_planet_set_by_id($this->id, "`density` = {$new_density}, `density_index` = {$new_density_index}");
226
      db_mysql::db_transaction_commit();
227
228
      $this->density = $new_density;
229
      $this->density_index = $new_density_index;
230
      $result = array(
231
        'STATUS'  => ERR_NONE,
232
        'MESSAGE' => sprintf(SN::$lang['ov_core_err_none'], SN::$lang['uni_planet_density_types'][$planet_density_index], SN::$lang['uni_planet_density_types'][$new_density_index], $new_density),
233
      );
234
    } catch (Exception $e) {
235
      db_mysql::db_transaction_rollback();
236
      $result = array(
237
        'STATUS'  => $e->getCode(),
238
        'MESSAGE' => $e->getMessage(),
239
      );
240
    }
241
242
    return $result;
243
  }
244
245
  /**
246
   * @return array
247
   */
248
  public function planet_density_price_chart() {
249
    $sn_data_density = sn_get_groups('planet_density');
250
    $density_price_chart = array();
251
252
    foreach ($sn_data_density as $density_id => $density_data) {
253
      // Отсекаем записи с RARITY = 0 - служебные записи и супер-ядра
254
      $density_data[UNIT_PLANET_DENSITY_RARITY] ? $density_price_chart[$density_id] = $density_data[UNIT_PLANET_DENSITY_RARITY] : false;
255
    }
256
    unset($density_price_chart[PLANET_DENSITY_NONE]);
257
258
    $total_rarity = array_sum($density_price_chart);
259
260
    foreach ($density_price_chart as &$density_data) {
261
      $density_data = ceil($total_rarity / $density_data * $this->field_max * PLANET_DENSITY_TO_DARK_MATTER_RATE);
262
    }
263
264
    return $density_price_chart;
265
  }
266
267
  /**
268
   * @param int $user_dark_matter
269
   *
270
   * @return array
271
   */
272
  public function tpl_planet_density_info($user_dark_matter) {
273
    $result = [];
274
275
    $density_price_chart = Planet::planet_density_price_chart();
0 ignored issues
show
Bug Best Practice introduced by
The method Planet\Planet::planet_density_price_chart() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

275
    /** @scrutinizer ignore-call */ 
276
    $density_price_chart = Planet::planet_density_price_chart();
Loading history...
276
277
    foreach ($density_price_chart as $density_price_index => &$density_price_data) {
278
      $density_cost = $density_price_data;
279
      $density_price_data = array(
280
        'COST'            => $density_cost,
281
        'COST_TEXT'       => HelperString::numberFloorAndFormat($density_cost),
282
        'COST_TEXT_CLASS' => prettyNumberGetClass($density_cost, $user_dark_matter),
283
        'REST'            => $user_dark_matter - $density_cost,
284
        'ID'              => $density_price_index,
285
        'TEXT'            => SN::$lang['uni_planet_density_types'][$density_price_index],
286
      );
287
      $result[] = $density_price_data;
288
    }
289
290
    $planet_density_index = $this->density_index;
291
292
    return [
293
      '.'                    => [
294
        'densities' => $result,
295
      ],
296
      'PLANET_DENSITY_INDEX' => $planet_density_index,
297
      'PLANET_CORE_TEXT'     => \SN::$lang['uni_planet_density_types'][$planet_density_index],
298
    ];
299
  }
300
301
  /**
302
   * @param array $user
303
   *
304
   * @return array
305
   */
306
  public function int_planet_pretemplate($user) {
307
    $governor_id = $this->PLANET_GOVERNOR_ID;
308
    $governor_level_plain = mrc_get_level($user, $this->asArray(), $governor_id, false, true);
309
310
    return [
311
      'PLANET_ID'        => $this->id,
312
      'PLANET_NAME'      => htmlentities($this->name, ENT_QUOTES, 'UTF-8'),
313
      'PLANET_NAME_JS'   => htmlentities(js_safe_string($this->name), ENT_QUOTES, 'UTF-8'),
314
      'PLANET_GALAXY'    => $this->galaxy,
315
      'PLANET_SYSTEM'    => $this->system,
316
      'PLANET_PLANET'    => $this->planet,
317
      'PLANET_TYPE'      => $this->planet_type,
318
      'PLANET_TYPE_TEXT' => SN::$lang['sys_planet_type'][$this->planet_type],
319
      'PLANET_DEBRIS'    => $this->debris_metal + $this->debris_crystal,
320
      'PLANET_IMAGE'     => $this->image,
321
322
      'PLANET_GOVERNOR_ID'         => $governor_id,
323
      'PLANET_GOVERNOR_NAME'       => SN::$lang['tech'][$governor_id],
324
      'PLANET_GOVERNOR_LEVEL'      => $governor_level_plain,
325
      'PLANET_GOVERNOR_LEVEL_PLUS' => mrc_get_level($user, $this->asArray(), $governor_id, false, false) - $governor_level_plain,
326
      'PLANET_GOVERNOR_LEVEL_MAX'  => get_unit_param($governor_id, P_MAX_STACK),
327
    ];
328
  }
329
330
  public function reset() {
331
    $this->governor = null;
332
333
    $this->resources = [
334
      RES_METAL     => 0,
335
      RES_CRYSTAL   => 0,
336
      RES_DEUTERIUM => 0,
337
    ];
338
339
    return parent::reset();
340
  }
341
342
  /**
343
   * @return RecordPlanet
344
   */
345
  public function _getContainer() {
346
    return $this->_container;
347
  }
348
349
350
  /**
351
   * @param int   $resourceId
352
   * @param float $resourceCount
353
   *
354
   * @throws \Exception
355
   */
356
  public function changeResource($resourceId, $resourceCount) {
357
    if (empty($resourceCount)) {
358
      return;
359
    }
360
361
    if (!array_key_exists($resourceId, $this->resources)) {
362
      throw new \Exception("PLANET ERROR! Trying to change unknown resource type [{$resourceId}] '{$resourceCount}' on planet [{$this->id}]");
363
    }
364
365
    $resourceCount = ceil($resourceCount);
366
367
    if ($this->resources[$resourceId] + $resourceCount < 0) {
368
      throw new \Exception("PLANET ERROR! Trying to deduct more resources [{$resourceId}] '{$resourceCount}' when planet [{$this->id}] has only {$this->resources[$resourceId]} - deficiency " . ($this->resources[$resourceId] + $resourceCount));
369
    }
370
371
    $this->resources[$resourceId] += $resourceCount;
372
373
    $fieldName = pname_resource_name($resourceId);
374
    $this->_getContainer()->inc()->$fieldName = $resourceCount;
375
376
//    $this->metal = $this->resources[RES_METAL];
377
//    $this->crystal = $this->resources[RES_CRYSTAL];
378
//    $this->deuterium = $this->resources[RES_DEUTERIUM];
379
  }
380
381
  public function dbLoadRecord($id) {
382
    $result = parent::dbLoadRecord($id);
383
384
    if(!$this->isNew()) {
385
      $this->resources[RES_METAL] = $this->_getContainer()->metal;
386
      $this->resources[RES_CRYSTAL] = $this->_getContainer()->crystal;
387
      $this->resources[RES_DEUTERIUM] = $this->_getContainer()->deuterium;
388
    }
389
390
    return $result;
391
  }
392
393
}
394