Completed
Push — master ( 91cb97...87a0d5 )
by Andres
32s
created

src/scripts/component/exotic.js   A

Complexity

Total Complexity 31
Complexity/F 2.21

Size

Lines of Code 175
Function Count 14

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 0
wmc 31
c 3
b 0
f 0
nc 32
mnd 2
bc 29
fnc 14
dl 0
loc 175
rs 9.8
bpm 2.0714
cpm 2.2142
noi 0

1 Function

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