Completed
Push — master ( 6328f8...dd2c0a )
by Andres
29s
created

src/scripts/component/exotic.js   B

Complexity

Total Complexity 36
Complexity/F 2.12

Size

Lines of Code 182
Function Count 17

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 0
wmc 36
c 4
b 0
f 0
nc 1536
mnd 3
bc 31
fnc 17
dl 0
loc 182
rs 8.8
bpm 1.8235
cpm 2.1176
noi 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B angular.controller(ꞌct_exoticꞌ) 0 172 1
1
/**
2
 exotic
3
 Component that handles the exotic matter and prestige logic.
4
 It includes exotic matter production, exotic upgrades, and infusion of
5
 subatomic particles to boost exotic production.
6
 A prestige erases the progress of a single element, and produces exotic
7
 matter for said element.
8
9
 @namespace Components
10
 */
11
'use strict';
12
13
angular.module('game').component('exotic', {
14
  templateUrl: 'views/exotic.html',
15
  controller:  'ct_exotic',
16
  controllerAs: 'ct'
17
});
18
19
angular.module('game').controller('ct_exotic', ['state', 'format', 'visibility', 'upgrade', 'data', 'util',
20
  function (state, format, visibility, upgrade, data, util) {
21
    let ct = this;
22
    ct.state = state;
23
    ct.data = data;
24
    ct.util = util;
25
    ct.format = format;
26
    ct.infuse = {};
27
    let sortFunc = [
28
      (a,b) => data.exotic_upgrades[a].name < data.exotic_upgrades[b].name ? -1 : 1,
29
      (a,b) => data.exotic_upgrades[a].price - data.exotic_upgrades[b].price
30
    ]
31
32
    /* Exotic production is a function of the different resources of each
33
    element. Additionally, multi-element molecules count double, once for
34
    each participating element. */
35
    ct.exoticProduction = function(element) {
36
      let breakdown = {};
37
      for (let resource of data.elements[element].includes) {
38
        let production = {};
39
        if (!state.player.resources[resource].unlocked ||
40
            typeof state.player.statistics.exotic_run[element][resource] === 'undefined') {
41
          continue;
42
        }
43
        for (let elem in data.resources[resource].elements) {
44
          if(!state.player.statistics.exotic_run[elem]){
45
             continue;
46
          }
47
          let numberAtoms = data.resources[resource].elements[elem];
48
          let prod = prestigeFormula((state.player.statistics.exotic_run[elem][resource] || 0)*numberAtoms);
49
50
          let args = {
51
            production: prod,
52
            resource: resource
53
          };
54
55
          upgrade.executeAll(data.exotic_upgrades, state.player.exotic_upgrades[elem], ['production', 'exotic'], args);
56
57
          // extract back the value from applying the upgrades
58
          let newExotic = data.elements[elem].exotic;
59
          production[newExotic] = (production[newExotic] || 0) + args.production;
60
        }
61
        for (let key in production) {
62
          // we adjust the infusion
63
          production[key] = Math.floor(production[key]*ct.totalInfuseBoost());
64
        }
65
        breakdown[resource] = production;
66
      }
67
68
      return breakdown;
69
    };
70
71
    ct.productionSum = function(element){
72
      let production = ct.exoticProduction(element);
73
      let sum = {};
74
      for(let resource in production){
75
        for(let elem in production[resource]){
76
          sum[elem] = sum[elem]+production[resource][elem] || production[resource][elem];
77
        }
78
      }
79
      return sum;
80
    }
81
82
    function prestigeFormula(resource){
83
      resource = resource || 0;
84
      let production = Math.pow(Math.E,(-0.5+Math.sqrt(0.25+0.8686*Math.log(resource/1e6)))/0.4343) || 0;
85
      return Math.round(Math.max(0, production));
86
    }
87
88
    ct.exoticPrestige = function(index) {
89
      let slot = state.player.element_slots[index];
90
      let production = ct.productionSum(slot.element);
91
92
      for (let key in production) {
93
        util.addResource(state.player, 'dark', key, production[key]);
94
      }
95
96
      for(let resource in ct.infuse){
97
        state.player.resources[resource].number = Math.max(0, state.player.resources[resource].number-ct.infuse[resource]);
98
      }
99
100
      upgrade.resetElement(state.player, slot.element);
101
102
      // we deactivate reactions and redoxes
103
      for (let reaction of slot.reactions) {
104
        reaction.active = false;
105
      }
106
107
      for (let redox of slot.redoxes) {
108
        redox.active = false;
109
      }
110
111
      // we cache them in case players want to pick up the same element
112
      // the cache only lasts the current session
113
      state.reactionsCache[slot.element] = slot.reactions;
114
      state.redoxesCache[slot.element] = slot.redoxes;
115
116
      state.player.element_slots[index] = null;
117
      state.player.statistics.exotic_run[slot.element] = {};
118
    };
119
120
    ct.buyExoticUpgrade = function(name, slot) {
121
      let price = data.exotic_upgrades[name].price;
122
      let currency = data.elements[slot.element].exotic;
123
      upgrade.buyUpgrade(state.player,
124
        state.player.exotic_upgrades[slot.element],
125
        data.exotic_upgrades[name],
126
        name,
127
        price,
128
        currency);
129
    };
130
131
    ct.setPercentage = function(resource, percentage) {
132
      ct.infuse[resource] = Math.floor(state.player.resources[resource].number*(percentage/100));
133
    };
134
135
    ct.fixNumber = function(resource) {
136
      ct.infuse[resource] = Math.max(0, Math.min(state.player.resources[resource].number, ct.infuse[resource]));
137
    };
138
139
    /* This function checks that values inserted in the text boxes are
140
    valid numbers */
141
    ct.isValidInfusion = function() {
142
      let valid = true;
143
      for(let resource in ct.infuse){
144
        valid = valid && Number.isFinite(ct.infuse[resource]);
145
      }
146
      return valid;
147
    };
148
149
    ct.infuseBoost = function(resource) {
150
        let number = Math.min(ct.infuse[resource], state.player.resources[resource].number);
151
        if(number === 0){
152
          return 1;
153
        }
154
        // log adds diminishing returns to the infusion
155
        return 1 + Math.log(number)/Math.log(1.25)*ct.data.constants.INFUSE_POWER;
156
    };
157
158
    /* The infusion boosts are multiplicative with respect to each other */
159
    ct.totalInfuseBoost = function() {
160
      let total = 1;
161
      for(let resource in ct.infuse){
162
        total *= ct.infuseBoost(resource);
163
      }
164
      return total;
165
    };
166
167
    ct.visibleExoticUpgrades = function(slot) {
168
      return visibility.visible(data.exotic_upgrades, isExoticUpgradeVisible, slot, sortFunc[state.sort]);
169
    };
170
171
    function isExoticUpgradeVisible(name, slot) {
172
      return visibility.isUpgradeVisible(name, slot, data.exotic_upgrades[name]) && (!state.hideBought || !state.player.exotic_upgrades[slot.element][name]);
173
    }
174
175
    ct.visibleSubatomic = function() {
176
      return visibility.visible(data.resources, isSubatomicVisible, '');
177
    };
178
179
    function isSubatomicVisible(name) {
180
      if (!state.player.resources[name].unlocked) {
181
        return false;
182
      }
183
184
      if(data.resources[name].type &&
185
         data.resources[name].type.indexOf('subatomic') !== -1){
186
          return true;
187
      }
188
189
      return false;
190
    }
191
  }
192
]);
193