src/scripts/component/exotic.js   A
last analyzed

Complexity

Total Complexity 33
Complexity/F 2.54

Size

Lines of Code 176
Function Count 13

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 0
wmc 33
c 2
b 0
f 0
nc 576
mnd 3
bc 30
fnc 13
dl 0
loc 176
rs 9.3999
bpm 2.3076
cpm 2.5384
noi 0

1 Function

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