Skip to content

Instantly share code, notes, and snippets.

@Rio6
Last active March 30, 2024 21:10
Show Gist options
  • Save Rio6/a92227a8af23de36893a335d5631791d to your computer and use it in GitHub Desktop.
Save Rio6/a92227a8af23de36893a335d5631791d to your computer and use it in GitHub Desktop.
Custom theme for Istrolid
var r26_theme = r26_theme || {};
// Function to hook
r26_theme.hooks = r26_theme.hooks || {
process: Interpolator.prototype.process,
drawSprite: Atlas.prototype.drawSprite
};
// Change this for different colors
r26_theme.theme = r26_theme.theme || {
// Istrolid theme colors
spotColor: [0, 0, 0, 255],
fillColor: [0, 0, 50, 255],
rockColor: [255, 255, 255, 255],
// Color of things
// Alpha is not used
arrowColor: [255, 255, 255, 255],
bulletColor: [255, 180, 180, 255],
partColor: [200, 200, 255, 255], // Particle not unit part
aoeColor: [255, 0, 0, 180], // Arty/phase AOE indicator color
// Team colors for Spawns and Points
alphaColor: [230, 230, 230, 255],
betaColor: [100, 100, 0, 255]
};
// Images need to be changed
r26_theme.bulletImages = [
"parts/fireBeamLarge.png",
"parts/fireHex1.png",
"parts/fireRing.png",
"parts/fireTorp1.png",
"parts/fireMis1.png",
"parts/fireLong1.png",
"parts/fireMine.png",
"parts/fireShot1.png",
"parts/fireBeamLarge.png",
"parts/fireFlack1.png",
"parts/hit1.png",
"parts/fireEnergyBall.png",
"parts/fizzleMine.png",
"parts/fizzleMinePart.png",
"parts/fizzleMineEnergy.png",
"parts/bombDormant.png",
"parts/fireAuto.png",
"parts/zap1.png",
"parts/fireWavePull.png",
"parts/fireWavePush.png",
"parts/fireFlame1.png"
];
r26_theme.partImages = [
"img/fire02.png",
"img/point02.png"
];
r26_theme.invImages = [
"parts/fireLong1.png",
"parts/fireTorp1.png",
"parts/fireMis1.png",
"parts/fireMine.png",
"img/arrow01.png",
"img/arrow02.png"
];
r26_theme.ignoreFns = [
"Unit",
"StasisField",
"EnergyTransfer",
];
r26_theme.callerListener = r26_theme.callerListener || {
parts: {
StasisField: parts.StasisField.prototype.draw,
EnergyTransfer: parts.EnergyTransfer.prototype.draw,
},
types: {
Unit: types.Unit.prototype.draw,
ArtilleryBullet: types.ArtilleryBullet.prototype.draw,
Bomb: types.Bomb.prototype.draw,
SpawnPoint: types.SpawnPoint.prototype.draw,
CommandPoint: types.CommandPoint.prototype.draw,
},
};
// Override functions
Interpolator.prototype.process = function(data) {
let ret = r26_theme.hooks.process.call(this, data);
if(r26_theme.theme.spotColor && r26_theme.theme.fillColor && r26_theme.theme.rockColor)
sim.theme = r26_theme.theme;
// Transparent design/fleet menu
mapping.themes[0] = {
spotColor: [0, 0, 0, 0],
fillColor: [0, 0, 0, 0],
rockColor: [0, 0, 0, 0]
};
return ret;
}
Atlas.prototype.drawSprite = function(src, pos, size, rot, color, z) {
if(!r26_theme.ignoreFns.includes(r26_theme.caller)) {
let newColor = null
if(r26_theme.caller === "SpawnPoint" || r26_theme.caller === "CommandPoint") {
if(simpleEquals(color, [20, 20, 20, 255]))
newColor = r26_theme.theme.betaColor;
else
newColor = r26_theme.theme.alphaColor;
}
else if(
(r26_theme.caller === "ArtilleryBullet" || r26_theme.caller === "Bomb") &&
(src === "img/point02.png" || src === "img/fire02.png")
) {
newColor = r26_theme.theme.aoeColor;
}
else if(src === "img/arrow01.png" || src === "img/arrow02.png")
newColor = r26_theme.theme.arrowColor;
else if(r26_theme.bulletImages.includes(src))
newColor = r26_theme.theme.bulletColor;
else if(r26_theme.partImages.includes(src))
newColor = r26_theme.theme.partColor;
if(newColor) {
let alpha = color && color[3];
color = newColor;
color[3] = alpha;
}
}
return r26_theme.hooks.drawSprite.call(this, src, pos, size, rot, color, z);
}
// Change black images to white so color can be added to it
r26_theme.invertImage = function(img, srcs) {
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d', { willReadFrequently: true });
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
for(let src of srcs) {
let x, y, w, h;
let mapping = atlas.mappings[src];
if(!mapping) {
console.error("not in mapping", src);
return;
}
let uv = mapping.uv;
x = img.width * uv[0];
y = img.height - img.height * uv[1];
w = img.width * uv[2] - x;
h = img.height - img.height * uv[3] - y;
let imageData = ctx.getImageData(x, y, w, h);
let data = imageData.data;
for(let i = 0; i < data.length; i += 4) {
// red
data[i] = 255;
// green
data[i + 1] = 255;
// blue
data[i + 2] = 255;
}
ctx.putImageData(imageData, x, y);
}
return canvas.toDataURL("image/png");
}
// Make some sprites white on the atlas
if(!r26_theme.image) {
r26_theme.image = new Image();
r26_theme.image.onload = function() {
atlas.src = r26_theme.invertImage(r26_theme.image, r26_theme.invImages);
if(baseAtlas)
baseAtlas.loadAtlas(atlas);
}
r26_theme.image.src = atlas.src;
}
// add caller listener to functions
for(let ns in r26_theme.callerListener) {
for(let name in r26_theme.callerListener[ns]) {
window[ns][name].prototype.draw = function() {
r26_theme.caller = name;
let ret = r26_theme.callerListener[ns][name].apply(this, arguments);
r26_theme.caller = null;
return ret;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment