// ==UserScript==
// @name C&C: Tiberium Alliances - xTr1m's Base Overlay- Diplay Ratio 16:10
// @description Provides an overlay over the base of the gain/cost relationship of building upgrades by holding the Control key
// @namespace http*://*.alliances.commandandconquer.com/*
// @include http*://*.alliances.commandandconquer.com/*
// @version 1.12
// @author xTr1m/DLwarez
// @grant none
// @source https://github.com/xTr1m/BaseOverlay
// ==/UserScript==
(function() {
var injectFunction = function()
{
function createClass()
{
qx.Class.define("xTr1m_Base_Overlay",
{
type: "singleton",
extend: qx.core.Object,
construct: function()
{
try
{
var app = qx.core.Init.getApplication();
this.__window = new xTr1m_Base_Overlay.Window();
var onKeyDown = function(e)
{
var xt = xTr1m_Base_Overlay.getInstance();
// TODO: Determine if the player is watching his base and doesn't have build/sell/move mode enabled
if (!!e.ctrlKey && !xt.__windowOpened)
{
xt.__openWindow();
}
};
var onKeyUp = function(e)
{
var xt = xTr1m_Base_Overlay.getInstance();
if (!e.ctrlKey && xt.__windowOpened)
{
xt.__closeWindow();
}
};
document.addEventListener('keydown', onKeyDown, true);
document.addEventListener('keyup', onKeyUp, true);
document.addEventListener('blur', onKeyUp, true);
}
catch (e)
{
console.log("Something is terribly wrong with xTr1m's Base Ovelray script. :(");
console.log(e.toString());
}
console.log("xTr1m's Base Overlay script: Initialising finshed");
},
destruct: function()
{
},
members:
{
__windowOpened: false,
__window: null,
__openWindow: function()
{
this.__windowOpened = true;
this.__window.open();
},
__closeWindow: function()
{
this.__windowOpened = false;
this.__window.close();
}
}
});
qx.Class.define("xTr1m_Base_Overlay.Window",
{
extend: qx.ui.container.Composite,
construct: function()
{
this.base(arguments);
var layout = new qx.ui.layout.Canvas();
this._setLayout(layout);
this.__background = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
this._add(this.__background, { left: 0, top: 0, right: 0, bottom: 0, allowGrowX: true, allowGrowY: true });
},
destruct: function()
{
},
members:
{
__background: null,
__buildings: [],
open: function()
{
var app = qx.core.Init.getApplication();
var mainOverlay = app.getMainOverlay();
this.setWidth(mainOverlay.getWidth());
this.setMaxWidth(mainOverlay.getMaxWidth());
this.setHeight(mainOverlay.getHeight());
this.setMaxHeight(mainOverlay.getMaxHeight());
this.__background.removeAll();
this.__background.setThemedBackgroundColor("#00000080");
var data = ClientLib.Data.MainData.GetInstance();
var cities = data.get_Cities();
var ownCity = cities.get_CurrentOwnCity();
var buildings = ownCity.get_Buildings();
var visMain = ClientLib.Vis.VisMain.GetInstance();
var visCity = visMain.get_City();
var zoomFactor = visCity.get_ZoomFactor();
var hudEntities = [];
var maxRes = 0;
var minRes = Number.MAX_VALUE;
var width = visCity.get_GridWidth() * zoomFactor;
var height = visCity.get_GridHeight() * zoomFactor;
this.collectData(ownCity);
for (var ri in this.__buildings)
{
var building = this.__buildings[ri];
var x = building.PosX * width;
var y = building.PosY * height;
x -= visCity.get_MinXPosition();
y -= visCity.get_MinYPosition();
maxRes = Math.max(maxRes, building.Ratio);
minRes = Math.min(minRes, building.Ratio);
hudEntities.push({ "Ratio": building.Ratio, "X": x, "Y" : y });
}
var deltaRes = maxRes - minRes;
for (var i in hudEntities)
{
var entity = hudEntities[i];
var relRes = (entity.Ratio - minRes) / deltaRes;
var relHex = Math.round(relRes * 15);
var red = (15 - relHex).toString(16);
var green = relHex.toString(16);
var box = new qx.ui.layout.HBox();
var overlay = new qx.ui.container.Composite(box).set({
decorator : new qx.ui.decoration.Single(1, "solid", "#000000").set({backgroundColor : "#" + red + green + "0"}),
opacity : 0.8,
width: width - 2,
height: height - 2
});
box.setAlignX("center");
box.setAlignY("middle");
var label = new qx.ui.basic.Label(entity.Ratio.toFixed(6)).set({
allowGrowX: false,
allowGrowY: false,
textColor: "blue",
font: new qx.bom.Font(16, ["fantasy"])
});
overlay._add(label);
this.__background._add(overlay,
{
left: entity.X + 1,
top: entity.Y + 16
});
}
app.getDesktop().add(this, { left: mainOverlay.getBounds().left, top: mainOverlay.getBounds().top });
},
close: function()
{
var app = qx.core.Init.getApplication();
app.getDesktop().remove(this);
},
collectData: function (city)
{
try
{
var resList = [];
resList.push(this.getResList(city, [ClientLib.Base.ETechName.Harvester, ClientLib.Base.ETechName.Silo], ClientLib.Base.EModifierType.TiberiumPackageSize, ClientLib.Base.EModifierType.TiberiumProduction));
resList.push(this.getResList(city, [ClientLib.Base.ETechName.Harvester, ClientLib.Base.ETechName.Silo], ClientLib.Base.EModifierType.CrystalPackageSize, ClientLib.Base.EModifierType.CrystalProduction));
resList.push(this.getResList(city, [ClientLib.Base.ETechName.PowerPlant, ClientLib.Base.ETechName.Accumulator], ClientLib.Base.EModifierType.PowerPackageSize, ClientLib.Base.EModifierType.PowerProduction));
resList.push(this.getResList(city, [ClientLib.Base.ETechName.Refinery, ClientLib.Base.ETechName.PowerPlant], ClientLib.Base.EModifierType.CreditsPackageSize, ClientLib.Base.EModifierType.CreditsProduction));
this.__buildings = [];
for (var i in resList)
{
var resEntry = resList[i];
for (var b in resEntry)
{
var building = resEntry[b];
var index = building.PosY * 10 + building.PosX;
if (!(index in this.__buildings))
{
this.__buildings[index] = building;
}
else
{
this.__buildings[index].Gain += building.Gain;
}
}
}
for (var j in this.__buildings)
{
this.__buildings[j].Ratio = this.__buildings[j].Gain / this.__buildings[j].Cost;
}
}
catch (e)
{
console.log("xTr1m_Base_Overlay.Window.collectData: ", e);
}
},
getResList: function (city, arTechtypes, eModPackageSize, eModProduction)
{
try
{
var i = 0;
var buildings = city.get_Buildings().d;
var resAll = [];
var objbuildings = [];
if (PerforceChangelist >= 376877)
{
for (var o in buildings) //new
{
objbuildings.push(buildings[o]);
}
}
else
{
for (i = 0; i < buildings.length; i++) //old
{
objbuildings.push(buildings[i]);
}
}
for (i = 0; i < objbuildings.length; i++)
{
var city_building = objbuildings[i];
var iTechType = city_building.get_TechName();
var bSkip = true;
for (var iTypeKey in arTechtypes)
{
if (arTechtypes[iTypeKey] == iTechType)
{
bSkip = false;
break;
}
}
if (bSkip)
{
continue;
}
var city_buildingdetailview = city.GetBuildingDetailViewInfo(city_building);
if (city_buildingdetailview === null)
{
continue;
}
var bindex = city_building.get_Id();
var resbuilding = [];
resbuilding.PosX = city_building.get_CoordX();
resbuilding.PosY = city_building.get_CoordY();
resbuilding.Gain = 0;
for (var ModifierType in city_buildingdetailview.OwnProdModifiers.d)
{
switch (parseInt(ModifierType, 10))
{
case eModPackageSize:
{
var ModOj = city_buildingdetailview.OwnProdModifiers.d[city_building.get_MainModifierTypeId()];
var CurrentDelay = (ModOj.TotalValue) / ClientLib.Data.MainData.GetInstance().get_Time().get_StepsPerHour();
var NextDelay = (ModOj.TotalValue + ModOj.NewLvlDelta) / ClientLib.Data.MainData.GetInstance().get_Time().get_StepsPerHour();
var mtProd = city_buildingdetailview.OwnProdModifiers.d[ModifierType];
var CurrentProd = mtProd.TotalValue / CurrentDelay;
var NextProd = (mtProd.TotalValue + mtProd.NewLvlDelta) / NextDelay;
resbuilding.Gain += NextProd - CurrentProd;
break;
}
case eModProduction:
{
resbuilding.Gain += city_buildingdetailview.OwnProdModifiers.d[ModifierType].NewLvlDelta;
break;
}
}
}
var TechLevelData = ClientLib.Base.Util.GetTechLevelResourceRequirements_Obj(city_building.get_CurrentLevel() + 1, city_building.get_TechGameData_Obj());
var Cost = 0;
for (var costtype in TechLevelData)
{
if (typeof(TechLevelData[costtype]) == "function" || TechLevelData[costtype].Type == "0")
{
continue;
}
if (parseInt(TechLevelData[costtype].Count) <= 0)
{
continue;
}
Cost += TechLevelData[costtype].Count;
}
resbuilding.Cost = Cost;
resAll.push(resbuilding);
}
return resAll;
}
catch (e)
{
console.log("xTr1m_Base_Overlay.Window.getResList: ", e);
}
},
}
});
}
function waitForGame()
{
try
{
if (typeof qx != 'undefined' && typeof qx.core != 'undefined' && typeof qx.core.Init != 'undefined' && qx.core.Init.getApplication() !== null)
{
var app = qx.core.Init.getApplication();
if (app.initDone === true)
{
try
{
createClass();
xTr1m_Base_Overlay.getInstance();
}
catch(e)
{
console.log("xTr1m's Base Overlay script init error:");
console.log(e);
}
}
else
window.setTimeout(waitForGame, 1000);
}
else
{
window.setTimeout(waitForGame, 1000);
}
}
catch (e)
{
if (typeof console != 'undefined') console.log(e);
else if (window.opera) opera.postError(e);
else GM_log(e);
}
}
window.setTimeout(waitForGame, 1000);
};
var script = document.createElement("script");
var txt = injectFunction.toString();
script.innerHTML = "(" + txt + ")();";
script.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(script);
})();