Completed
Push — master ( 3d9b6d...945660 )
by Andres
32s
created

angular.controller(ꞌct_redoxꞌ)   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
nc 2
dl 0
loc 5
rs 9.4285
nop 1
1
/**
2
 redox
3
 Component that handles reduction/oxidation and ions.
4
5
 @namespace Components
6
 */
7
'use strict';
8
9
angular.module('game').component('redox', {
10
  templateUrl: 'views/redox.html',
11
  controller: 'ct_redox',
12
  controllerAs: 'ct'
13
});
14
15
angular.module('game').controller('ct_redox', ['state', 'data', 'visibility', 'util', 'format', 'reaction', 'upgrade',
16
  function (state, data, visibility, util, format, reaction, upgradeService) {
17
    let ct = this;
18
    ct.state = state;
19
    ct.data = data;
20
    ct.util = util;
21
    ct.format = format;
22
    ct.reaction = reaction;
23
    ct.upgradeService = upgradeService;
24
    ct.adjustAmount = [1, 10, 25, 100];
25
26
    ct.update = function(player) {
27
      processRedox(player);
28
      processElectronegativity(player);
29
    };
30
31
    function processRedox(player){
32
      for(let slot of player.element_slots){
33
        if(!slot){
34
          continue;
35
        }
36
        for (let redox of slot.redoxes) {
37
          if (!redox.resource || !redox.active || redox.from === redox.to) {
38
            continue;
39
          }
40
41
          let reactant = ct.generateName(redox.element, redox.from);
42
          let power = util.calculateValue(data.global_upgrades.redox_bandwidth.power.base,
43
                data.global_upgrades.redox_bandwidth.power,
44
                player.global_upgrades_current.redox_bandwidth);
45
          let number = Math.min(power, player.resources[reactant].number);
46
          let react = ct.redoxReaction(redox);
47
48
          ct.reaction.react(number, react, player);
49
        }
50
      }
51
    }
52
53
    function processElectronegativity(player){
54
      for(let key in data.elements){
55
        let element = data.elements[key];
56
        if(element.electronegativity === 0){
57
          continue;
58
        }
59
        let ions = element.anions.concat(element.cations);
60
		    ions.push(element.main);
61
        for(let resource of ions){
62
          if(player.resources[resource].number === 0){
63
            continue;
64
          }
65
          let charge = data.resources[resource].charge || 0;
66
          let probabilities = probabilityDistribution(key, charge);
67
          for(let probKey in probabilities){
68
            if(charge === parseInt(probKey, 10)) continue;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
69
            let production = Math.floor(probabilities[probKey]*player.resources[resource].number);
70
            if(production === 0){
71
              continue;
72
            }
73
            let react = ct.redoxReaction({
74
              element: key,
75
              from: charge,
76
              to: parseInt(probKey, 10)
77
            });
78
            // electronegativity is 'for free'
79
      			react.reactant.eV = 0;
80
            // FIXME: starvation should fix this
81
            if(react.reactant['e-']){
82
              production = Math.min(production, player.resources['e-'].number);
83
            }
84
            ct.reaction.react(production, react, player);
85
          }
86
        }
87
      }
88
    }
89
90
    function probabilityDistribution(element, charge){
91
    	let prob = {};
92
    	let start = -data.elements[element].electron_affinity.length;
93
    	let end = charge;
94
    	// lower than index, affected by negativity
95
    	rangeProbability(element, prob, start, end, 1, data.elements[element].negative_factor);
96
97
    	prob[charge] = 1;
98
99
    	start = charge+1;
100
    	end = data.elements[element].ionization_energy.length+1;
101
    	// lower than index, affected by positivity
102
    	rangeProbability(element, prob, start, end, -1, data.elements[element].positive_factor);
103
104
    	let sum = 0;
105
    	for(let i in prob){
106
    		sum += prob[i];
107
    	}
108
    	for(let i in prob){
109
    		prob[i] /= sum;
110
    	}
111
    	return prob;
112
    }
113
114
    function rangeProbability(element, prob, start, end, offset, factor){
115
    	for(let i = start; i < end; i++){
116
    		let difference = data.redox[element][i]-data.redox[element][i+offset];
117
    		if(difference <= 0){
118
    			difference = -difference;
119
    		}else{
120
    			difference = 1/difference;
121
    		}
122
    		prob[i] = Math.pow(data.constants.ELECTRONEGATIVITY_CHANCE,Math.abs(i))*factor*difference;
123
    	}
124
    }
125
126
    /* Writes a redox in the form of a reaction so that we can use the reaction
127
    service to process it */
128
    ct.redoxReaction = function (redox) {
129
      let reactant = ct.generateName(redox.element, redox.from);
130
      let product = ct.generateName(redox.element, redox.to);
131
      let energy = redoxEnergy(redox.from, redox.to, redox.element);
132
133
      let react = {
134
        'reactant': {},
135
        'product': {}
136
      };
137
138
      react.reactant[reactant] = 1;
139
      react.product[product] = 1;
140
      if (energy > 0) {
141
        react.reactant.eV = energy;
142
      } else if (energy < 0) {
143
        react.product.eV = -energy;
144
      }
145
146
      let electron = redox.from - redox.to;
147
      if (electron > 0) {
148
        react.reactant['e-'] = electron;
149
      } else if (electron < 0) {
150
        react.product['e-'] = -electron;
151
      }
152
153
      return react;
154
    };
155
156
    /* Calculates how much energy it takes to go from a redox level to another
157
    for a given element */
158
    function redoxEnergy(from, to, element) {
159
      let energyFrom = data.redox[element][from];
160
      let energyTo = data.redox[element][to];
161
      let energy = energyTo - energyFrom;
162
163
      return energy;
164
    }
165
166
    /* Generates the name of a ion, e.g. O3+ */
167
    ct.generateName = function (element, i) {
168
      if (i === 0) {
169
        return data.elements[element].main;
170
      }
171
      let postfix = '';
172
      if (Math.abs(i) > 1) {
173
        postfix = Math.abs(i);
174
      }
175
      postfix += getSign(i);
176
      let name = element + postfix;
177
      return name;
178
    };
179
180
    function getSign(number) {
181
      return number > 0 ? '+' : '-';
182
    }
183
184
    ct.redoxSize = function (player) {
185
      let size = 0;
186
      for(let slot of player.element_slots){
187
        if(!slot){
188
          continue;
189
        }
190
        size += slot.redoxes.length;
191
      }
192
      return size;
193
    };
194
195
    /* Adds a new redox to the player list */
196
    ct.addRedox = function (player, slot) {
197
      if(ct.redoxSize(player) >= util.calculateValue(data.global_upgrades.redox_slots.power.base,
198
            data.global_upgrades.redox_slots.power,
199
            player.global_upgrades.redox_slots)){
200
        return;
201
      }
202
      slot.redoxes.push({
203
        resource: data.elements[slot.element].main,
204
        active: false,
205
        element: slot.element,
206
        from: 0,
207
        to: 1
208
      });
209
    };
210
211
    ct.removeRedox = function (slot, index) {
212
      slot.redoxes.splice(index, 1);
213
    };
214
215
    ct.checkAll = function(slot){
216
      for(let redox of slot.redoxes){
217
        redox.active = slot.active;
218
      }
219
    }
220
221
    ct.visibleRedox = function(slot) {
222
      return slot.redoxes;
223
    };
224
225
    ct.adjustLevel = function(player, upgrade, amount){
226
      player.global_upgrades_current[upgrade] += amount;
227
      // We cap it between 1 and the current max level
228
      player.global_upgrades_current[upgrade] = Math.max(1, Math.min(player.global_upgrades_current[upgrade], player.global_upgrades[upgrade]));
229
    };
230
231
    ct.visibleUpgrades = function() {
232
      return visibility.visible(data.global_upgrades, upgradeService.filterByTag('redoxes'));
233
    };
234
235
    state.registerUpdate('redox', ct.update);
236
  }
237
]);
238