Completed
Push — master ( 78b239...b3de34 )
by Andres
37s
created

angular.controller(ꞌct_exoticꞌ)   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
c 0
b 0
f 0
nc 3
dl 0
loc 10
rs 9.4285
nop 2
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
      function(a,b){
29
        if(data.exotic_upgrades[a].name === data.exotic_upgrades[b].name){
30
          return data.exotic_upgrades[a].price - data.exotic_upgrades[b].price;
31
        }
32
        if(data.exotic_upgrades[a].name < data.exotic_upgrades[b].name){
33
          return -1;
34
        }else{
35
          return 1;
36
        }
37
      },
38
      (a,b) => data.exotic_upgrades[a].price - data.exotic_upgrades[b].price
39
    ];
40
    ct.cache = {breakdown:{}};
41
42
    ct.update = function(player) {
43
      refresh(player);
44
    };
45
46
    /* Refreshes the values in the cache */
47
    function refresh(player){
48
        ct.cache.breakdown = {};
49
        for(let slot of player.element_slots || []){
50
          if(!slot){
51
            continue;
52
          }
53
          ct.cache.breakdown[slot.element] = ct.exoticProduction(slot.element);
54
        }
55
    }
56
57
    /* Exotic production is a function of the different resources of each
58
    element. Additionally, multi-element molecules count double, once for
59
    each participating element. */
60
    ct.exoticProduction = function(element) {
61
      let breakdown = {};
62
      for (let resource of data.elements[element].includes) {
63
        if (!state.player.resources[resource].unlocked ||
64
            !state.player.statistics.exotic_run[element] ||
65
            typeof state.player.statistics.exotic_run[element][resource] === 'undefined') {
66
          continue;
67
        }
68
        let production = {};
69
        for (let elem in data.resources[resource].elements) {
70
          if(!state.player.statistics.exotic_run[elem]){
71
             continue;
72
          }
73
          let numberAtoms = data.resources[resource].elements[elem];
74
          let prod = prestigeFormula((state.player.statistics.exotic_run[elem][resource] || 0)*numberAtoms);
75
76
          let args = {
77
            production: prod,
78
            resource: resource
79
          };
80
81
          upgrade.executeAll(data.exotic_upgrades, state.player.exotic_upgrades[elem], ['production', 'exotic'], args);
82
83
          // extract back the value from applying the upgrades
84
          let newExotic = data.elements[elem].exotic;
85
          production[newExotic] = (production[newExotic] || 0) + args.production;
86
        }
87
        for (let key in production) {
88
          // we adjust the infusion
89
          production[key] = Math.floor(production[key]*ct.totalInfuseBoost());
90
        }
91
        breakdown[resource] = production;
92
      }
93
94
      return breakdown;
95
    };
96
97
    ct.productionSum = function(element){
98
      let production = ct.cache.breakdown[element] || {};
99
      let sum = {};
100
	    sum[data.elements[element].exotic] = 0;
101
      for(let resource in production){
102
        for(let elem in production[resource]){
103
          sum[elem] = sum[elem]+production[resource][elem] || production[resource][elem];
104
        }
105
      }
106
      return sum;
107
    };
108
109
    function prestigeFormula(resource){
110
      resource = resource || 0;
111
      let production = Math.pow(Math.E,(-0.5+Math.sqrt(0.25+0.8686*Math.log(resource/1e6)))/0.4343) || 0;
112
      return Math.round(Math.max(0, production));
113
    }
114
115
    ct.exoticPrestige = function(index) {
116
      let slot = state.player.element_slots[index];
117
      let production = ct.productionSum(slot.element);
118
119
      for (let key in production) {
120
        util.addResource(state.player, 'dark', key, production[key]);
121
      }
122
123
      for(let resource in ct.infuse){
124
        state.player.resources[resource].number = Math.max(0, state.player.resources[resource].number-ct.infuse[resource]);
125
      }
126
127
      upgrade.resetElement(state.player, slot.element);
128
129
      // we deactivate reactions and redoxes
130
      for (let reaction of slot.reactions) {
131
        reaction.active = false;
132
      }
133
134
      for (let redox of slot.redoxes) {
135
        redox.active = false;
136
      }
137
138
      // we cache them in case players want to pick up the same element
139
      // the cache only lasts the current session
140
      state.reactionsCache[slot.element] = slot.reactions;
141
      state.redoxesCache[slot.element] = slot.redoxes;
142
143
      state.player.element_slots[index] = null;
144
      state.player.statistics.exotic_run[slot.element] = {};
145
    };
146
147
    ct.buyExoticUpgrade = function(name, slot) {
148
      let price = data.exotic_upgrades[name].price;
149
      let currency = data.elements[slot.element].exotic;
150
      upgrade.buyUpgrade(state.player,
151
        state.player.exotic_upgrades[slot.element],
152
        data.exotic_upgrades[name],
153
        name,
154
        price,
155
        currency);
156
    };
157
158
    ct.setPercentage = function(resource, percentage) {
159
      ct.infuse[resource] = Math.floor(state.player.resources[resource].number*(percentage/100));
160
    };
161
162
    ct.fixNumber = function(resource) {
163
      ct.infuse[resource] = Math.max(0, Math.min(state.player.resources[resource].number, ct.infuse[resource]));
164
    };
165
166
    /* This function checks that values inserted in the text boxes are
167
    valid numbers */
168
    ct.isValidInfusion = function() {
169
      let valid = true;
170
      for(let resource in ct.infuse){
171
        valid = valid && Number.isFinite(ct.infuse[resource]);
172
      }
173
      return valid;
174
    };
175
176
    ct.infuseBoost = function(resource) {
177
        let number = Math.min(ct.infuse[resource], state.player.resources[resource].number);
178
        if(number === 0){
179
          return 1;
180
        }
181
        // log adds diminishing returns to the infusion
182
        return 1 + Math.log(number)/Math.log(1.25)*ct.data.constants.INFUSE_POWER;
183
    };
184
185
    /* The infusion boosts are multiplicative with respect to each other */
186
    ct.totalInfuseBoost = function() {
187
      let total = 1;
188
      for(let resource in ct.infuse){
189
        total *= ct.infuseBoost(resource);
190
      }
191
      return total;
192
    };
193
194
    ct.visibleExoticUpgrades = function(slot) {
195
      return visibility.visible(data.exotic_upgrades, isExoticUpgradeVisible, slot, sortFunc[state.player.options.sortIndex]);
196
    };
197
198
    function isExoticUpgradeVisible(name, slot) {
199
      return visibility.isUpgradeVisible(name, slot, data.exotic_upgrades[name]) &&
200
          (!state.player.options.hideBought || !state.player.exotic_upgrades[slot.element][name]);
201
    }
202
203
    ct.visibleSubatomic = function() {
204
      return visibility.visible(data.resources, isSubatomicVisible, '');
205
    };
206
207
    function isSubatomicVisible(name) {
208
      if (!state.player.resources[name].unlocked) {
209
        return false;
210
      }
211
212
      if(data.resources[name].type &&
213
         data.resources[name].type.indexOf('subatomic') !== -1){
214
          return true;
215
      }
216
217
      return false;
218
    }
219
220
    state.registerUpdate('exotic', ct.update);
221
	  refresh(state.player);
222
  }
223
]);
224