Completed
Push — work-fleets ( fff2b6...e0e753 )
by SuperNova.WS
06:54
created

eco_get_build_data.php ➔ eco_get_build_data()   F

Complexity

Conditions 31
Paths > 20000

Size

Total Lines 105
Code Lines 76

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 31
eloc 76
nc 247040
nop 5
dl 0
loc 105
rs 2
c 3
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
function eco_lab_sort_effectivness($a, $b) {
4
  return $a['laboratory_effective_level'] > $b['laboratory_effective_level'] ? -1 : ($a['laboratory_effective_level'] < $b['laboratory_effective_level'] ? 1 : 0);
5
}
6
7
/**
8
 * eco_get_build_data.php
9
 *
10
 * 1.0 - copyright (c) 2010 by Gorlum for http://supernova.ws
11
 * @version 1.0
12
 */
13
function eco_get_lab_max_effective_level(&$user, $lab_require) {
14
  if (!$user['user_as_ally'] && !isset($user['laboratories_active'])) {
15
    $user['laboratories_active'] = array();
16
    $query = db_unit_list_laboratories($user['id']);
17
    while ($row = db_fetch($query)) {
18
      if (!eco_unit_busy($user, $row, UNIT_TECHNOLOGIES)) {
19
        $row += array(
20
          STRUC_LABORATORY             => $level_lab = mrc_get_level($user, $row, STRUC_LABORATORY),
21
          STRUC_LABORATORY_NANO        => $level_lab_nano = mrc_get_level($user, $row, STRUC_LABORATORY_NANO),
22
          'laboratory_effective_level' => $level_lab * pow(2, $level_lab_nano),
23
        );
24
        $user['laboratories_active'][$row['id']] = $row;
25
      }
26
    }
27
28
    uasort($user['laboratories_active'], 'eco_lab_sort_effectivness');
29
  }
30
31
  if (!isset($user['research_effective_level'][$lab_require])) {
32
    if ($user['user_as_ally']) {
33
      $lab_level = db_ally_get_ally_count($user);
34
    } else {
35
      $tech_intergalactic = mrc_get_level($user, null, TECH_RESEARCH) + 1;
36
      $lab_level['effective_level'] = 0;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$lab_level was never initialized. Although not strictly required by PHP, it is generally a good practice to add $lab_level = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
37
38
      foreach ($user['laboratories_active'] as $data) {
39
        if ($tech_intergalactic <= 0) {
40
          break;
41
        }
42
        if ($data[STRUC_LABORATORY] >= $lab_require) {
43
          $lab_level['effective_level'] += $data['laboratory_effective_level'];
44
          $tech_intergalactic--;
45
        }
46
      }
47
    }
48
    $user['research_effective_level'][$lab_require] = $lab_level['effective_level'] ? $lab_level['effective_level'] : 1;
49
  }
50
51
  return $user['research_effective_level'][$lab_require];
52
}
53
54
function eco_get_build_data(&$user, $planet, $unit_id, $unit_level = 0, $only_cost = false) {
55
  $rpg_exchange_deuterium = classSupernova::$config->rpg_exchange_deuterium;
56
57
  $unit_data = get_unit_param($unit_id);
58
  // $unit_db_name = &$unit_data[P_NAME];
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
59
60
  $unit_factor = $unit_data[P_COST][P_FACTOR] ? $unit_data[P_COST][P_FACTOR] : 1;
61
  $price_increase = pow($unit_factor, $unit_level);
62
63
  $can_build = isset($unit_data[P_MAX_STACK]) && $unit_data[P_MAX_STACK] ? $unit_data[P_MAX_STACK] : 1000000000000;
64
  $can_destroy = 1000000000000;
65
  $time = 0;
66
  $only_dark_matter = 0;
67
  $cost_in_metal = 0;
68
  $cost = array();
69
  foreach ($unit_data[P_COST] as $resource_id => $resource_amount) {
70
    if ($resource_id === P_FACTOR || !($resource_cost = $resource_amount * $price_increase)) {
71
      continue;
72
    }
73
74
    $cost[BUILD_CREATE][$resource_id] = round($resource_cost);
75
    $cost[BUILD_DESTROY][$resource_id] = round($resource_cost / 2);
76
77
    $resource_db_name = pname_resource_name($resource_id);
78
    $cost_in_metal += $cost[BUILD_CREATE][$resource_id] * classSupernova::$config->__get("rpg_exchange_{$resource_db_name}");
79
    if (in_array($resource_id, sn_get_groups('resources_loot'))) {
80
      $time += $resource_cost * classSupernova::$config->__get("rpg_exchange_{$resource_db_name}") / $rpg_exchange_deuterium;
81
      $resource_got = mrc_get_level($user, $planet, $resource_id);
82
    } elseif ($resource_id == RES_DARK_MATTER) {
83
      $resource_got = mrc_get_level($user, null, $resource_id);
84
    } elseif ($resource_id == RES_ENERGY) {
85
      $resource_got = max(0, $planet['energy_max'] - $planet['energy_used']);
86
    } else {
87
      $resource_got = 0;
88
    }
89
    $only_dark_matter = $only_dark_matter ? $only_dark_matter : $resource_id;
90
91
    $can_build = min($can_build, $resource_got / $cost[BUILD_CREATE][$resource_id]);
92
    $can_destroy = min($can_destroy, $resource_got / $cost[BUILD_DESTROY][$resource_id]);
93
  }
94
95
  $resources_normalized = 0;
96
  $resources_loot = sn_get_groups('resources_loot');
97
  foreach ($resources_loot as $resource_id) {
98
    $resource_db_name = pname_resource_name($resource_id);
99
    $resource_got = mrc_get_level($user, $planet, $resource_id);
100
    $resources_normalized += floor($resource_got) * classSupernova::$config->__get("rpg_exchange_{$resource_db_name}");
101
  }
102
103
  $cost[BUILD_AUTOCONVERT] = $only_dark_matter != RES_DARK_MATTER ? max(!empty($unit_data[P_MAX_STACK]) ? $unit_data[P_MAX_STACK] : 0, floor($resources_normalized / $cost_in_metal)) : 0;
104
105
  $can_build = $can_build > 0 ? floor($can_build) : 0;
106
  $cost['CAN'][BUILD_CREATE] = $can_build;
107
108
  $can_destroy = $can_destroy > 0 ? floor($can_destroy) : 0;
109
  $cost['CAN'][BUILD_DESTROY] = $can_destroy;
110
111
  $cost[P_OPTIONS][P_ONLY_DARK_MATTER] = $only_dark_matter = $only_dark_matter == RES_DARK_MATTER;
112
  $cost[P_OPTIONS][P_TIME_RAW] = $time = $time * 60 * 60 / get_game_speed() / 2500;
113
114
  // TODO - Вынести в отдельную процедуру расчёт стоимости
115
  if ($only_cost) {
116
    return $cost;
117
  }
118
119
  $cost['RESULT'][BUILD_CREATE] = eco_can_build_unit($user, $planet, $unit_id);
120
  $cost['RESULT'][BUILD_CREATE] = $cost['RESULT'][BUILD_CREATE] == BUILD_ALLOWED ? ($cost['CAN'][BUILD_CREATE] ? BUILD_ALLOWED : BUILD_NO_RESOURCES) : $cost['RESULT'][BUILD_CREATE];
121
122
  $mercenary = 0;
123
  $cost['RESULT'][BUILD_DESTROY] = BUILD_INDESTRUCTABLE;
124
  if (in_array($unit_id, sn_get_groups('structures'))) {
125
    $time = $time * pow(0.5, mrc_get_level($user, $planet, STRUC_FACTORY_NANO)) / (mrc_get_level($user, $planet, STRUC_FACTORY_ROBOT) + 1);
126
    $mercenary = MRC_ENGINEER;
127
    $cost['RESULT'][BUILD_DESTROY] =
128
      mrc_get_level($user, $planet, $unit_id, null, true)
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
129
        ? ($cost['CAN'][BUILD_DESTROY]
130
        ? ($cost['RESULT'][BUILD_CREATE] == BUILD_UNIT_BUSY ? BUILD_UNIT_BUSY : BUILD_ALLOWED)
131
        : BUILD_NO_RESOURCES
132
      )
133
        : BUILD_NO_UNITS;
134
  } elseif (in_array($unit_id, sn_get_groups('tech'))) {
135
    $lab_level = eco_get_lab_max_effective_level($user, intval($unit_data['require'][STRUC_LABORATORY]));
136
    $time = $time / $lab_level;
137
    $mercenary = MRC_ACADEMIC;
138
  } elseif (in_array($unit_id, sn_get_groups('defense'))) {
139
    $time = $time * pow(0.5, mrc_get_level($user, $planet, STRUC_FACTORY_NANO)) / (mrc_get_level($user, $planet, STRUC_FACTORY_HANGAR) + 1);
140
    $mercenary = MRC_FORTIFIER;
141
  } elseif (in_array($unit_id, sn_get_groups('fleet'))) {
142
    $time = $time * pow(0.5, mrc_get_level($user, $planet, STRUC_FACTORY_NANO)) / (mrc_get_level($user, $planet, STRUC_FACTORY_HANGAR) + 1);
143
    $mercenary = MRC_ENGINEER;
144
  }
145
146
  if ($mercenary) {
147
    $time = $time / mrc_modify_value($user, $planet, $mercenary, 1);
148
  }
149
150
  if (in_array($unit_id, sn_get_groups('governors')) || $only_dark_matter) {
151
    $cost[RES_TIME][BUILD_CREATE] = $cost[RES_TIME][BUILD_DESTROY] = 0;
152
  } else {
153
    $cost[RES_TIME][BUILD_CREATE] = round($time >= 1 ? $time : 1);
154
    $cost[RES_TIME][BUILD_DESTROY] = round($time / 2 <= 1 ? 1 : $time / 2);
155
  }
156
157
  return $cost;
158
}
159
160
function eco_can_build_unit($user, $planet, $unit_id) { return sn_function_call(__FUNCTION__, array($user, $planet, $unit_id, &$result)); }
0 ignored issues
show
Bug introduced by
The variable $result does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
161
162
function sn_eco_can_build_unit($user, $planet, $unit_id, &$result) {
163
  $result = isset($result) ? $result : BUILD_ALLOWED;
164
  $result = $result == BUILD_ALLOWED && eco_unit_busy($user, $planet, $unit_id) ? BUILD_UNIT_BUSY : $result;
165
166
  $unit_param = get_unit_param($unit_id);
167
  if ($unit_param[P_UNIT_TYPE] != UNIT_MERCENARIES || !classSupernova::$config->empire_mercenary_temporary) {
168
    $requirement = &$unit_param[P_REQUIRE];
169
    if ($result == BUILD_ALLOWED && $requirement) {
170
      foreach ($requirement as $require_id => $require_level) {
171
        if (mrc_get_level($user, $planet, $require_id) < $require_level) {
172
          $result = BUILD_REQUIRE_NOT_MEET;
173
          break;
174
        }
175
      }
176
    }
177
  }
178
179
  return $result;
180
}
181
182
function eco_is_builds_in_que($planet_que, $unit_list) {
183
  $eco_is_builds_in_que = false;
184
185
  $unit_list = is_array($unit_list) ? $unit_list : array($unit_list => $unit_list);
186
  $planet_que = explode(';', $planet_que);
187
  foreach ($planet_que as $planet_que_item) {
188
    if ($planet_que_item) {
189
      list($planet_que_item) = explode(',', $planet_que_item);
190
      if (in_array($planet_que_item, $unit_list)) {
191
        $eco_is_builds_in_que = true;
192
        break;
193
      }
194
    }
195
  }
196
197
  return $eco_is_builds_in_que;
198
}
199
200
function eco_unit_busy(&$user, &$planet, $unit_id) { return sn_function_call(__FUNCTION__, array(&$user, &$planet, $unit_id, &$result)); }
0 ignored issues
show
Bug introduced by
The variable $result does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
201
202
function sn_eco_unit_busy(&$user, &$planet, $unit_id, &$result) {
203
  $result = isset($result) ? $result : false;
204
  if (!$result) {
205
    if (($unit_id == STRUC_LABORATORY || $unit_id == STRUC_LABORATORY_NANO) && !classSupernova::$config->BuildLabWhileRun) {
206
      $global_que = que_get($user['id'], $planet['id'], QUE_RESEARCH, false);
0 ignored issues
show
Documentation introduced by
QUE_RESEARCH is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
207
      if (is_array($global_que['ques'][QUE_RESEARCH][$user['id']])) {
208
        $first_element = reset($global_que['ques'][QUE_RESEARCH][$user['id']]);
209
        if (is_array($first_element)) {
210
          $result = true;
211
        }
212
      }
213
      //if(!empty($global_que['ques'][QUE_RESEARCH][$user['id']][0]))
0 ignored issues
show
Unused Code Comprehensibility introduced by
96% 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...
214
      //{
215
      //  $result = true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
216
      //}
217
    } elseif (($unit_id == UNIT_TECHNOLOGIES || in_array($unit_id, sn_get_groups('tech'))) && !classSupernova::$config->BuildLabWhileRun && $planet['que']) {
218
      $result = eco_is_builds_in_que($planet['que'], array(STRUC_LABORATORY, STRUC_LABORATORY_NANO));
219
    }
220
  }
221
222
//  switch($unit_id)
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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...
223
//  {
224
//    case STRUC_FACTORY_HANGAR:
225
//      $hangar_busy = $planet['b_hangar'] && $planet['b_hangar_id'];
226
//      $return = $hangar_busy;
227
//    break;
228
//  }
229
230
  return $result;
231
}
232