Completed
Push — master ( 01c562...b22fbb )
by Andres
29s
created

angular.controller(ꞌct_exoticꞌ)   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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