Completed
Push — master ( 290a67...91f4e5 )
by Andres
27s
created

src/scripts/component/exotic.js   A

Complexity

Total Complexity 32
Complexity/F 2.46

Size

Lines of Code 173
Function Count 13

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 0
wmc 32
c 4
b 0
f 0
nc 576
mnd 3
bc 29
fnc 13
dl 0
loc 173
rs 9.6
bpm 2.2307
cpm 2.4615
noi 0

1 Function

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