Completed
Push — master ( 6e8dba...bda2ec )
by Andres
30s
created

exotic.js ➔ ... ➔ ct.exoticPrestige   B

Complexity

Conditions 6
Paths 32

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
c 1
b 0
f 0
nc 32
dl 0
loc 36
rs 8.439
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: ['state', 'format', 'visibility', 'upgrade', 'data', 'util', exotic],
16
  controllerAs: 'ct'
17
});
18
19
function exotic(state, format, visibility, upgrade, data, util) {
20
  let ct = this;
21
  ct.state = state;
22
  ct.data = data;
23
  ct.util = util;
24
  ct.format = format;
25
  ct.infuse = {};
26
27
  /* Exotic production is a function of the different resources of each
28
  element. Additionally, multi-element molecules count double, once for
29
  each participating element. */
30
  ct.exoticProduction = function(element) {
31
    let production = {};
32
    let exoticResource = data.elements[element].exotic;
33
    production[exoticResource] = 0;
34
    for (let resource of data.elements[element].includes) {
35
      if (!state.player.resources[resource].unlocked) {
36
        continue;
37
      }
38
      if (data.resources[resource].type.indexOf('molecule') !== -1) {
39
        let multiplier = 0;
40
        for (let key in data.resources[resource].elements) {
41
          let number = data.resources[resource].elements[key];
42
          multiplier += number;
43
        }
44
        for (let elem in data.resources[resource].elements) {
45
          let newExotic = data.elements[elem].exotic;
46
          production[newExotic] = production[newExotic] || 0;
47
          production[newExotic] += prestigeFormula(state.player.resources[resource].number)*multiplier;
48
        }
49
      }else{
50
        production[exoticResource] += prestigeFormula(state.player.resources[resource].number);
51
      }
52
    }
53
    for (let key in production) {
54
      // we adjust the infusion
55
      production[key] = Math.floor(production[key]*ct.totalInfuseBoost());
56
    }
57
58
    return production;
59
  };
60
61
  function prestigeFormula(resource){
62
    let stepFactor = Math.max(Math.pow(10, Math.floor(Math.log10(resource))), 1);
63
    let step = stepFactor/data.constants.EXOTIC_STEP_QUOTIENT;
64
    let sigmoidQuotient = 1+Math.pow(Math.E, -(resource/stepFactor-data.constants.EXOTIC_SIGMOID_MAGIC));
65
    let sigmoid = 1/sigmoidQuotient+0.1;
66
    return Math.floor(step * sigmoid);
67
  }
68
69
  ct.exoticPrestige = function(slot) {
70
    let resources = state.player.resources;
71
    let production = ct.exoticProduction(slot.element);
72
73
    for (let key in production) {
74
      resources[key].number += production[key];
75
      resources[key].unlocked = true;
76
    }
77
78
    for(let resource in ct.infuse){
79
      state.player.resources[resource].number -= ct.infuse[resource];
80
    }
81
82
    upgrade.resetElement(state.player, slot.element);
83
84
    // we deactivate reactions and redoxes
85
    for (let reaction of slot.reactions) {
86
      reaction.active = false;
87
    }
88
89
    for (let redox of slot.redoxes) {
90
      redox.active = false;
91
    }
92
93
    // we cache them in case players want to pick up the same element
94
    // the cache only lasts the current session
95
    state.reactionsCache[slot.element] = slot.reactions;
96
    state.redoxesCache[slot.element] = slot.redoxes;
97
98
    // FIXME: copy the hydrogen for the time being. actually should be set to null
99
    for(let key in data.element_slot){
100
      slot[key] = angular.copy(data.element_slot[key]);
101
    }
102
    slot.generators['1'] = 1;
103
    slot.element = 'H';
104
  };
105
106
  ct.buyExoticUpgrade = function(name, slot) {
107
    let price = data.exotic_upgrades[name].price;
108
    let currency = data.elements[slot.element].exotic;
109
    upgrade.buyUpgrade(state.player,
110
      state.player.exotic_upgrades[slot.element],
111
      name,
112
      price,
113
      currency);
114
  };
115
116
  ct.setPercentage = function(resource, percentage) {
117
    ct.infuse[resource] = Math.floor(state.player.resources[resource].number*(percentage/100));
118
  };
119
120
  ct.fixNumber = function(resource) {
121
    ct.infuse[resource] = Math.max(0, Math.min(state.player.resources[resource].number, ct.infuse[resource]));
122
  };
123
124
  /* This function checks that values inserted in the text boxes are
125
  valid numbers */
126
  ct.isValidInfusion = function() {
127
    let valid = true;
128
    for(let resource in ct.infuse){
129
      valid = valid && Number.isFinite(ct.infuse[resource]);
130
    }
131
    return valid;
132
  };
133
134
  ct.infuseBoost = function(resource) {
135
      let number = Math.min(ct.infuse[resource], state.player.resources[resource].number);
136
      if(number === 0){
137
        return 1;
138
      }
139
      // log adds diminishing returns to the infusion
140
      return 1 + Math.log(number)/Math.log(1.25)*ct.data.constants.INFUSE_POWER;
141
  };
142
143
  /* The infusion boosts are multiplicative with respect to each other */
144
  ct.totalInfuseBoost = function() {
145
    let total = 1;
146
    for(let resource in ct.infuse){
147
      total *= ct.infuseBoost(resource);
148
    }
149
    return total;
150
  };
151
152
  ct.visibleExoticUpgrades = function(slot) {
153
    return visibility.visible(data.exotic_upgrades, isExoticUpgradeVisible, slot);
154
  };
155
156
  function isExoticUpgradeVisible(name, slot) {
157
    return visibility.isUpgradeVisible(name, slot, data.exotic_upgrades[name]);
158
  }
159
160
  ct.visibleSubatomic = function() {
161
    return visibility.visible(data.resources, isSubatomicVisible, '');
162
  };
163
164
  function isSubatomicVisible(name) {
165
    if (!state.player.resources[name].unlocked) {
166
      return false;
167
    }
168
169
    if(data.resources[name].type &&
170
       data.resources[name].type.indexOf('subatomic') !== -1){
171
        return true;
172
    }
173
174
    return false;
175
  }
176
}
177