// ==UserScript==
// @version 1.1.2
// @name OGame 5: Formulas
// @autor Sergio Flores Genis (MrGenis)
// @oujs:autor mrgenis
// @date 2015-09-23
// @namespace OGame
// @description Formulas de OGame 5
// @include http://*.ogame.gameforge.*/game/*
// @exclude *
// @grant none
// ==/UserScript==
Math.trunc = Math.trunc || function (x) { return x < 0 ? Math.ceil(x) : Math.floor(x); };
function byId(id) { return document.getElementById(id); }
var win = (typeof unsafeWindow) == 'undefined' ? window : unsafeWindow;
function _fnOGame() {
var root = this;
/**
* Define propiedades en la raiz del objeto _fnOGame (root)
* @param key Nombre de la propiedad a definir
* @param value valor asignado a la propiedad
* @param e indica si es enumerable (def : true)
* @param w indica si se puede escribir (def : false)
* @param c indica si puede ser reconfigurable (def : false)
* @returns Propiedad creada
*/
function _define(key, value, e, w, c) {
var config = {};
config.enumerable = ('undefined' === typeof(e)) ? true : e;
config.writable = ('undefined' === typeof(w)) ? false : w;
config.configurable = ('undefined' === typeof(c)) ? false : c;
if ('undefined' !== typeof(value)
|| null != value) config.value = value;
return Object.defineProperty(root, key, config);
};
_define('server_time', win.startServerTime + win.timeDiff);
_define('server_version', root.meta('ogame-version'));
_define('currentPage', win.currentPage);
_define('currentPlanetType', root.meta('ogame-planet-type'));
_define('currentPlanetId', parseInt(root.meta('ogame-planet-id')) );
_define('isPage', function(p){
return (p === root.currentPage);
});
/* ======================================================================= */
/* ============================== Tienda ================================= */
/* ======================================================================= */
_define('items',{
metal10 : 'de922af379061263a56d7204d1c395cefcfb7d75',
metal20 : 'ba85cc2b8a5d986bbfba6954e2164ef71af95d4a',
metal30 : '05294270032e5dc968672425ab5611998c409166',
metalFP10 : 'b956c46faa8e4e5d8775701c69dbfbf53309b279',
crystal10 : '3c9f85221807b8d593fa5276cdf7af9913c4a35d',
crystal20 : '422db99aac4ec594d483d8ef7faadc5d40d6f7d3',
crystal30 : '118d34e685b5d1472267696d1010a393a59aed03',
crystalFP10: '090a969b05d1b5dc458a6b1080da7ba08b84ec7f',
deuterium10 : 'd9fa5f359e80ff4f4c97545d07c66dbadab1d1be',
deuterium20 : 'e4b78acddfa6fd0234bcb814b676271898b0dbb3',
deuterium30 : '5560a1580a0330e8aadf05cb5bfe6bc3200406e2',
deuteriumFP10: 'e254352ac599de4dd1f20f0719df0a070c623ca8'
}, true);
/* ####################################################################### */
/* ======================================================================= */
/* ============== Objeto para el almacenamiento de datos ================= */
/* ======================================================================= */
function _oStorage() {
var skey = root.meta('ogame-universe').split('.')[0];
Object.defineProperty(this, 'mask', {
value : '$OGame#' + skey + '.',
enumerable : true,
configurable : false,
writable : false
});
};
_oStorage.prototype.set = function (key, value) {
value = JSON.stringify(value);
return localStorage.setItem(this.mask + key, value);
};
_oStorage.prototype.get = function (key) {
var raw = localStorage.getItem(this.mask + key) || 0;
return JSON.parse(raw);
};
_oStorage.prototype.has = function (key) {
return (this.get(key) !== 0);
};
_oStorage.prototype.remove = function (key) {
localStorage.removeItem(key);
};
_define('Storage', new _oStorage());
/* ####################################################################### */
/* ======================================================================= */
/* ================== Cargando informacion del universo ================== */
/* ======================================================================= */
(function() {
/** root.server (enumerable) */
function _loadUniverse() {
var information = root.Storage.get('server'),
ajax = jQuery.Deferred();
if (!information) {
ajax = jQuery.ajax({
method : 'get', url : '/api/serverData.xml',
cache : true, dataType : 'xml', global : false,
success : function (data, status, xhr) {
var xml = jQuery(data.firstChild),
information = {};
xml.children().each(function (i, o) {
information[o.nodeName] = o.innerHTML;
});
information['serverId'] = data.firstChild.getAttribute('serverId');
information['timeread'] = data.firstChild.getAttribute('timestamp');
root.Storage.set('server', information);
}
});
} else {
ajax.resolve("$OGame.server");
ajax = ajax.promise();
}
_define('server', information);
return ajax;
};
function _loadLocalization() {
var information = root.Storage.get('server_localization'),
ajax = jQuery.Deferred();
if (!information) {
ajax = jQuery.ajax({
method : 'get', url : '/api/localization.xml',
cache : true, dataType : 'xml', global : false,
success : function (data, status, xhr) {
var xml = data.firstChild,
nodes = xml.childNodes,
information = {};
// tech
var tech = nodes.item(0),
items = tech.childElementCount;
for (var i = 0; i<items ; i++) {
var child = tech.children.item(i);
information[ child.id ] = child.innerHTML;
}
// missions
var mission = nodes.item(1);
items = mission.childElementCount;
for( i = 0; i<items; i++) {
var child = mission.children.item(i);
information[ 'm'+child.id ] = child.innerHTML;
}
root.Storage.set('server_localization', information);
}
});
} else {
ajax.resolve("$OGame.server_localization");
ajax = ajax.promise();
}
_define('_namesData', information, false);
return ajax;
};
var loader = jQuery.when(
_loadUniverse(),
_loadLocalization()
);
_define('defered', function () {
return loader;
}, true);
})();
/* ####################################################################### */
/* ======================================================================= */
/* ======================== Nombres de estructuras ======================= */
/* ======================================================================= */
(function (page) {
var _localization_ = win.LocalizationStrings;
_localization_.names = function (key) {
if ('undefined' === typeof(root._namesData[key]))
return 'LN' + key;
return root._namesData[key];
};
_define('Localization', _localization_);
})(root.currentPage);
/* ####################################################################### */
/* ======================================================================= */
/* ============================ Equipo comando =========================== */
/* ======================================================================= */
(function () {
root.officers = {
commander : (byId('officers').getElementsByClassName('commander')[0].className.indexOf('on') != -1),
admiral : (byId('officers').getElementsByClassName('admiral')[0].className.indexOf('on') != -1),
admiral_fleet : 0,
geologist : (byId('officers').getElementsByClassName('geologist')[0].className.indexOf('on') != -1),
geologist_mines : 0,
technocrat : (byId('officers').getElementsByClassName('technocrat')[0].className.indexOf('on') != -1),
technocrat_spy : 0,
technocrat_research : 1,
engineer : (byId('officers').getElementsByClassName('engineer')[0].className.indexOf('on') != -1),
enginner_energy : 1,
all : (byId('officers').className.indexOf('all') != -1)
};
_define('allOfficers', root.officers.all);
if (root.allOfficers) {
root.officers.admiral_fleet = 3;
root.officers.enginner_energy = 1.12;
root.officers.geologist_mines = 0.12;
root.officers.technocrat_spy = 3;
root.officers.technocrat_research = 1.25;
} else {
if (root.officers.admiral)
root.officers.admiral_fleet = 2;
if (root.officers.engineer)
root.officers.enginner_energy = 1.1;
if (root.officers.geologist)
root.officers.geologist_mines = 0.1;
if (root.officers.technocrat) {
root.officers.technocrat_spy = 2;
root.officers.technocrat_research = 1.25;
}
}
Object.defineProperty(root, 'officers', {
writable : false,
configurable : false
});
Object.freeze(root.officers);
})();
/* ####################################################################### */
/* ======================================================================= */
/* ========================== Naves y defenzas =========================== */
/* ======================================================================= */
(function (root) {
/**
* (constructor) Objeto para guardar al costo base de un elemento
* @param m : costo en metal
* @param c : costo en cristal
* @param d : costo en deuterio
*/
function _costo(m, c, d) {
Object.defineProperty(this, 'metal', {
value : m,
enumerable : true
});
Object.defineProperty(this, 'crystal', {
value : c,
enumerable : true
});
Object.defineProperty(this, 'deuterium', {
value : d,
enumerable : true
});
}
/**
* (constructor) Objeto que reprecenta una defensa
* @param m : costo en metal
* @param c : costo en cristal
* @param d : costo en deuterio
*/
function _defence(m, c, d) {
_costo.call(this, m, c, d);
};
_defence.prototype = Object.create(_costo.prototype);
_defence.prototype.constructor = _defence;
_defence.prototype.fnTimeProduction = function (n, shipyard, nanite) {
var time = 3600 * ((this.metal + this.crystal) / 5000 * 2 / (shipyard + 1.0) * Math.pow(0.5, nanite));
return (Math.floor(time) * n) / root.server.speed;
};
Object.defineProperty(root.Object, 'oDefence', {
enumerable : true,
value : function (m, c, d) {
return new _defence(m, c, d);
}
});
/**
* (constructor) Objeto que reprecenta una nave
* @param m : costo en metal
* @param c : costo en cristal
* @param d : costo en deuterio
* @param s : capacidad de carga
*/
function _ship(m, c, d, s) {
_defence.call(this, m, c, d);
Object.defineProperty(this, 'capacity', {
value : s,
enumerable : true
});
};
_defence.prototype = Object.create(_defence.prototype);
_defence.prototype.constructor = _ship;
Object.defineProperty(root.Object, 'oShip', {
enumerable : true,
value : function (m, c, d, s) {
return new _ship(m, c, d, s);
}
});
})(root);
this.defences = {
/* Lanzamisiles */
401 : root.Object.oDefence(2000, 0, 0),
/* Lázer pequeño */
402 : root.Object.oDefence(1500, 500, 0),
/* Lázer grande */
403 : root.Object.oDefence(6000, 2000, 0),
/* Cañon guass */
404 : root.Object.oDefence(20000, 15000, 2000),
/* Cañon iónico */
405 : root.Object.oDefence(2000, 6000, 0),
/* Caño de plasma */
406 : root.Object.oDefence(50000, 50000, 30000),
/* Cúpula pequeña */
407 : root.Object.oDefence(10000, 10000, 0),
/* Cúpula grande */
408 : root.Object.oDefence(50000, 50000, 0),
/* Intercepción */
502 : root.Object.oDefence(8000, 0, 2000),
/* Interplanetario */
503 : root.Object.oDefence(12500, 2500, 10000)
};
this.ships = {
/* Cazador ligero */
204 : root.Object.oShip(3000, 1000, 0, 50),
/* Cazador pesado */
205 : root.Object.oShip(6000, 4000, 0, 100),
/* Crucero */
206 : root.Object.oShip(20000, 7000, 2000, 800),
/* Nave de batalla */
207 : root.Object.oShip(45000, 15000, 0, 1500),
/* Acorazado */
215 : root.Object.oShip(30000, 40000, 15000, 750),
/* Bombardero */
211 : root.Object.oShip(50000, 25000, 15000, 500),
/* Destructor */
213 : root.Object.oShip(60000, 50000, 15000, 2000),
/* EDL Muerte */
214 : root.Object.oShip(5000000, 4000000, 1000000, 1000000),
/* NP de carga */
202 : root.Object.oShip(2000, 2000, 0, 5000),
/* NG de carga */
203 : root.Object.oShip(6000, 6000, 0, 25000),
/* Nave de colonia */
208 : root.Object.oShip(10000, 20000, 10000, 7500),
/* Reciclador */
209 : root.Object.oShip(10000, 6000, 2000, 20000),
/* Sonda espionaje */
210 : root.Object.oShip(0, 1000, 0, 5),
/* Satélite solar */
212 : root.Object.oShip(0, 2000, 500, 0)
};
/* ####################################################################### */
/* ======================================================================= */
/* ======================== Energia y produccion ========================= */
/* ======================================================================= */
function _energyMetalCrystal(level, power) {
return Math.ceil(power * 10 * level * Math.pow(1.1, level));
}
this.energy = {};
_define('energy', {
metal : _energyMetalCrystal,
crystal : _energyMetalCrystal,
deuterium : function (level, power) {
return Math.ceil(power * 20 * level * Math.pow(1.1, level));
},
solar : function (level, power) {
return Math.floor(power * engineer * (20 * level * Math.pow(1.1, level)));
},
fusion : function (level, power, techEnergy) {
return Math.floor(power * engineer * (30 * level * Math.pow(1.05 + techEnergy * 0.01, level)));
},
satellite : function (count, power, temp) {
var s = Math.floor(count * power * engineer * Math.floor((temp + 140) / 6));
return (s < 0) ? 0 : s;
},
factor : function (metal, metalPower,
crystal, crystalPower, deuterium, deuteriumPower,
solar, solarPower, fusion, fusionPower, satellite, satellitePower, temp, techEnergy) {
var koeff = 1,
used = f.energy.metal(metal, metalPower)
+ f.energy.crystal(crystal, crystalPower)
+ f.energy.deuterium(deuterium, deuteriumPower),
produced = f.energy.solar(solar, solarPower)
+ f.energy.fusion(fusion, fusionPower, techEnergy)
+ f.energy.satellite(satellite, satellitePower, temp);
if (used > 0) koeff = produced / (1.0 * used);
if (koeff > 1) koeff = 1;
return {
koeff : koeff,
produced : produced,
used : used,
diff : produced - used
};
}
}, true);
Object.freeze(root.energy);
function _amplifierById( id ) {
if (id == root.items.metal10
|| id == root.items.metalFP10
|| id == root.items.crystal10
|| id == root.items.crystalFP10
|| id == root.items.deuterium10
|| id == root.items.deuteriumFP10 ) {
return 0.1;
} else if( id == root.items.metal20
|| id == root.items.crystal20
|| id == root.items.deuterium20 ) {
return 0.2;
} else if ( id == root.items.metal30
|| id == root.items.crystal30
|| id == root.items.deuterium30 ) {
return 0.3;
}
};
function _production(base, mine, plasm, obj) {
var geol = mine + root.officers.geologist_mines,
mg = Math.ceil(mine + geol);
plasm = mine * plasm;
obj = mine * _amplifierById(obj);
return {
production : Math.round(base + mg + plasm + object),
resources : {income:base, mine:Math.round(mine), geologist:Math.round(geol),
plasma:Math.round(plasm), object:Math.round(obj)}
};
}
_define('production', {
metal : function(level, object, power, koeff, plasma) {
var base = (30 * speed),
mine = (speed * power * koeff * 30 * level * Math.pow(1.1, level)) ;
plasma = plasma / 100;
return _production(base, mine, plasma, object);
},
crystal : function(level, object, power, koeff, plasma) {
var base = (15 * speed),
mine = (speed * power * koeff * 20 * level * Math.pow(1.1, level)) ;
plasma = (plasma * 66) / 10000;
return _production(base, mine, plasma, object);
},
deuterium : function(level, object, power, koeff, temp) {
var mine = (speed * power * koeff
* 10 * level * Math.pow(1.1, level) * (1.44 - 0.004 * temp));
return _production(0, mine, 0, object);
},
fusion : function(level, power){
return (speed * power * 10 * level * Math.pow(1.1, level));
}
}, true);
/* ####################################################################### */
};
_fnOGame.prototype.Object = {};
_fnOGame.prototype.meta = function(key) {
return document.getElementsByName(key)[0].content;
};
_fnOGame.prototype.fnStorage = function (l) {
if (NaN === l || 'undefined' === typeof(l)) return NaN;
return 5000 * Math.trunc(2.5 * Math.pow(Math.E, (20 * l) / 33));
};
_fnOGame.prototype.fnTimeResearch = function (metal, crystal, lab) {
return ((metal + crystal) / 1000 * (1 + lab)) * this.server.speed;
}
_fnOGame.prototype.fnTitle = function (e) {
if ('string' == typeof(e))
e = jQuery(e)[0];
if ('undefined' == typeof(e))
return '';
var tx = (e.title == '') ? jQuery(e).data('tipped_restore_title') : e.title;
return tx;
};
_fnOGame.prototype.fnTimespanToShorten = function (seconds, minimize) {
if ('undefine' === typeof(minimize))
minimize = true;
var localization = this.Localization.timeunits;
if (seconds == 0)
return '0' + localization.short.second;
var timeStr = '',
haveWeek = false,
haveDay = false;
if (seconds >= 604800) {
// el tiempo es 1 SEMANA o mas
timeStr += Math.floor(seconds / 604800);
timeStr += localization.short.week + ' ';
seconds = seconds % 604800;
haveWeek = true;
}
if (seconds >= 86400 || timeStr.length > 0) {
// el tiempo es mayor o igual a 1 DIA
// ya se a definido texto antes.
if (seconds / 86400 >= 1) {
timeStr += Math.floor(seconds / 86400);
timeStr += localization.short.day + ' ';
}
seconds = seconds % 86400;
haveDay = true;
}
if (seconds >= 3600 || timeStr.length > 0) {
// el tiempo es mayor o igual a 1 HORA
// ya se a definido texto antes.
if (seconds / 3600 >= 1) {
timeStr += Math.floor(seconds / 3600);
timeStr += localization.short.hour + ' ';
}
seconds = seconds % 3600;
}
if (minimize && haveWeek)
return timeStr;
if (seconds >= 60 || timeStr.length > 0) {
// timepo es mayor o igual a 1 MINUTO
if (seconds / 60 >= 1) {
timeStr += Math.floor(seconds / 60);
timeStr += localization.short.minute + ' ';
}
seconds = seconds % 60;
}
if (minimize && haveDay)
return timeStr;
if (seconds > 0) {
// el tiempo tiene segundos
timeStr += Math.floor(seconds);
timeStr += localization.short.second;
}
return timeStr;
};
_fnOGame.prototype.fnNumberHumanReadable = function(num, cut) {
num = num || 0;
cut = cut || 3;
return win.gfNumberGetHumanReadable(num, cut);
};
var $OGame = new _fnOGame();
win.$OGame = $OGame;