mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 07:50:45 +00:00
Dim untargetable nukes so players can tell SAMs can't hit them
Nukes flying outside SAM-targetable range now render at reduced alpha (unit.untargetableAlpha, default 0.6), including the hydrogen bomb's glow halo. Adds a FLAG_FLICKER_UNTARGETABLE instance flag in UnitPass driven by the existing UnitState.targetable field. Also fixes the alt-view trade-friendly check to match its flag exactly, so retreating warships (flag 4) no longer render ally-yellow in alt view.
This commit is contained in:
@@ -223,6 +223,7 @@ export interface RenderSettings {
|
||||
hBombGlowB: number;
|
||||
hBombGlowStrength: number; // peak opacity of the glow
|
||||
hBombGlowInner: number; // radial falloff start (0..1, quad-space)
|
||||
untargetableAlpha: number; // alpha for nukes SAMs can't target (0..1)
|
||||
};
|
||||
name: {
|
||||
lerpSpeed: number;
|
||||
|
||||
@@ -93,7 +93,7 @@ const HYDROGEN_BOMB_COL = UNIT_ORDER.indexOf(UT_HYDROGEN_BOMB);
|
||||
* Per-instance data (16 bytes):
|
||||
* float x, y, ownerID — 12 bytes (3 floats)
|
||||
* uint8 atlasIdx — 1 byte (atlas column 0–11)
|
||||
* uint8 flags — 1 byte (0 = normal, 1 = flicker, 2 = angry, 3 = trade-friendly, 4 = retreating)
|
||||
* uint8 flags — 1 byte (0 = normal, 1 = flicker, 2 = angry, 3 = trade-friendly, 4 = retreating, 5 = flicker-untargetable)
|
||||
* 2 bytes padding — aligns to 4-byte boundary
|
||||
*/
|
||||
const FLOATS_PER_INSTANCE = 4;
|
||||
@@ -105,6 +105,7 @@ const FLAG_FLICKER = 1;
|
||||
const FLAG_ANGRY = 2;
|
||||
const FLAG_TRADE_FRIENDLY = 3;
|
||||
const FLAG_RETREATING = 4;
|
||||
const FLAG_FLICKER_UNTARGETABLE = 5;
|
||||
|
||||
/** Atlas column indices for train sub-types (resolved from trainType + loaded) */
|
||||
const TRAIN_ENGINE_COL = UNIT_ORDER.indexOf("TrainEngine");
|
||||
@@ -183,6 +184,7 @@ export class UnitPass {
|
||||
private uHBombGlowColor: WebGLUniformLocation;
|
||||
private uHBombGlowStrength: WebGLUniformLocation;
|
||||
private uHBombGlowInner: WebGLUniformLocation;
|
||||
private uUntargetableAlpha: WebGLUniformLocation;
|
||||
|
||||
private affiliationTex: WebGLTexture | null = null;
|
||||
private altView = false;
|
||||
@@ -263,6 +265,10 @@ export class UnitPass {
|
||||
this.program,
|
||||
"uHBombGlowInner",
|
||||
)!;
|
||||
this.uUntargetableAlpha = gl.getUniformLocation(
|
||||
this.program,
|
||||
"uUntargetableAlpha",
|
||||
)!;
|
||||
|
||||
// Texture unit bindings
|
||||
gl.useProgram(this.program);
|
||||
@@ -427,7 +433,8 @@ export class UnitPass {
|
||||
} else if (isAngryWarship) {
|
||||
flags = FLAG_ANGRY;
|
||||
} else if (isFlicker) {
|
||||
flags = FLAG_FLICKER;
|
||||
// Untargetable nukes render dimmed so players can tell SAMs can't hit them
|
||||
flags = unit.targetable ? FLAG_FLICKER : FLAG_FLICKER_UNTARGETABLE;
|
||||
}
|
||||
const isMissile = MISSILE_TYPES.has(unit.unitType);
|
||||
|
||||
@@ -508,6 +515,7 @@ export class UnitPass {
|
||||
);
|
||||
gl.uniform1f(this.uHBombGlowStrength, us.hBombGlowStrength);
|
||||
gl.uniform1f(this.uHBombGlowInner, us.hBombGlowInner);
|
||||
gl.uniform1f(this.uUntargetableAlpha, us.untargetableAlpha);
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.paletteTex);
|
||||
|
||||
@@ -189,7 +189,8 @@
|
||||
"hBombGlowG": 0.72,
|
||||
"hBombGlowB": 0.15,
|
||||
"hBombGlowStrength": 0.5,
|
||||
"hBombGlowInner": 0.45
|
||||
"hBombGlowInner": 0.45,
|
||||
"untargetableAlpha": 0.6
|
||||
},
|
||||
"name": {
|
||||
"lerpSpeed": 10,
|
||||
|
||||
@@ -11,6 +11,7 @@ uniform int uAltView;
|
||||
uniform vec3 uHBombGlowColor;
|
||||
uniform float uHBombGlowStrength;
|
||||
uniform float uHBombGlowInner;
|
||||
uniform float uUntargetableAlpha;
|
||||
|
||||
in vec2 vQuadPos;
|
||||
in vec2 vCellUV;
|
||||
@@ -27,6 +28,7 @@ const float FLAG_FLICKER = 1.0;
|
||||
const float FLAG_ANGRY = 2.0;
|
||||
const float FLAG_TRADE_FRIENDLY = 3.0;
|
||||
const float FLAG_RETREATING = 4.0;
|
||||
const float FLAG_FLICKER_UNTARGETABLE = 5.0; // nuke out of SAM range — dimmed
|
||||
|
||||
// Ally color for trade-friendly override (yellow — matches affiliation.ts ALLY)
|
||||
const vec3 ALLY_COLOR = vec3(1.0, 1.0, 0.0);
|
||||
@@ -40,6 +42,11 @@ const vec3 FLICKER_COLORS[4] = vec3[4](
|
||||
);
|
||||
|
||||
void main() {
|
||||
// Untargetable nukes render translucent so players know SAMs can't hit them
|
||||
float alphaMul = abs(vFlags - FLAG_FLICKER_UNTARGETABLE) < 0.1
|
||||
? uUntargetableAlpha
|
||||
: 1.0;
|
||||
|
||||
// The sprite lives in the central cell-space region [0,1]; for the enlarged
|
||||
// hydrogen-bomb quad, anything outside that range is glow-only margin.
|
||||
vec4 texel = vec4(0.0);
|
||||
@@ -57,7 +64,7 @@ void main() {
|
||||
float d = length(vQuadPos - 0.5) * 2.0; // 0 at center → ~1 at quad edge
|
||||
float g = (1.0 - smoothstep(uHBombGlowInner, 1.0, d)) * uHBombGlowStrength;
|
||||
if (g > 0.001) {
|
||||
fragColor = vec4(uHBombGlowColor, g);
|
||||
fragColor = vec4(uHBombGlowColor, g * alphaMul);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -69,10 +76,10 @@ void main() {
|
||||
// Alt-view: solid affiliation color, no gray-replacement bands
|
||||
if (uAltView != 0) {
|
||||
// Enemy trade ships heading to a self/allied port render as yellow (ally)
|
||||
vec3 ac = vFlags > 2.5
|
||||
vec3 ac = abs(vFlags - FLAG_TRADE_FRIENDLY) < 0.1
|
||||
? ALLY_COLOR
|
||||
: texelFetch(uAffiliation, ivec2(int(vOwnerID), 1), 0).rgb;
|
||||
fragColor = vec4(ac, texel.a);
|
||||
fragColor = vec4(ac, texel.a * alphaMul);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -93,7 +100,8 @@ void main() {
|
||||
} else if (abs(vFlags - FLAG_RETREATING) < 0.1) {
|
||||
// Retreating: slowly blink the center (100 band) black so the ship reads as fleeing
|
||||
retreatBlink = step(0.5, fract(uTick * 0.07));
|
||||
} else if (abs(vFlags - FLAG_FLICKER) < 0.1) {
|
||||
} else if (abs(vFlags - FLAG_FLICKER) < 0.1 ||
|
||||
abs(vFlags - FLAG_FLICKER_UNTARGETABLE) < 0.1) {
|
||||
// Flicker: cycle through hot colors, offset by position hash
|
||||
float phase = fract(uTick * uFlickerSpeed + vHash);
|
||||
int idx = int(phase * 4.0) % 4;
|
||||
@@ -124,5 +132,5 @@ void main() {
|
||||
color = borderColor;
|
||||
}
|
||||
|
||||
fragColor = vec4(color, texel.a);
|
||||
fragColor = vec4(color, texel.a * alphaMul);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user