Completed
Push — master ( c1627a...f635b6 )
by Andres
34s
created

angular.controller(ꞌct_exoticꞌ)   A

Complexity

Conditions 3
Paths 6

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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