Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Fleet often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Fleet, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 31 | class Fleet extends UnitContainer { |
||
| 32 | |||
| 33 | // DBRow inheritance ************************************************************************************************* |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Table name in DB |
||
| 37 | * |
||
| 38 | * @var string |
||
| 39 | */ |
||
| 40 | protected static $_table = 'fleets'; |
||
| 41 | /** |
||
| 42 | * Name of ID field in DB |
||
| 43 | * |
||
| 44 | * @var string |
||
| 45 | */ |
||
| 46 | protected static $_dbIdFieldName = 'fleet_id'; |
||
| 47 | /** |
||
| 48 | * DB_ROW to Class translation scheme |
||
| 49 | * |
||
| 50 | * @var array |
||
| 51 | */ |
||
| 52 | protected static $_properties = array( |
||
| 53 | 'dbId' => array( |
||
| 54 | P_DB_FIELD => 'fleet_id', |
||
| 55 | ), |
||
| 56 | 'playerOwnerId' => array( |
||
| 57 | P_METHOD_EXTRACT => 'ownerExtract', |
||
| 58 | P_METHOD_INJECT => 'ownerInject', |
||
| 59 | // P_DB_FIELD => 'fleet_owner', |
||
|
|
|||
| 60 | ), |
||
| 61 | 'mission_type' => array( |
||
| 62 | P_DB_FIELD => 'fleet_mission', |
||
| 63 | P_FUNC_INPUT => 'intval', |
||
| 64 | ), |
||
| 65 | |||
| 66 | 'target_owner_id' => array( |
||
| 67 | P_DB_FIELD => 'fleet_target_owner', |
||
| 68 | ), |
||
| 69 | 'group_id' => array( |
||
| 70 | P_DB_FIELD => 'fleet_group', |
||
| 71 | ), |
||
| 72 | 'is_returning' => array( |
||
| 73 | P_DB_FIELD => 'fleet_mess', |
||
| 74 | P_FUNC_INPUT => 'intval', |
||
| 75 | ), |
||
| 76 | |||
| 77 | 'shipCount' => array( |
||
| 78 | P_DB_FIELD => 'fleet_amount', |
||
| 79 | // TODO - CHECK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||
| 80 | // P_FUNC_OUTPUT => 'get_ship_count', |
||
| 81 | // P_DB_FIELDS_LINKED => array( |
||
| 82 | // 'fleet_amount', |
||
| 83 | // ), |
||
| 84 | P_READ_ONLY => true, |
||
| 85 | ), |
||
| 86 | |||
| 87 | 'time_launch' => array( |
||
| 88 | P_DB_FIELD => 'start_time', |
||
| 89 | ), |
||
| 90 | |||
| 91 | 'time_arrive_to_target' => array( |
||
| 92 | P_DB_FIELD => 'fleet_start_time', |
||
| 93 | ), |
||
| 94 | 'time_mission_job_complete' => array( |
||
| 95 | P_DB_FIELD => 'fleet_end_stay', |
||
| 96 | ), |
||
| 97 | 'time_return_to_source' => array( |
||
| 98 | P_DB_FIELD => 'fleet_end_time', |
||
| 99 | ), |
||
| 100 | |||
| 101 | 'fleet_start_planet_id' => array( |
||
| 102 | P_DB_FIELD => 'fleet_start_planet_id', |
||
| 103 | P_FUNC_INPUT => 'nullIfEmpty', |
||
| 104 | ), |
||
| 105 | |||
| 106 | 'fleet_start_galaxy' => array( |
||
| 107 | P_DB_FIELD => 'fleet_start_galaxy', |
||
| 108 | ), |
||
| 109 | 'fleet_start_system' => array( |
||
| 110 | P_DB_FIELD => 'fleet_start_system', |
||
| 111 | ), |
||
| 112 | 'fleet_start_planet' => array( |
||
| 113 | P_DB_FIELD => 'fleet_start_planet', |
||
| 114 | ), |
||
| 115 | 'fleet_start_type' => array( |
||
| 116 | P_DB_FIELD => 'fleet_start_type', |
||
| 117 | ), |
||
| 118 | |||
| 119 | 'fleet_end_planet_id' => array( |
||
| 120 | P_DB_FIELD => 'fleet_end_planet_id', |
||
| 121 | P_FUNC_INPUT => 'nullIfEmpty', |
||
| 122 | ), |
||
| 123 | 'fleet_end_galaxy' => array( |
||
| 124 | P_DB_FIELD => 'fleet_end_galaxy', |
||
| 125 | ), |
||
| 126 | 'fleet_end_system' => array( |
||
| 127 | P_DB_FIELD => 'fleet_end_system', |
||
| 128 | ), |
||
| 129 | 'fleet_end_planet' => array( |
||
| 130 | P_DB_FIELD => 'fleet_end_planet', |
||
| 131 | ), |
||
| 132 | 'fleet_end_type' => array( |
||
| 133 | P_DB_FIELD => 'fleet_end_type', |
||
| 134 | ), |
||
| 135 | |||
| 136 | 'resource_list' => array( |
||
| 137 | P_METHOD_EXTRACT => 'resourcesExtract', |
||
| 138 | P_METHOD_INJECT => 'resourcesInject', |
||
| 139 | P_DB_FIELDS_LINKED => array( |
||
| 140 | 'fleet_resource_metal', |
||
| 141 | 'fleet_resource_crystal', |
||
| 142 | 'fleet_resource_deuterium', |
||
| 143 | ), |
||
| 144 | ), |
||
| 145 | ); |
||
| 146 | |||
| 147 | |||
| 148 | // UnitContainer inheritance ***************************************************************************************** |
||
| 149 | /** |
||
| 150 | * Type of this location |
||
| 151 | * |
||
| 152 | * @var int $locationType |
||
| 153 | */ |
||
| 154 | protected static $locationType = LOC_FLEET; |
||
| 155 | |||
| 156 | |||
| 157 | // New properties **************************************************************************************************** |
||
| 158 | /** |
||
| 159 | * `fleet_owner` |
||
| 160 | * |
||
| 161 | * @var int |
||
| 162 | */ |
||
| 163 | protected $_playerOwnerId = 0; |
||
| 164 | /** |
||
| 165 | * `fleet_group` |
||
| 166 | * |
||
| 167 | * @var int |
||
| 168 | */ |
||
| 169 | protected $_group_id = 0; |
||
| 170 | |||
| 171 | /** |
||
| 172 | * `fleet_mission` |
||
| 173 | * |
||
| 174 | * @var int |
||
| 175 | */ |
||
| 176 | protected $_mission_type = 0; |
||
| 177 | |||
| 178 | /** |
||
| 179 | * `fleet_target_owner` |
||
| 180 | * |
||
| 181 | * @var int |
||
| 182 | */ |
||
| 183 | protected $_target_owner_id = null; |
||
| 184 | |||
| 185 | /** |
||
| 186 | * @var array |
||
| 187 | */ |
||
| 188 | protected $resource_list = array( |
||
| 189 | RES_METAL => 0, |
||
| 190 | RES_CRYSTAL => 0, |
||
| 191 | RES_DEUTERIUM => 0, |
||
| 192 | ); |
||
| 193 | |||
| 194 | |||
| 195 | /** |
||
| 196 | * `fleet__mess` - Флаг возвращающегося флота |
||
| 197 | * |
||
| 198 | * @var int |
||
| 199 | */ |
||
| 200 | protected $_is_returning = 0; |
||
| 201 | /** |
||
| 202 | * `start_time` - Время отправления - таймштамп взлёта флота из точки отправления |
||
| 203 | * |
||
| 204 | * @var int $_time_launch |
||
| 205 | */ |
||
| 206 | protected $_time_launch = 0; // `start_time` = SN_TIME_NOW |
||
| 207 | /** |
||
| 208 | * `fleet_start_time` - Время прибытия в точку миссии/время начала выполнения миссии |
||
| 209 | * |
||
| 210 | * @var int $_time_arrive_to_target |
||
| 211 | */ |
||
| 212 | protected $_time_arrive_to_target = 0; // `fleet_start_time` = SN_TIME_NOW + $time_travel |
||
| 213 | /** |
||
| 214 | * `fleet_end_stay` - Время окончания миссии в точке назначения |
||
| 215 | * |
||
| 216 | * @var int $_time_mission_job_complete |
||
| 217 | */ |
||
| 218 | protected $_time_mission_job_complete = 0; // `fleet_end_stay` |
||
| 219 | /** |
||
| 220 | * `fleet_end_time` - Время возвращения флота после окончания миссии |
||
| 221 | * |
||
| 222 | * @var int $_time_return_to_source |
||
| 223 | */ |
||
| 224 | protected $_time_return_to_source = 0; // `fleet_end_time` |
||
| 225 | |||
| 226 | |||
| 227 | protected $_fleet_start_planet_id = null; |
||
| 228 | protected $_fleet_start_galaxy = 0; |
||
| 229 | protected $_fleet_start_system = 0; |
||
| 230 | protected $_fleet_start_planet = 0; |
||
| 231 | protected $_fleet_start_type = PT_ALL; |
||
| 232 | |||
| 233 | protected $_fleet_end_planet_id = null; |
||
| 234 | protected $_fleet_end_galaxy = 0; |
||
| 235 | protected $_fleet_end_system = 0; |
||
| 236 | protected $_fleet_end_planet = 0; |
||
| 237 | protected $_fleet_end_type = PT_ALL; |
||
| 238 | |||
| 239 | // Missile properties |
||
| 240 | public $missile_target = 0; |
||
| 241 | |||
| 242 | // Fleet event properties |
||
| 243 | public $fleet_start_name = ''; |
||
| 244 | public $fleet_end_name = ''; |
||
| 245 | public $ov_label = ''; |
||
| 246 | public $ov_this_planet = ''; |
||
| 247 | public $event_time = 0; |
||
| 248 | |||
| 249 | protected $resource_delta = array(); |
||
| 250 | protected $resource_replace = array(); |
||
| 251 | |||
| 252 | |||
| 253 | // |
||
| 254 | |||
| 255 | |||
| 256 | protected $allowed_missions = array(); |
||
| 257 | protected $exists_missions = array(); |
||
| 258 | protected $allowed_planet_types = array( |
||
| 259 | // PT_NONE => PT_NONE, |
||
| 260 | PT_PLANET => PT_PLANET, |
||
| 261 | PT_MOON => PT_MOON, |
||
| 262 | PT_DEBRIS => PT_DEBRIS |
||
| 263 | ); |
||
| 264 | |||
| 265 | // TODO - Move to Player |
||
| 266 | public $dbOwnerRow = array(); |
||
| 267 | public $dbSourcePlanetRow = array(); |
||
| 268 | |||
| 269 | /** |
||
| 270 | * GSPT coordinates of target |
||
| 271 | * |
||
| 272 | * @var Vector |
||
| 273 | */ |
||
| 274 | public $targetVector = array(); |
||
| 275 | /** |
||
| 276 | * Target planet row |
||
| 277 | * |
||
| 278 | * @var array |
||
| 279 | */ |
||
| 280 | public $dbTargetRow = array(); |
||
| 281 | public $dbTargetOwnerRow = array(); |
||
| 282 | |||
| 283 | /** |
||
| 284 | * Fleet speed - old in 1/10 of 100% |
||
| 285 | * |
||
| 286 | * @var int |
||
| 287 | */ |
||
| 288 | public $oldSpeedInTens = 0; |
||
| 289 | |||
| 290 | public $tempPlayerMaxFleets = 0; |
||
| 291 | public $travelData = array(); |
||
| 292 | |||
| 293 | protected $isRealFlight = false; |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Fleet constructor. |
||
| 297 | */ |
||
| 298 | public function __construct() { |
||
| 299 | parent::__construct(); |
||
| 300 | $this->allowed_missions = $this->exists_missions = sn_get_groups('missions'); |
||
| 301 | } |
||
| 302 | |||
| 303 | /** |
||
| 304 | * @param array $template_result |
||
| 305 | * @param array $playerRow |
||
| 306 | * @param array $planetRow |
||
| 307 | */ |
||
| 308 | // TODO - redo to unit/unitlist renderer |
||
| 309 | public function renderAvailableShips(&$template_result, $playerRow, $planetRow) { |
||
| 310 | $record_index = 0; |
||
| 311 | $ship_list = array(); |
||
| 312 | foreach(sn_get_groups('fleet') as $n => $unit_id) { |
||
| 313 | $unit_level = mrc_get_level($playerRow, $planetRow, $unit_id, false, true); |
||
| 314 | if($unit_level <= 0) { |
||
| 315 | continue; |
||
| 316 | } |
||
| 317 | $ship_data = get_ship_data($unit_id, $playerRow); |
||
| 318 | $ship_list[$unit_id] = array( |
||
| 319 | '__INDEX' => $record_index++, |
||
| 320 | 'ID' => $unit_id, |
||
| 321 | 'NAME' => classLocale::$lang['tech'][$unit_id], |
||
| 322 | 'AMOUNT' => $unit_level, |
||
| 323 | 'AMOUNT_TEXT' => pretty_number($unit_level), |
||
| 324 | 'CONSUMPTION' => $ship_data['consumption'], |
||
| 325 | 'CONSUMPTION_TEXT' => pretty_number($ship_data['consumption']), |
||
| 326 | 'SPEED' => $ship_data['speed'], |
||
| 327 | 'SPEED_TEXT' => pretty_number($ship_data['speed']), |
||
| 328 | 'CAPACITY' => $ship_data['capacity'], |
||
| 329 | 'CAPACITY_TEXT' => pretty_number($ship_data['capacity']), |
||
| 330 | ); |
||
| 331 | } |
||
| 332 | |||
| 333 | sortUnitRenderedList($ship_list, classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT], classSupernova::$user_options[PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE]); |
||
| 334 | |||
| 335 | foreach($ship_list as $ship_data) { |
||
| 336 | $template_result['.']['ships'][] = $ship_data; |
||
| 337 | } |
||
| 338 | } |
||
| 339 | |||
| 340 | public function isEmpty() { |
||
| 341 | return !$this->resourcesGetTotal() && !$this->shipsGetTotal(); |
||
| 342 | } |
||
| 343 | |||
| 344 | // public function getPlayerOwnerId() { |
||
| 345 | // return $this->playerOwnerId; |
||
| 346 | // } |
||
| 347 | |||
| 348 | /** |
||
| 349 | * Initializes Fleet from user params and posts it to DB |
||
| 350 | */ |
||
| 351 | public function dbInsert() { |
||
| 352 | // WARNING! MISSION TIMES MUST BE SET WITH set_times() method! |
||
| 353 | // TODO - more checks! |
||
| 354 | if(empty($this->_time_launch)) { |
||
| 355 | die('Fleet time not set!'); |
||
| 356 | } |
||
| 357 | |||
| 358 | parent::dbInsert(); |
||
| 359 | } |
||
| 360 | |||
| 361 | |||
| 362 | /* FLEET DB ACCESS =================================================================================================*/ |
||
| 363 | |||
| 364 | /** |
||
| 365 | * LOCK - Lock all records which can be used with mission |
||
| 366 | * |
||
| 367 | * @param $mission_data |
||
| 368 | * @param $fleet_id |
||
| 369 | * |
||
| 370 | * @return array|bool|mysqli_result|null |
||
| 371 | */ |
||
| 372 | public function dbLockFlying(&$mission_data) { |
||
| 373 | // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row |
||
| 374 | // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets |
||
| 375 | |||
| 376 | $fleet_id_safe = idval($this->_dbId); |
||
| 377 | |||
| 378 | return doquery( |
||
| 379 | // Блокировка самого флота |
||
| 380 | "SELECT 1 FROM {{fleets}} AS f " . |
||
| 381 | |||
| 382 | // Блокировка всех юнитов, принадлежащих этому флоту |
||
| 383 | "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " . |
||
| 384 | |||
| 385 | // Блокировка всех прилетающих и улетающих флотов, если нужно |
||
| 386 | // TODO - lock fleets by COORDINATES |
||
| 387 | ($mission_data['dst_fleets'] ? "LEFT JOIN {{fleets}} AS fd ON fd.fleet_end_planet_id = f.fleet_end_planet_id OR fd.fleet_start_planet_id = f.fleet_end_planet_id " : '') . |
||
| 388 | // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination |
||
| 389 | ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') . |
||
| 390 | |||
| 391 | ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') . |
||
| 392 | // Блокировка всех юнитов, принадлежащих владельцу планеты-цели |
||
| 393 | ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') . |
||
| 394 | // Блокировка планеты-цели |
||
| 395 | ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') . |
||
| 396 | // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели |
||
| 397 | // ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') . |
||
| 398 | |||
| 399 | |||
| 400 | ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') . |
||
| 401 | // Блокировка всех юнитов, принадлежащих владельцу флота |
||
| 402 | ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') . |
||
| 403 | // Блокировка планеты отправления |
||
| 404 | ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') . |
||
| 405 | // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота |
||
| 406 | // ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') . |
||
| 407 | |||
| 408 | "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE" |
||
| 409 | ); |
||
| 410 | } |
||
| 411 | |||
| 412 | /** |
||
| 413 | * Lock all fields that belongs to operation |
||
| 414 | * |
||
| 415 | * @param $dbId |
||
| 416 | * |
||
| 417 | * @internal param DBLock $dbRow - Object that accumulates locks |
||
| 418 | * |
||
| 419 | */ |
||
| 420 | // TODO = make static |
||
| 421 | public function dbGetLockById($dbId) { |
||
| 422 | doquery( |
||
| 423 | // Блокировка самого флота |
||
| 424 | "SELECT 1 FROM {{fleets}} AS FLEET0 " . |
||
| 425 | // Lock fleet owner |
||
| 426 | "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " . |
||
| 427 | // Блокировка всех юнитов, принадлежащих этому флоту |
||
| 428 | "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " . |
||
| 429 | |||
| 430 | // Без предварительной выборки неизвестно - куда летит этот флот. |
||
| 431 | // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота. |
||
| 432 | // Получаем матрицу 2х2 - т.е. 4 подзапроса. |
||
| 433 | // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты. |
||
| 434 | // Поэтому тип планеты не указывается |
||
| 435 | |||
| 436 | // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0 |
||
| 437 | "LEFT JOIN {{fleets}} AS FLEET1 ON |
||
| 438 | FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND |
||
| 439 | FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND |
||
| 440 | FLEET1.fleet_end_system = FLEET0.fleet_end_system AND |
||
| 441 | FLEET1.fleet_end_planet = FLEET0.fleet_end_planet |
||
| 442 | " . |
||
| 443 | // Блокировка всех юнитов, принадлежащих этим флотам |
||
| 444 | "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " . |
||
| 445 | // Lock fleet owner |
||
| 446 | "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " . |
||
| 447 | |||
| 448 | "LEFT JOIN {{fleets}} AS FLEET2 ON |
||
| 449 | FLEET2.fleet_mess = 1 AND FLEET0.fleet_mess = 0 AND |
||
| 450 | FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND |
||
| 451 | FLEET2.fleet_start_system = FLEET0.fleet_end_system AND |
||
| 452 | FLEET2.fleet_start_planet = FLEET0.fleet_end_planet |
||
| 453 | " . |
||
| 454 | // Блокировка всех юнитов, принадлежащих этим флотам |
||
| 455 | "LEFT JOIN {{unit}} as UNIT2 ON |
||
| 456 | UNIT2.unit_location_type = " . LOC_FLEET . " AND |
||
| 457 | UNIT2.unit_location_id = FLEET2.fleet_id |
||
| 458 | " . |
||
| 459 | // Lock fleet owner |
||
| 460 | "LEFT JOIN {{users}} as USER2 on |
||
| 461 | USER2.id = FLEET2.fleet_owner |
||
| 462 | " . |
||
| 463 | |||
| 464 | // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1 |
||
| 465 | "LEFT JOIN {{fleets}} AS FLEET3 ON |
||
| 466 | FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND |
||
| 467 | FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND |
||
| 468 | FLEET3.fleet_end_system = FLEET0.fleet_start_system AND |
||
| 469 | FLEET3.fleet_end_planet = FLEET0.fleet_start_planet |
||
| 470 | " . |
||
| 471 | // Блокировка всех юнитов, принадлежащих этим флотам |
||
| 472 | "LEFT JOIN {{unit}} as UNIT3 ON |
||
| 473 | UNIT3.unit_location_type = " . LOC_FLEET . " AND |
||
| 474 | UNIT3.unit_location_id = FLEET3.fleet_id |
||
| 475 | " . |
||
| 476 | // Lock fleet owner |
||
| 477 | "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " . |
||
| 478 | |||
| 479 | "LEFT JOIN {{fleets}} AS FLEET4 ON |
||
| 480 | FLEET4.fleet_mess = 1 AND FLEET0.fleet_mess = 1 AND |
||
| 481 | FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND |
||
| 482 | FLEET4.fleet_start_system = FLEET0.fleet_start_system AND |
||
| 483 | FLEET4.fleet_start_planet = FLEET0.fleet_start_planet |
||
| 484 | " . |
||
| 485 | // Блокировка всех юнитов, принадлежащих этим флотам |
||
| 486 | "LEFT JOIN {{unit}} as UNIT4 ON |
||
| 487 | UNIT4.unit_location_type = " . LOC_FLEET . " AND |
||
| 488 | UNIT4.unit_location_id = FLEET4.fleet_id |
||
| 489 | " . |
||
| 490 | // Lock fleet owner |
||
| 491 | "LEFT JOIN {{users}} as USER4 on |
||
| 492 | USER4.id = FLEET4.fleet_owner |
||
| 493 | " . |
||
| 494 | |||
| 495 | |||
| 496 | // Locking start planet |
||
| 497 | "LEFT JOIN {{planets}} AS PLANETS5 ON |
||
| 498 | FLEET0.fleet_mess = 1 AND |
||
| 499 | PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND |
||
| 500 | PLANETS5.system = FLEET0.fleet_start_system AND |
||
| 501 | PLANETS5.planet = FLEET0.fleet_start_planet |
||
| 502 | " . |
||
| 503 | // Lock planet owner |
||
| 504 | "LEFT JOIN {{users}} as USER5 on |
||
| 505 | USER5.id = PLANETS5.id_owner |
||
| 506 | " . |
||
| 507 | // Блокировка всех юнитов, принадлежащих этой планете |
||
| 508 | "LEFT JOIN {{unit}} as UNIT5 ON |
||
| 509 | UNIT5.unit_location_type = " . LOC_PLANET . " AND |
||
| 510 | UNIT5.unit_location_id = PLANETS5.id |
||
| 511 | " . |
||
| 512 | |||
| 513 | |||
| 514 | // Locking destination planet |
||
| 515 | "LEFT JOIN {{planets}} AS PLANETS6 ON |
||
| 516 | FLEET0.fleet_mess = 0 AND |
||
| 517 | PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND |
||
| 518 | PLANETS6.system = FLEET0.fleet_end_system AND |
||
| 519 | PLANETS6.planet = FLEET0.fleet_end_planet |
||
| 520 | " . |
||
| 521 | // Lock planet owner |
||
| 522 | "LEFT JOIN {{users}} as USER6 on |
||
| 523 | USER6.id = PLANETS6.id_owner |
||
| 524 | " . |
||
| 525 | // Блокировка всех юнитов, принадлежащих этой планете |
||
| 526 | "LEFT JOIN {{unit}} as UNIT6 ON |
||
| 527 | UNIT6.unit_location_type = " . LOC_PLANET . " AND |
||
| 528 | UNIT6.unit_location_id = PLANETS6.id |
||
| 529 | " . |
||
| 530 | "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE" |
||
| 531 | ); |
||
| 532 | } |
||
| 533 | |||
| 534 | |||
| 535 | public function dbRowParse($db_row) { |
||
| 536 | parent::dbRowParse($db_row); // TODO: Change the autogenerated stub |
||
| 537 | $player = new Player(); |
||
| 538 | $player->dbLoad($db_row['fleet_owner']); |
||
| 539 | $this->setLocatedAt($player); |
||
| 540 | } |
||
| 541 | |||
| 542 | /* FLEET HELPERS =====================================================================================================*/ |
||
| 543 | /** |
||
| 544 | * Forcibly returns fleet before time outs |
||
| 545 | */ |
||
| 546 | public function commandReturn() { |
||
| 547 | $ReturnFlyingTime = ($this->_time_mission_job_complete != 0 && $this->_time_arrive_to_target < SN_TIME_NOW ? $this->_time_arrive_to_target : SN_TIME_NOW) - $this->_time_launch + SN_TIME_NOW + 1; |
||
| 548 | |||
| 549 | $this->markReturned(); |
||
| 550 | |||
| 551 | // Считаем, что флот уже долетел TODO |
||
| 552 | $this->time_arrive_to_target = SN_TIME_NOW; |
||
| 553 | // Убираем флот из группы |
||
| 554 | $this->group_id = 0; |
||
| 555 | // Отменяем работу в точке назначения |
||
| 556 | $this->time_mission_job_complete = 0; |
||
| 557 | // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения |
||
| 558 | $this->time_return_to_source = $ReturnFlyingTime; |
||
| 559 | |||
| 560 | // Записываем изменения в БД |
||
| 561 | $this->dbSave(); |
||
| 562 | |||
| 563 | if($this->_group_id) { |
||
| 564 | // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table |
||
| 565 | db_fleet_aks_purge(); |
||
| 566 | } |
||
| 567 | } |
||
| 568 | |||
| 569 | |||
| 570 | /** |
||
| 571 | * @return array |
||
| 572 | */ |
||
| 573 | public function target_coordinates_without_type() { |
||
| 574 | return array( |
||
| 575 | 'galaxy' => $this->_fleet_end_galaxy, |
||
| 576 | 'system' => $this->_fleet_end_system, |
||
| 577 | 'planet' => $this->_fleet_end_planet, |
||
| 578 | ); |
||
| 579 | } |
||
| 580 | |||
| 581 | /** |
||
| 582 | * @return array |
||
| 583 | */ |
||
| 584 | public function target_coordinates_typed() { |
||
| 585 | return array( |
||
| 586 | 'galaxy' => $this->_fleet_end_galaxy, |
||
| 587 | 'system' => $this->_fleet_end_system, |
||
| 588 | 'planet' => $this->_fleet_end_planet, |
||
| 589 | 'type' => $this->_fleet_end_type, |
||
| 590 | ); |
||
| 591 | } |
||
| 592 | |||
| 593 | /** |
||
| 594 | * @return array |
||
| 595 | */ |
||
| 596 | public function launch_coordinates_typed() { |
||
| 597 | return array( |
||
| 598 | 'galaxy' => $this->_fleet_start_galaxy, |
||
| 599 | 'system' => $this->_fleet_start_system, |
||
| 600 | 'planet' => $this->_fleet_start_planet, |
||
| 601 | 'type' => $this->_fleet_start_type, |
||
| 602 | ); |
||
| 603 | } |
||
| 604 | |||
| 605 | |||
| 606 | /** |
||
| 607 | * Sets object fields for fleet return |
||
| 608 | */ |
||
| 609 | public function markReturned() { |
||
| 610 | // TODO - Проверка - а не возвращается ли уже флот? |
||
| 611 | $this->is_returning = 1; |
||
| 612 | } |
||
| 613 | |||
| 614 | public function isReturning() { |
||
| 615 | return 1 == $this->_is_returning; |
||
| 616 | } |
||
| 617 | |||
| 618 | public function markReturnedAndSave() { |
||
| 619 | $this->markReturned(); |
||
| 620 | $this->dbSave(); |
||
| 621 | } |
||
| 622 | |||
| 623 | /** |
||
| 624 | * Parses extended unit_array which can include not only ships but resources, captains etc |
||
| 625 | * |
||
| 626 | * @param $unit_array |
||
| 627 | */ |
||
| 628 | // TODO - separate shipList and unitList |
||
| 629 | public function unitsSetFromArray($unit_array) { |
||
| 630 | if(empty($unit_array) || !is_array($unit_array)) { |
||
| 631 | return; |
||
| 632 | } |
||
| 633 | foreach($unit_array as $unit_id => $unit_count) { |
||
| 634 | $unit_count = floatval($unit_count); |
||
| 635 | if(!$unit_count) { |
||
| 636 | continue; |
||
| 637 | } |
||
| 638 | |||
| 639 | if($this->isShip($unit_id)) { |
||
| 640 | $this->unitList->unitSetCount($unit_id, $unit_count); |
||
| 641 | } elseif($this->isResource($unit_id)) { |
||
| 642 | $this->resource_list[$unit_id] = $unit_count; |
||
| 643 | } else { |
||
| 644 | throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), ERR_ERROR); |
||
| 645 | } |
||
| 646 | } |
||
| 647 | } |
||
| 648 | |||
| 649 | |||
| 650 | /** |
||
| 651 | * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time. |
||
| 652 | * |
||
| 653 | * @param int $time_to_travel - flight duration in seconds |
||
| 654 | * @param int $time_on_mission - time on mission in seconds |
||
| 655 | * @param int $group_sync_delta_time - delta time to adjust fleet arrival time if fleet is a part of group (i.e. ACS) |
||
| 656 | * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past |
||
| 657 | */ |
||
| 658 | public function set_times($time_to_travel, $time_on_mission = 0, $group_sync_delta_time = 0, $flight_departure = SN_TIME_NOW) { |
||
| 659 | $this->_time_launch = $flight_departure; |
||
| 660 | |||
| 661 | $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel + $group_sync_delta_time; |
||
| 662 | $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0; |
||
| 663 | $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel; |
||
| 664 | } |
||
| 665 | |||
| 666 | |||
| 667 | public function parse_missile_db_row($missile_db_row) { |
||
| 668 | // $this->_reset(); |
||
| 669 | |||
| 670 | if(empty($missile_db_row) || !is_array($missile_db_row)) { |
||
| 671 | return; |
||
| 672 | } |
||
| 673 | |||
| 674 | // $planet_start = db_planet_by_vector($irak_original, 'fleet_start_', false, 'name'); |
||
| 675 | // $irak_original['fleet_start_name'] = $planet_start['name']; |
||
| 676 | $this->missile_target = $missile_db_row['primaer']; |
||
| 677 | |||
| 678 | $this->_dbId = -$missile_db_row['id']; |
||
| 679 | $this->_playerOwnerId = $missile_db_row['fleet_owner']; |
||
| 680 | $this->_mission_type = MT_MISSILE; |
||
| 681 | |||
| 682 | $this->_target_owner_id = $missile_db_row['fleet_target_owner']; |
||
| 683 | |||
| 684 | $this->_group_id = 0; |
||
| 685 | $this->_is_returning = 0; |
||
| 686 | |||
| 687 | $this->_time_launch = 0; // $irak['start_time']; |
||
| 688 | $this->_time_arrive_to_target = 0; // $irak['fleet_start_time']; |
||
| 689 | $this->_time_mission_job_complete = 0; // $irak['fleet_end_stay']; |
||
| 690 | $this->_time_return_to_source = $missile_db_row['fleet_end_time']; |
||
| 691 | |||
| 692 | $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null; |
||
| 693 | $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy']; |
||
| 694 | $this->_fleet_start_system = $missile_db_row['fleet_start_system']; |
||
| 695 | $this->_fleet_start_planet = $missile_db_row['fleet_start_planet']; |
||
| 696 | $this->_fleet_start_type = $missile_db_row['fleet_start_type']; |
||
| 697 | |||
| 698 | $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null; |
||
| 699 | $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy']; |
||
| 700 | $this->_fleet_end_system = $missile_db_row['fleet_end_system']; |
||
| 701 | $this->_fleet_end_planet = $missile_db_row['fleet_end_planet']; |
||
| 702 | $this->_fleet_end_type = $missile_db_row['fleet_end_type']; |
||
| 703 | |||
| 704 | $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']); |
||
| 705 | } |
||
| 706 | |||
| 707 | |||
| 708 | /** |
||
| 709 | * @param $from |
||
| 710 | */ |
||
| 711 | public function set_start_planet($from) { |
||
| 712 | $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null; |
||
| 713 | $this->fleet_start_galaxy = $from['galaxy']; |
||
| 714 | $this->fleet_start_system = $from['system']; |
||
| 715 | $this->fleet_start_planet = $from['planet']; |
||
| 716 | $this->fleet_start_type = $from['planet_type']; |
||
| 717 | } |
||
| 718 | |||
| 719 | /** |
||
| 720 | * @param $to |
||
| 721 | */ |
||
| 722 | public function set_end_planet($to) { |
||
| 723 | $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0; |
||
| 724 | $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null; |
||
| 725 | $this->fleet_end_galaxy = $to['galaxy']; |
||
| 726 | $this->fleet_end_system = $to['system']; |
||
| 727 | $this->fleet_end_planet = $to['planet']; |
||
| 728 | $this->fleet_end_type = $to['planet_type']; |
||
| 729 | } |
||
| 730 | |||
| 731 | /** |
||
| 732 | * @param Vector $to |
||
| 733 | */ |
||
| 734 | public function setTargetFromVectorObject($to) { |
||
| 735 | $this->_fleet_end_galaxy = $to->galaxy; |
||
| 736 | $this->_fleet_end_system = $to->system; |
||
| 737 | $this->_fleet_end_planet = $to->planet; |
||
| 738 | $this->_fleet_end_type = $to->type; |
||
| 739 | } |
||
| 740 | |||
| 741 | /** |
||
| 742 | * @param array $db_row |
||
| 743 | */ |
||
| 744 | protected function ownerExtract(array &$db_row) { |
||
| 745 | $player = new Player(); |
||
| 746 | $player->dbLoad($db_row['fleet_owner']); |
||
| 747 | $this->setLocatedAt($player); |
||
| 748 | } |
||
| 749 | |||
| 750 | /** |
||
| 751 | * @param array $db_row |
||
| 752 | */ |
||
| 753 | protected function ownerInject(array &$db_row) { |
||
| 754 | $db_row['fleet_owner'] = $this->getPlayerOwnerId(); |
||
| 755 | } |
||
| 756 | |||
| 757 | |||
| 758 | |||
| 759 | |||
| 760 | // UnitList/Ships access *************************************************************************************************** |
||
| 761 | |||
| 762 | // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов |
||
| 763 | protected function isShip($unit_id) { |
||
| 764 | return UnitShip::is_in_group($unit_id); |
||
| 765 | } |
||
| 766 | |||
| 767 | /** |
||
| 768 | * Set unit count of $unit_id to $unit_count |
||
| 769 | * If there is no $unit_id - it will be created and saved to DB on dbSave |
||
| 770 | * |
||
| 771 | * @param int $unit_id |
||
| 772 | * @param int $unit_count |
||
| 773 | */ |
||
| 774 | public function shipSetCount($unit_id, $unit_count = 0) { |
||
| 775 | $this->shipAdjustCount($unit_id, $unit_count, true); |
||
| 776 | } |
||
| 777 | |||
| 778 | /** |
||
| 779 | * Adjust unit count of $unit_id by $unit_count - or just replace value |
||
| 780 | * If there is no $unit_id - it will be created and saved to DB on dbSave |
||
| 781 | * |
||
| 782 | * @param int $unit_id |
||
| 783 | * @param int $unit_count |
||
| 784 | * @param bool $replace_value |
||
| 785 | */ |
||
| 786 | public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) { |
||
| 787 | $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value); |
||
| 788 | } |
||
| 789 | |||
| 790 | public function shipGetCount($unit_id) { |
||
| 791 | return $this->unitList->unitGetCount($unit_id); |
||
| 792 | } |
||
| 793 | |||
| 794 | public function shipsCountApplyLossMultiplier($ships_lost_multiplier) { |
||
| 795 | $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier); |
||
| 796 | } |
||
| 797 | |||
| 798 | /** |
||
| 799 | * Returns ship list in fleet |
||
| 800 | */ |
||
| 801 | public function shipsGetArray() { |
||
| 802 | return $this->unitList->unitsGetArray(); |
||
| 803 | } |
||
| 804 | |||
| 805 | public function shipsGetTotal() { |
||
| 806 | return $this->unitList->unitsCount(); |
||
| 807 | } |
||
| 808 | |||
| 809 | public function shipsGetCapacity() { |
||
| 810 | return $this->unitList->shipsCapacity(); |
||
| 811 | } |
||
| 812 | |||
| 813 | public function shipsGetHoldFree() { |
||
| 814 | return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal()); |
||
| 815 | } |
||
| 816 | |||
| 817 | public function shipsGetTotalById($ship_id) { |
||
| 818 | return $this->unitList->unitsCountById($ship_id); |
||
| 819 | } |
||
| 820 | |||
| 821 | /** |
||
| 822 | * Возвращает ёмкость переработчиков во флоте |
||
| 823 | * |
||
| 824 | * @param array $recycler_info |
||
| 825 | * |
||
| 826 | * @return int |
||
| 827 | * |
||
| 828 | * @version 41a6.84 |
||
| 829 | */ |
||
| 830 | public function shipsGetCapacityRecyclers(array $recycler_info) { |
||
| 831 | $recyclers_incoming_capacity = 0; |
||
| 832 | $fleet_data = $this->shipsGetArray(); |
||
| 833 | foreach($recycler_info as $recycler_id => $recycler_data) { |
||
| 834 | $recyclers_incoming_capacity += $fleet_data[$recycler_id] * $recycler_data['capacity']; |
||
| 835 | } |
||
| 836 | |||
| 837 | return $recyclers_incoming_capacity; |
||
| 838 | } |
||
| 839 | |||
| 840 | /** |
||
| 841 | * Restores fleet or resources to planet |
||
| 842 | * |
||
| 843 | * @param bool $start |
||
| 844 | * @param int $result |
||
| 845 | * |
||
| 846 | * @return int |
||
| 847 | */ |
||
| 848 | // TODO - split to functions |
||
| 849 | public function shipsLand($start = true, &$result = CACHE_NOTHING) { |
||
| 850 | sn_db_transaction_check(true); |
||
| 851 | |||
| 852 | // Если флот уже обработан - не существует или возращается - тогда ничего не делаем |
||
| 853 | if($this->isEmpty()) { |
||
| 854 | return $result; |
||
| 855 | } |
||
| 856 | |||
| 857 | $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed(); |
||
| 858 | |||
| 859 | // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!! |
||
| 860 | // TODO Проверить от многократного срабатывания !!! |
||
| 861 | // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока |
||
| 862 | // TODO поменять на владельца планеты - когда его будут возвращать всегда !!! |
||
| 863 | |||
| 864 | // Узнаем ИД владельца планеты. |
||
| 865 | // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов. |
||
| 866 | // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок. |
||
| 867 | $planet_arrival = db_planet_by_vector($coordinates, '', true); |
||
| 868 | // Блокируем пользователя |
||
| 869 | // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда |
||
| 870 | $user = db_user_by_id($planet_arrival['id_owner'], true); |
||
| 871 | |||
| 872 | // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом |
||
| 873 | // Флот, который возвращается на захваченную планету, пропадает |
||
| 874 | // Ship landing is possible only to fleet owner's planet |
||
| 875 | if($this->getPlayerOwnerId() == $planet_arrival['id_owner']) { |
||
| 876 | $db_changeset = array(); |
||
| 877 | |||
| 878 | $fleet_array = $this->shipsGetArray(); |
||
| 879 | foreach($fleet_array as $ship_id => $ship_count) { |
||
| 880 | if($ship_count) { |
||
| 881 | $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship_count, $user, $planet_arrival['id']); |
||
| 882 | } |
||
| 883 | } |
||
| 884 | |||
| 885 | // Adjusting ship amount on planet |
||
| 886 | if(!empty($db_changeset)) { |
||
| 887 | db_changeset_apply($db_changeset); |
||
| 888 | } |
||
| 889 | |||
| 890 | // Restoring resources to planet |
||
| 891 | $this->resourcesUnload($start, $result); |
||
| 892 | } |
||
| 893 | |||
| 894 | $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST); |
||
| 895 | |||
| 896 | $result = RestoreFleetToPlanet($this, $start, $result); |
||
| 897 | |||
| 898 | $this->dbDelete(); |
||
| 899 | |||
| 900 | return $result; |
||
| 901 | } |
||
| 902 | |||
| 903 | |||
| 904 | // Resources access *************************************************************************************************** |
||
| 905 | |||
| 906 | /** |
||
| 907 | * Extracts resources value from db_row |
||
| 908 | * |
||
| 909 | * @param array $db_row |
||
| 910 | * |
||
| 911 | * @internal param Fleet $that |
||
| 912 | * @version 41a6.84 |
||
| 913 | */ |
||
| 914 | protected function resourcesExtract(array &$db_row) { |
||
| 915 | $this->resource_list = array( |
||
| 916 | RES_METAL => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0, |
||
| 917 | RES_CRYSTAL => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0, |
||
| 918 | RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0, |
||
| 919 | ); |
||
| 920 | } |
||
| 921 | |||
| 922 | protected function resourcesInject(array &$db_row) { |
||
| 923 | $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL]; |
||
| 924 | $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL]; |
||
| 925 | $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM]; |
||
| 926 | } |
||
| 927 | |||
| 928 | /** |
||
| 929 | * Set current resource list from array of units |
||
| 930 | * |
||
| 931 | * @param array $resource_list |
||
| 932 | */ |
||
| 933 | public function resourcesSet($resource_list) { |
||
| 934 | if(!empty($this->propertiesAdjusted['resource_list'])) { |
||
| 935 | throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR); |
||
| 936 | } |
||
| 937 | $this->resourcesAdjust($resource_list, true); |
||
| 938 | } |
||
| 939 | |||
| 940 | /** |
||
| 941 | * Updates fleet resource list with deltas |
||
| 942 | * |
||
| 943 | * @param $resource_delta_list |
||
| 944 | */ |
||
| 945 | public function resourcesAdjust($resource_delta_list, $replace_value = false) { |
||
| 946 | !is_array($resource_delta_list) ? $resource_delta_list = array() : false; |
||
| 947 | |||
| 948 | foreach($resource_delta_list as $resource_id => $unit_delta) { |
||
| 949 | if(!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) { |
||
| 950 | // Not a resource or no resources - continuing |
||
| 951 | continue; |
||
| 952 | } |
||
| 953 | |||
| 954 | if($replace_value) { |
||
| 955 | $this->resource_list[$resource_id] = $unit_delta; |
||
| 956 | } else { |
||
| 957 | $this->resource_list[$resource_id] += $unit_delta; |
||
| 958 | // Preparing changes |
||
| 959 | $this->resource_delta[$resource_id] += $unit_delta; |
||
| 960 | $this->propertiesAdjusted['resource_list'] = 1; |
||
| 961 | } |
||
| 962 | |||
| 963 | // Check for negative unit value |
||
| 964 | if($this->resource_list[$resource_id] < 0) { |
||
| 965 | // TODO |
||
| 966 | throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR); |
||
| 967 | } |
||
| 968 | } |
||
| 969 | } |
||
| 970 | |||
| 971 | public function resourcesGetTotal() { |
||
| 972 | return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list); |
||
| 973 | } |
||
| 974 | |||
| 975 | /** |
||
| 976 | * @param array $rate |
||
| 977 | * |
||
| 978 | * @return float |
||
| 979 | */ |
||
| 980 | public function resourcesGetTotalInMetal(array $rate) { |
||
| 981 | return |
||
| 982 | $this->resource_list[RES_METAL] * $rate[RES_METAL] |
||
| 983 | + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL] |
||
| 984 | + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL]; |
||
| 985 | } |
||
| 986 | |||
| 987 | /** |
||
| 988 | * Returns resource list in fleet |
||
| 989 | */ |
||
| 990 | // TODO |
||
| 991 | public function resourcesGetList() { |
||
| 992 | return $this->resource_list; |
||
| 993 | } |
||
| 994 | |||
| 995 | public function resourcesReset() { |
||
| 996 | $this->resourcesSet(array( |
||
| 997 | RES_METAL => 0, |
||
| 998 | RES_CRYSTAL => 0, |
||
| 999 | RES_DEUTERIUM => 0, |
||
| 1000 | )); |
||
| 1001 | } |
||
| 1002 | |||
| 1003 | /** |
||
| 1004 | * Restores fleet or resources to planet |
||
| 1005 | * |
||
| 1006 | * @param bool $start |
||
| 1007 | * @param bool $only_resources |
||
| 1008 | * @param int $result |
||
| 1009 | * |
||
| 1010 | * @return int |
||
| 1011 | */ |
||
| 1012 | public function resourcesUnload($start = true, &$result = CACHE_NOTHING) { |
||
| 1013 | sn_db_transaction_check(true); |
||
| 1014 | |||
| 1015 | // Если флот уже обработан - не существует или возращается - тогда ничего не делаем |
||
| 1016 | if(!$this->resourcesGetTotal()) { |
||
| 1017 | return $result; |
||
| 1018 | } |
||
| 1019 | |||
| 1020 | $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed(); |
||
| 1021 | |||
| 1022 | // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!! |
||
| 1023 | // TODO Проверить от многократного срабатывания !!! |
||
| 1024 | // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока |
||
| 1025 | // TODO поменять на владельца планеты - когда его будут возвращать всегда !!! |
||
| 1026 | |||
| 1027 | |||
| 1028 | // Узнаем ИД владельца планеты. |
||
| 1029 | // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов. |
||
| 1030 | // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок. |
||
| 1031 | $planet_arrival = db_planet_by_vector($coordinates, '', true); |
||
| 1032 | |||
| 1033 | // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом |
||
| 1034 | |||
| 1035 | // Restoring resources to planet |
||
| 1036 | if($this->resourcesGetTotal()) { |
||
| 1037 | $fleet_resources = $this->resourcesGetList(); |
||
| 1038 | db_planet_set_by_id($planet_arrival['id'], |
||
| 1039 | "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'"); |
||
| 1040 | } |
||
| 1041 | |||
| 1042 | $this->resourcesReset(); |
||
| 1043 | $this->markReturned(); |
||
| 1044 | |||
| 1045 | $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST); |
||
| 1046 | |||
| 1047 | return $result; |
||
| 1048 | } |
||
| 1049 | |||
| 1050 | |||
| 1051 | protected function isResource($unit_id) { |
||
| 1052 | return UnitResourceLoot::is_in_group($unit_id); |
||
| 1053 | } |
||
| 1054 | |||
| 1055 | /** |
||
| 1056 | * @param int $speed_percent |
||
| 1057 | * |
||
| 1058 | * @return array |
||
| 1059 | */ |
||
| 1060 | protected function flt_travel_data($speed_percent = 10) { |
||
| 1061 | $distance = $this->targetVector->distanceFromCoordinates($this->dbSourcePlanetRow); |
||
| 1062 | |||
| 1063 | return $this->unitList->travelData($speed_percent, $distance, $this->dbOwnerRow); |
||
| 1064 | } |
||
| 1065 | |||
| 1066 | |||
| 1067 | /** |
||
| 1068 | * @param array $dbPlayerRow |
||
| 1069 | * @param array $dbPlanetRow |
||
| 1070 | * @param Vector $targetVector |
||
| 1071 | * |
||
| 1072 | */ |
||
| 1073 | public function initDefaults($dbPlayerRow, $dbPlanetRow, $targetVector, $mission, $ships, $fleet_group_mr, $oldSpeedInTens) { |
||
| 1074 | $objFleet5Player = new Player(); |
||
| 1075 | $objFleet5Player->dbRowParse($dbPlayerRow); |
||
| 1076 | $this->setLocatedAt($objFleet5Player); |
||
| 1077 | |||
| 1078 | $this->mission_type = $mission; |
||
| 1079 | |||
| 1080 | $this->dbOwnerRow = $dbPlayerRow; |
||
| 1081 | |||
| 1082 | $this->set_start_planet($dbPlanetRow); |
||
| 1083 | $this->dbSourcePlanetRow = $dbPlanetRow; |
||
| 1084 | |||
| 1085 | $this->setTargetFromVectorObject($targetVector); |
||
| 1086 | $this->targetVector = $targetVector; |
||
| 1087 | |||
| 1088 | $this->populateTargetPlanet(); |
||
| 1089 | |||
| 1090 | $this->unitsSetFromArray($ships); |
||
| 1091 | |||
| 1092 | $this->_group_id = $fleet_group_mr; |
||
| 1093 | |||
| 1094 | $this->oldSpeedInTens = $oldSpeedInTens; |
||
| 1095 | |||
| 1096 | $this->fleetPage0Prepare(); |
||
| 1097 | |||
| 1098 | } |
||
| 1099 | |||
| 1100 | protected function populateTargetPlanet() { |
||
| 1101 | $targetPlanetCoords = $this->targetVector; |
||
| 1102 | if($this->mission_type != MT_NONE) { |
||
| 1103 | $this->restrictTargetTypeByMission(); |
||
| 1104 | |||
| 1105 | // TODO - Нельзя тут просто менять тип планеты или координат! |
||
| 1106 | // If current planet type is not allowed on mission - switch planet type |
||
| 1107 | if(empty($this->allowed_planet_types[$this->targetVector->type])) { |
||
| 1108 | $targetPlanetCoords->type = reset($this->allowed_planet_types); |
||
| 1109 | } |
||
| 1110 | } |
||
| 1111 | |||
| 1112 | $this->dbTargetRow = db_planet_by_vector_object($targetPlanetCoords); |
||
| 1113 | } |
||
| 1114 | |||
| 1115 | protected function restrictTargetTypeByMission() { |
||
| 1116 | if($this->_mission_type == MT_MISSILE) { |
||
| 1117 | $this->allowed_planet_types = array(PT_PLANET => PT_PLANET); |
||
| 1118 | } elseif($this->_mission_type == MT_COLONIZE || $this->_mission_type == MT_EXPLORE) { |
||
| 1119 | // TODO - PT_NONE |
||
| 1120 | $this->allowed_planet_types = array(PT_PLANET => PT_PLANET); |
||
| 1121 | } elseif($this->_mission_type == MT_RECYCLE) { |
||
| 1122 | $this->allowed_planet_types = array(PT_DEBRIS => PT_DEBRIS); |
||
| 1123 | } elseif($this->_mission_type == MT_DESTROY) { |
||
| 1124 | $this->allowed_planet_types = array(PT_MOON => PT_MOON); |
||
| 1125 | } else { |
||
| 1126 | $this->allowed_planet_types = array(PT_PLANET => PT_PLANET, PT_MOON => PT_MOON); |
||
| 1127 | } |
||
| 1128 | } |
||
| 1129 | |||
| 1130 | /** |
||
| 1131 | */ |
||
| 1132 | public function fleetPage0Prepare() { |
||
| 1133 | global $template_result; |
||
| 1134 | $template_result += array( |
||
| 1135 | 'thisgalaxy' => $this->dbSourcePlanetRow['galaxy'], |
||
| 1136 | 'thissystem' => $this->dbSourcePlanetRow['system'], |
||
| 1137 | 'thisplanet' => $this->dbSourcePlanetRow['planet'], |
||
| 1138 | 'thisplanet_type' => $this->dbSourcePlanetRow['planet_type'], |
||
| 1139 | |||
| 1140 | 'galaxy' => $this->targetVector->galaxy, |
||
| 1141 | 'system' => $this->targetVector->system, |
||
| 1142 | 'planet' => $this->targetVector->planet, |
||
| 1143 | 'planet_type' => $this->targetVector->type, |
||
| 1144 | 'target_mission' => $this->_mission_type, |
||
| 1145 | 'MISSION_NAME' => $this->_mission_type ? classLocale::$lang['type_mission'][$this->_mission_type] : '', |
||
| 1146 | |||
| 1147 | 'MT_COLONIZE' => MT_COLONIZE, |
||
| 1148 | ); |
||
| 1149 | |||
| 1150 | // pdump($this->targetVector->type);pdie(); |
||
| 1151 | } |
||
| 1152 | |||
| 1153 | |||
| 1154 | public function restrictToKnownSpace() { |
||
| 1155 | if(!$this->targetVector->isInKnownSpace()) { |
||
| 1156 | throw new Exception('FLIGHT_VECTOR_BEYOND_SYSTEM', FLIGHT_VECTOR_BEYOND_SYSTEM); |
||
| 1157 | } |
||
| 1158 | } |
||
| 1159 | |||
| 1160 | public function restrictToTypePlanet($errorCode) { |
||
| 1161 | if($this->targetVector->type != PT_PLANET) { |
||
| 1162 | throw new Exception($errorCode, $errorCode); |
||
| 1163 | } |
||
| 1164 | } |
||
| 1165 | |||
| 1166 | public function restrictToNoMissiles() { |
||
| 1167 | $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET); |
||
| 1168 | $missilesDefense = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERCEPTOR); |
||
| 1169 | if($missilesAttack > 0 || $missilesDefense > 0) { |
||
| 1170 | throw new Exception('FLIGHT_SHIPS_NO_MISSILES', FLIGHT_SHIPS_NO_MISSILES); |
||
| 1171 | } |
||
| 1172 | } |
||
| 1173 | |||
| 1174 | public function restrictToTargetOwn() { |
||
| 1175 | if($this->dbTargetRow['id'] != $this->getPlayerOwnerId()) { |
||
| 1176 | throw new Exception('FLIGHT_VECTOR_ONLY_OWN', FLIGHT_VECTOR_ONLY_OWN); |
||
| 1177 | } |
||
| 1178 | } |
||
| 1179 | |||
| 1180 | public function restrictToTargetOther() { |
||
| 1181 | if($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) { |
||
| 1182 | throw new Exception('FLIGHT_VECTOR_ONLY_OTHER', FLIGHT_VECTOR_ONLY_OTHER); |
||
| 1183 | } |
||
| 1184 | } |
||
| 1185 | |||
| 1186 | public function restrictToNotOnlySpies() { |
||
| 1187 | if($this->unitList->unitsCountById(SHIP_SPY) == $this->shipsGetTotal()) { |
||
| 1188 | throw new Exception('FLIGHT_SHIPS_NOT_ONLY_SPIES', FLIGHT_SHIPS_NOT_ONLY_SPIES); |
||
| 1189 | } |
||
| 1190 | } |
||
| 1191 | |||
| 1192 | protected function restrictToUniverse() { |
||
| 1193 | if(!$this->targetVector->isInUniverse()) { |
||
| 1194 | throw new Exception('FLIGHT_VECTOR_BEYOND_UNIVERSE', FLIGHT_VECTOR_BEYOND_UNIVERSE); |
||
| 1195 | } |
||
| 1196 | } |
||
| 1197 | |||
| 1198 | protected function restrictToMovable() { |
||
| 1199 | if(!$this->unitList->unitsIsAllMovable($this->dbOwnerRow)) { |
||
| 1200 | throw new Exception('FLIGHT_SHIPS_UNMOVABLE', FLIGHT_SHIPS_UNMOVABLE); |
||
| 1201 | } |
||
| 1202 | } |
||
| 1203 | |||
| 1204 | protected function restrictToFleetUnits() { |
||
| 1205 | if(!$this->unitList->unitsInGroup(sn_get_groups(array('fleet', 'missile')))) { |
||
| 1206 | throw new Exception('FLIGHT_SHIPS_UNIT_WRONG', FLIGHT_SHIPS_UNIT_WRONG); |
||
| 1207 | } |
||
| 1208 | } |
||
| 1209 | |||
| 1210 | protected function restrictToColonizer() { |
||
| 1211 | // Colonization fleet should have at least one colonizer |
||
| 1212 | if(!$this->unitList->unitsCountById(SHIP_COLONIZER) <= 0) { |
||
| 1213 | throw new Exception('FLIGHT_SHIPS_NO_COLONIZER', FLIGHT_SHIPS_NO_COLONIZER); |
||
| 1214 | } |
||
| 1215 | } |
||
| 1216 | |||
| 1217 | protected function restrictToTargetExists() { |
||
| 1218 | if(empty($this->dbTargetRow) || empty($this->dbTargetRow['id'])) { |
||
| 1219 | throw new Exception('FLIGHT_VECTOR_NO_TARGET', FLIGHT_VECTOR_NO_TARGET); |
||
| 1220 | } |
||
| 1221 | } |
||
| 1222 | |||
| 1223 | |||
| 1224 | View Code Duplication | protected function restrictKnownSpaceOrMissionExplore() { |
|
| 1225 | // Is it exploration - fleet sent beyond of system? |
||
| 1226 | if($this->targetVector->isInKnownSpace()) { |
||
| 1227 | // No exploration beyond this point |
||
| 1228 | unset($this->allowed_missions[MT_EXPLORE]); |
||
| 1229 | |||
| 1230 | $this->restrictToKnownSpace(); |
||
| 1231 | |||
| 1232 | return; |
||
| 1233 | } |
||
| 1234 | $this->restrictToNotOnlySpies(); |
||
| 1235 | $this->restrictToNoMissiles(); |
||
| 1236 | |||
| 1237 | $this->allowed_missions = array(MT_EXPLORE => MT_EXPLORE,); |
||
| 1238 | |||
| 1239 | throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED); |
||
| 1240 | } |
||
| 1241 | |||
| 1242 | View Code Duplication | protected function restrictTargetExistsOrMissionColonize() { |
|
| 1243 | // Is it colonization - fleet sent to empty place? |
||
| 1244 | if(!empty($this->dbTargetRow)) { |
||
| 1245 | // No colonization beyond this point |
||
| 1246 | unset($this->allowed_missions[MT_COLONIZE]); |
||
| 1247 | |||
| 1248 | $this->restrictToTargetExists(); |
||
| 1249 | |||
| 1250 | return; |
||
| 1251 | } |
||
| 1252 | // Only planet can be destination for colonization |
||
| 1253 | $this->restrictToTypePlanet(FLIGHT_MISSION_COLONIZE_NOT_PLANET); |
||
| 1254 | $this->restrictToColonizer(); |
||
| 1255 | $this->restrictToNoMissiles(); |
||
| 1256 | |||
| 1257 | $this->allowed_missions = array(MT_COLONIZE => MT_COLONIZE,); |
||
| 1258 | |||
| 1259 | throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED); |
||
| 1260 | } |
||
| 1261 | |||
| 1262 | protected function restrictNotDebrisOrMissionRecycle() { |
||
| 1263 | if($this->targetVector->type != PT_DEBRIS) { |
||
| 1264 | // No recycling beyond this point |
||
| 1265 | unset($this->allowed_missions[MT_RECYCLE]); |
||
| 1266 | |||
| 1267 | return; |
||
| 1268 | } |
||
| 1269 | |||
| 1270 | $this->restrictToNoMissiles(); |
||
| 1271 | |||
| 1272 | // restrict to recyclers |
||
| 1273 | $recyclers = 0; |
||
| 1274 | foreach(sn_get_groups('flt_recyclers') as $recycler_id) { |
||
| 1275 | $recyclers += $this->unitList->unitsCountById($recycler_id); |
||
| 1276 | } |
||
| 1277 | |||
| 1278 | if($recyclers <= 0) { |
||
| 1279 | throw new Exception('FLIGHT_SHIPS_NO_RECYCLERS', FLIGHT_SHIPS_NO_RECYCLERS); |
||
| 1280 | } |
||
| 1281 | |||
| 1282 | $this->allowed_missions = array(MT_RECYCLE => MT_RECYCLE,); |
||
| 1283 | |||
| 1284 | throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED); |
||
| 1285 | } |
||
| 1286 | |||
| 1287 | protected function restrictMissionMissile() { |
||
| 1288 | $missilesAttack = $this->unitList->unitsCountById(UNIT_DEF_MISSILE_INTERPLANET); |
||
| 1289 | if($missilesAttack <= 0) { |
||
| 1290 | // No missile attack beyond this point |
||
| 1291 | unset($this->allowed_missions[MT_MISSILE]); |
||
| 1292 | |||
| 1293 | return; |
||
| 1294 | } |
||
| 1295 | |||
| 1296 | if($missilesAttack != $this->shipsGetTotal()) { |
||
| 1297 | throw new Exception('FLIGHT_SHIPS_ONLY_MISSILES', FLIGHT_SHIPS_ONLY_MISSILES); |
||
| 1298 | } |
||
| 1299 | |||
| 1300 | $this->restrictToTypePlanet(FLIGHT_MISSION_MISSILE_ONLY_PLANET); |
||
| 1301 | $this->restrictToTargetOther(); |
||
| 1302 | |||
| 1303 | $this->allowed_missions = array(MT_MISSILE => MT_MISSILE,); |
||
| 1304 | throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED); |
||
| 1305 | } |
||
| 1306 | |||
| 1307 | View Code Duplication | protected function restrictToNotOnlySpiesOrMissionSpy() { |
|
| 1308 | if($this->unitList->unitsCountById(SHIP_SPY) != $this->shipsGetTotal()) { |
||
| 1309 | // throw new Exception('FLIGHT_SHIPS_ONLY_SPIES', FLIGHT_SHIPS_ONLY_SPIES); |
||
| 1310 | unset($this->allowed_missions[MT_SPY]); |
||
| 1311 | |||
| 1312 | $this->restrictToNotOnlySpies(); |
||
| 1313 | |||
| 1314 | return; |
||
| 1315 | } |
||
| 1316 | |||
| 1317 | $this->allowed_missions = array(MT_SPY => MT_SPY,); |
||
| 1318 | throw new Exception('FLIGHT_ALLOWED', FLIGHT_ALLOWED); |
||
| 1319 | } |
||
| 1320 | |||
| 1321 | protected function restrictMissionDestroy() { |
||
| 1322 | // If target vector is not Moon - then it can't be Destroy mission |
||
| 1323 | // If no Reapers (i.e. Death Star) in fleet - then mission Moon Destroy is unaccessible |
||
| 1324 | if($this->targetVector->type != PT_MOON || $this->unitList->unitsCountById(SHIP_HUGE_DEATH_STAR) <= 0) { |
||
| 1325 | unset($this->allowed_missions[MT_DESTROY]); |
||
| 1326 | } |
||
| 1327 | } |
||
| 1328 | |||
| 1329 | protected function restrictMissionACS() { |
||
| 1330 | // If no ACS group is shown - then it can't be an ACS attack |
||
| 1331 | if(empty($this->_group_id)) { |
||
| 1332 | unset($this->allowed_missions[MT_ACS]); |
||
| 1333 | } |
||
| 1334 | } |
||
| 1335 | |||
| 1336 | /** @throws Exception */ |
||
| 1337 | protected function restrictFriendOrFoe() { |
||
| 1338 | // Checking target owner |
||
| 1339 | View Code Duplication | if($this->dbTargetRow['id'] == $this->getPlayerOwnerId()) { |
|
| 1340 | // Spying can't be done on owner's planet/moon |
||
| 1341 | unset($this->allowed_missions[MT_SPY]); |
||
| 1342 | // Attack can't be done on owner's planet/moon |
||
| 1343 | unset($this->allowed_missions[MT_ATTACK]); |
||
| 1344 | // ACS can't be done on owner's planet/moon |
||
| 1345 | unset($this->allowed_missions[MT_ACS]); |
||
| 1346 | // Destroy can't be done on owner's moon |
||
| 1347 | unset($this->allowed_missions[MT_DESTROY]); |
||
| 1348 | |||
| 1349 | $this->restrictToNoMissiles(); |
||
| 1350 | |||
| 1351 | // MT_RELOCATE |
||
| 1352 | // No checks |
||
| 1353 | // TODO - check captain |
||
| 1354 | |||
| 1355 | // MT_HOLD |
||
| 1356 | // TODO - Check for Allies Deposit for HOLD |
||
| 1357 | |||
| 1358 | // MT_TRANSPORT |
||
| 1359 | |||
| 1360 | } else { |
||
| 1361 | // Relocate can be done only on owner's planet/moon |
||
| 1362 | unset($this->allowed_missions[MT_RELOCATE]); |
||
| 1363 | |||
| 1364 | // TODO - check for moratorium |
||
| 1365 | |||
| 1366 | // MT_HOLD |
||
| 1367 | // TODO - Check for Allies Deposit for HOLD |
||
| 1368 | // TODO - Noob protection for HOLD depends on server settings |
||
| 1369 | |||
| 1370 | // MT_SPY |
||
| 1371 | $this->restrictToNotOnlySpiesOrMissionSpy(); |
||
| 1372 | |||
| 1373 | // TODO - check noob protection |
||
| 1374 | |||
| 1375 | // TODO - check bashing |
||
| 1376 | |||
| 1377 | // No missions except MT_MISSILE should have any missiles in fleet |
||
| 1378 | $this->restrictMissionMissile(); |
||
| 1379 | $this->restrictToNoMissiles(); |
||
| 1380 | // Beyond this point no mission can have a missile in fleet |
||
| 1381 | |||
| 1382 | // MT_DESTROY |
||
| 1383 | $this->restrictMissionDestroy(); |
||
| 1384 | |||
| 1385 | // MT_ACS |
||
| 1386 | $this->restrictMissionACS(); |
||
| 1387 | |||
| 1388 | // MT_ATTACK - no checks |
||
| 1389 | |||
| 1390 | // MT_TRANSPORT - no checks |
||
| 1391 | } |
||
| 1392 | } |
||
| 1393 | |||
| 1394 | protected function restrictToNotSource() { |
||
| 1395 | if($this->targetVector->isEqualToPlanet($this->dbSourcePlanetRow)) { |
||
| 1396 | throw new Exception('FLIGHT_VECTOR_SAME_SOURCE', FLIGHT_VECTOR_SAME_SOURCE); |
||
| 1397 | } |
||
| 1398 | } |
||
| 1399 | |||
| 1400 | protected function restrictToNonVacationSender() { |
||
| 1401 | if(!empty($this->dbOwnerRow['vacation']) && $this->dbOwnerRow['vacation'] >= SN_TIME_NOW) { |
||
| 1402 | throw new Exception('FLIGHT_PLAYER_VACATION_OWN', FLIGHT_PLAYER_VACATION_OWN); |
||
| 1403 | } |
||
| 1404 | } |
||
| 1405 | |||
| 1406 | protected function restrictToValidSpeedPercentOld() { |
||
| 1407 | $speed_possible = array(10, 9, 8, 7, 6, 5, 4, 3, 2, 1); |
||
| 1408 | if(!in_array($this->oldSpeedInTens, $speed_possible)) { |
||
| 1409 | throw new Exception('FLIGHT_FLEET_SPEED_WRONG', FLIGHT_FLEET_SPEED_WRONG); |
||
| 1410 | } |
||
| 1411 | |||
| 1412 | } |
||
| 1413 | |||
| 1414 | protected function restrict2ToAllowedMissions() { |
||
| 1419 | |||
| 1420 | protected function restrict2ToAllowedPlanetTypes() { |
||
| 1425 | |||
| 1426 | protected function restrict2ToMaxFleets() { |
||
| 1431 | |||
| 1432 | protected function restrict2ToEnoughShips() { |
||
| 1437 | |||
| 1438 | protected function restrict2ToEnoughCapacity($fleetCapacity, $fleetConsumption) { |
||
| 1439 | if(floor($fleetCapacity) < ceil(array_sum($this->resource_list) + $fleetConsumption)) { |
||
| 1440 | throw new Exception('FLIGHT_FLEET_OVERLOAD', FLIGHT_FLEET_OVERLOAD); |
||
| 1441 | } |
||
| 1442 | } |
||
| 1443 | |||
| 1444 | protected function restrict2ByResources($fleetConsumption) { |
||
| 1445 | $fleetResources = $this->resource_list; |
||
| 1446 | $fleetResources[RES_DEUTERIUM] = ceil($fleetResources[RES_DEUTERIUM] + $fleetConsumption); |
||
| 1447 | foreach($fleetResources as $resourceId => $resourceAmount) { |
||
| 1448 | if($fleetResources[$resourceId] < 0) { |
||
| 1449 | throw new Exception('FLIGHT_RESOURCES_NEGATIVE', FLIGHT_RESOURCES_NEGATIVE); |
||
| 1450 | } |
||
| 1451 | |||
| 1452 | if(mrc_get_level($this->dbOwnerRow, $this->dbSourcePlanetRow, $resourceId) < ceil($fleetResources[$resourceId])) { |
||
| 1453 | if($resourceId == RES_DEUTERIUM) { |
||
| 1454 | throw new Exception('FLIGHT_RESOURCES_FUEL_NOT_ENOUGH', FLIGHT_RESOURCES_FUEL_NOT_ENOUGH); |
||
| 1455 | } else { |
||
| 1456 | throw new Exception('FLIGHT_RESOURCES_NOT_ENOUGH', FLIGHT_RESOURCES_NOT_ENOUGH); |
||
| 1457 | } |
||
| 1458 | } |
||
| 1459 | } |
||
| 1460 | } |
||
| 1461 | |||
| 1462 | /** |
||
| 1463 | * Restricts mission availability internally w/o DB access |
||
| 1464 | * |
||
| 1465 | * @throws Exception |
||
| 1466 | */ |
||
| 1467 | public function restrictMission() { |
||
| 1468 | // Only "cheap" checks that didn't require to query DB |
||
| 1469 | |||
| 1470 | |||
| 1471 | // Check for valid percent speed value |
||
| 1472 | $this->restrictToValidSpeedPercentOld(); |
||
| 1473 | |||
| 1474 | // Player in Vacation can't send fleets |
||
| 1475 | $this->restrictToNonVacationSender(); |
||
| 1476 | |||
| 1477 | // Fleet source and destination can't be the same |
||
| 1478 | $this->restrictToNotSource(); |
||
| 1479 | |||
| 1480 | // No mission could fly beyond Universe - i.e. with wrong Galaxy and/or System coordinates |
||
| 1481 | $this->restrictToUniverse(); |
||
| 1482 | |||
| 1483 | // Only ships and missiles can be sent to mission |
||
| 1484 | $this->restrictToFleetUnits(); |
||
| 1485 | // Only units with main engines (speed >=0) can fly - no other units like satellites |
||
| 1486 | $this->restrictToMovable(); |
||
| 1487 | |||
| 1488 | // No missions except MT_EXPLORE could target coordinates beyond known system |
||
| 1489 | $this->restrictKnownSpaceOrMissionExplore(); |
||
| 1490 | // Beyond this point all mission address only known space |
||
| 1491 | |||
| 1492 | // No missions except MT_COLONIZE could target empty coordinates |
||
| 1493 | $this->restrictTargetExistsOrMissionColonize(); |
||
| 1494 | // Beyond this point all mission address only existing planets/moons |
||
| 1495 | |||
| 1496 | // No missions except MT_RECYCLE could target debris |
||
| 1497 | $this->restrictNotDebrisOrMissionRecycle(); |
||
| 1498 | // Beyond this point targets can be only PT_PLANET or PT_MOON |
||
| 1499 | |||
| 1500 | // TODO - later then |
||
| 1501 | $this->restrictFriendOrFoe(); |
||
| 1502 | } |
||
| 1503 | |||
| 1504 | |||
| 1505 | protected function printErrorIfNoShips() { |
||
| 1506 | if($this->unitList->unitsCount() <= 0) { |
||
| 1507 | message(classLocale::$lang['fl_err_no_ships'], classLocale::$lang['fl_error'], 'fleet' . DOT_PHP_EX, 5); |
||
| 1508 | } |
||
| 1509 | } |
||
| 1510 | |||
| 1511 | /** |
||
| 1512 | * @param array $template_result |
||
| 1513 | * |
||
| 1514 | * @throws Exception |
||
| 1515 | */ |
||
| 1516 | protected function renderFleet(&$template_result) { |
||
| 1535 | |||
| 1536 | /** |
||
| 1537 | * @param array $template_result |
||
| 1538 | * |
||
| 1539 | * @return array |
||
| 1540 | */ |
||
| 1541 | protected function renderAllowedMissions(&$template_result) { |
||
| 1554 | |||
| 1555 | /** |
||
| 1556 | * @param $template_result |
||
| 1557 | */ |
||
| 1558 | protected function renderDuration(&$template_result, $max_duration) { |
||
| 1569 | |||
| 1570 | /** |
||
| 1571 | * @param array $planetResources |
||
| 1572 | * @param array &$template_result |
||
| 1573 | */ |
||
| 1574 | protected function renderPlanetResources(&$planetResources, &$template_result) { |
||
| 1586 | |||
| 1587 | /** |
||
| 1588 | * @param $template_result |
||
| 1589 | */ |
||
| 1590 | protected function renderAllowedPlanetTypes(&$template_result) { |
||
| 1599 | |||
| 1600 | protected function renderFleet1TargetSelect(&$shortcut) { |
||
| 1629 | |||
| 1630 | /** |
||
| 1631 | * @param $template_result |
||
| 1632 | */ |
||
| 1633 | protected function renderFleetShortcuts(&$template_result) { |
||
| 1640 | |||
| 1641 | /** |
||
| 1642 | * Building list of own planets & moons |
||
| 1643 | * |
||
| 1644 | * @param $template_result |
||
| 1645 | */ |
||
| 1646 | protected function renderOwnPlanets(&$template_result) { |
||
| 1660 | |||
| 1661 | /** |
||
| 1662 | * @param $template_result |
||
| 1663 | */ |
||
| 1664 | protected function renderACSList(&$template_result) { |
||
| 1675 | |||
| 1676 | /** |
||
| 1677 | * @param $template_result |
||
| 1678 | */ |
||
| 1679 | protected function renderShipSortOptions(&$template_result) { |
||
| 1691 | |||
| 1692 | /** |
||
| 1693 | */ |
||
| 1694 | public function fleetPage0() { |
||
| 1740 | |||
| 1741 | public function fleetPage1() { |
||
| 1769 | |||
| 1770 | public function fleetPage2() { |
||
| 1833 | |||
| 1834 | |||
| 1835 | public function restrict2MissionTransportWithResources($fleetResources) { |
||
| 1844 | |||
| 1845 | protected function restrict2MissionExploreAvailable() { |
||
| 1862 | |||
| 1863 | |||
| 1864 | public function fleetPage3($time_to_travel) { |
||
| 2316 | |||
| 2317 | |||
| 2318 | /** |
||
| 2319 | * @param array $checklist |
||
| 2320 | * |
||
| 2321 | * @throws Exception |
||
| 2322 | */ |
||
| 2323 | public function checkMissionRestrictions($checklist) { |
||
| 2338 | |||
| 2339 | protected function checkSpeedPercentOld() { |
||
| 2342 | |||
| 2343 | protected function checkSenderNoVacation() { |
||
| 2346 | |||
| 2347 | protected function checkTargetNoVacation() { |
||
| 2350 | |||
| 2351 | protected function checkMultiAccount() { |
||
| 2354 | |||
| 2355 | protected function checkFleetNotEmpty() { |
||
| 2358 | |||
| 2359 | protected function checkTargetNotSource() { |
||
| 2362 | |||
| 2363 | protected function checkTargetInUniverse() { |
||
| 2366 | |||
| 2367 | protected function checkUnitsPositive() { |
||
| 2370 | |||
| 2371 | protected function checkOnlyFleetUnits() { |
||
| 2374 | |||
| 2375 | protected function checkOnlyFlyingUnits() { |
||
| 2378 | |||
| 2379 | protected function checkEnoughFleetSlots() { |
||
| 2382 | |||
| 2383 | protected function checkSourceEnoughShips() { |
||
| 2386 | |||
| 2387 | protected function checkEnoughCapacity($includeResources = true) { |
||
| 2396 | |||
| 2397 | protected function checkNotTooFar() { |
||
| 2400 | |||
| 2401 | protected function checkDebrisExists() { |
||
| 2404 | |||
| 2405 | protected function checkResourcesPositive() { |
||
| 2414 | |||
| 2415 | protected function checkCargo() { |
||
| 2418 | |||
| 2419 | protected function checkSourceEnoughFuel() { |
||
| 2424 | |||
| 2425 | |||
| 2426 | protected function checkSourceEnoughResources() { |
||
| 2437 | |||
| 2438 | protected function checkKnownSpace() { |
||
| 2441 | |||
| 2442 | protected function checkNotOnlySpies() { |
||
| 2445 | |||
| 2446 | public function checkNoMissiles() { |
||
| 2452 | |||
| 2453 | |||
| 2454 | protected function checkTargetExists() { |
||
| 2457 | |||
| 2458 | protected function checkHaveColonizer() { |
||
| 2462 | |||
| 2463 | protected function checkTargetIsPlanet() { |
||
| 2466 | |||
| 2467 | protected function checkTargetIsDebris() { |
||
| 2470 | |||
| 2471 | protected function checkHaveRecyclers() { |
||
| 2479 | |||
| 2480 | |||
| 2481 | // TODO |
||
| 2482 | protected function checkTargetOwn() { |
||
| 2513 | |||
| 2514 | |||
| 2515 | protected function alwaysFalse() { |
||
| 2518 | |||
| 2519 | |||
| 2520 | protected function checkSpiesOnly() { |
||
| 2532 | |||
| 2533 | protected function checkTargetAllyDeposit() { |
||
| 2541 | |||
| 2542 | |||
| 2543 | protected function checkMissionsOwn() { |
||
| 2561 | |||
| 2562 | protected function checkMission($missionType) { |
||
| 2574 | |||
| 2575 | protected function checkMissionNonRestrict($missionType) { |
||
| 2578 | |||
| 2579 | protected function checkMissionExplore() { |
||
| 2582 | |||
| 2583 | protected function checkMissionColonize() { |
||
| 2586 | |||
| 2587 | protected function checkMissionRecycle() { |
||
| 2590 | |||
| 2591 | protected function checkMissionMissile() { |
||
| 2594 | |||
| 2595 | protected function checkNotEmptyMission() { |
||
| 2598 | |||
| 2599 | |||
| 2600 | protected function checkMissionRelocate() { |
||
| 2603 | |||
| 2604 | protected function checkMissionHoldNonUnique() { |
||
| 2609 | |||
| 2610 | protected function checkMissionTransport() { |
||
| 2619 | |||
| 2620 | |||
| 2621 | protected function checkMissionSpy() { |
||
| 2624 | |||
| 2625 | |||
| 2626 | protected function checkRealFlight() { |
||
| 2629 | |||
| 2630 | protected function checkMissionExists() { |
||
| 2633 | |||
| 2634 | protected function checkTargetActive() { |
||
| 2640 | |||
| 2641 | // TODO - REDO MAIN FUNCTION |
||
| 2642 | protected function checkTargetNotActive() { |
||
| 2645 | |||
| 2646 | |||
| 2647 | protected function checkSameAlly() { |
||
| 2650 | |||
| 2651 | protected function checkTargetNoob() { |
||
| 2661 | |||
| 2662 | // TODO - REDO MAIN FUNCTION |
||
| 2663 | protected function checkTargetNotNoob() { |
||
| 2666 | |||
| 2667 | |||
| 2668 | protected function checkMissionHoldReal() { |
||
| 2674 | |||
| 2675 | |||
| 2676 | |||
| 2677 | protected function checkMissionHoldOnNotNoob() { |
||
| 2685 | |||
| 2686 | |||
| 2687 | protected function checkOnlyAttackMissiles() { |
||
| 2692 | |||
| 2693 | } |
||
| 2694 |
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.