mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-01 03:43:34 +00:00
sam is red when reloading (#268)
This commit is contained in:
BIN
Binary file not shown.
|
After Width: | Height: | Size: 184 B |
@@ -6,6 +6,7 @@ import { EventBus } from "../../../core/EventBus";
|
||||
import anchorIcon from "../../../../resources/images/buildings/port1.png";
|
||||
import missileSiloIcon from "../../../../resources/images/buildings/silo1.png";
|
||||
import SAMMissileIcon from "../../../../resources/images/buildings/silo4.png";
|
||||
import SAMMissileReloadingIcon from "../../../../resources/images/buildings/silo4-reloading.png";
|
||||
import shieldIcon from "../../../../resources/images/buildings/fortAlt2.png";
|
||||
import cityIcon from "../../../../resources/images/buildings/cityAlt1.png";
|
||||
import { GameView, UnitView } from "../../../core/game/GameView";
|
||||
@@ -14,6 +15,7 @@ import { GameUpdateType } from "../../../core/game/GameUpdates";
|
||||
import { euclDistFN } from "../../../core/game/GameMap";
|
||||
|
||||
const underConstructionColor = colord({ r: 150, g: 150, b: 150 });
|
||||
const reloadingColor = colord({ r: 255, g: 0, b: 0 });
|
||||
|
||||
interface UnitRenderConfig {
|
||||
icon: string;
|
||||
@@ -41,17 +43,17 @@ export class StructureLayer implements Layer {
|
||||
},
|
||||
[UnitType.MissileSilo]: {
|
||||
icon: missileSiloIcon,
|
||||
borderRadius: 8,
|
||||
borderRadius: 9.5,
|
||||
territoryRadius: 6,
|
||||
},
|
||||
[UnitType.DefensePost]: {
|
||||
icon: shieldIcon,
|
||||
borderRadius: 8,
|
||||
borderRadius: 9.5,
|
||||
territoryRadius: 6,
|
||||
},
|
||||
[UnitType.SAMLauncher]: {
|
||||
icon: SAMMissileIcon,
|
||||
borderRadius: 8,
|
||||
borderRadius: 10,
|
||||
territoryRadius: 6,
|
||||
},
|
||||
};
|
||||
@@ -62,32 +64,41 @@ export class StructureLayer implements Layer {
|
||||
) {
|
||||
this.theme = game.config().theme();
|
||||
this.loadIconData();
|
||||
this.loadIcon("reloadingSam", {
|
||||
icon: SAMMissileReloadingIcon,
|
||||
borderRadius: 8.525,
|
||||
territoryRadius: 6.525,
|
||||
});
|
||||
}
|
||||
|
||||
private loadIcon(unitType: string, config: UnitRenderConfig) {
|
||||
const image = new Image();
|
||||
image.src = config.icon;
|
||||
image.onload = () => {
|
||||
// Create temporary canvas for icon processing
|
||||
const tempCanvas = document.createElement("canvas");
|
||||
const tempContext = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = image.width;
|
||||
tempCanvas.height = image.height;
|
||||
|
||||
// Draw the unit icon
|
||||
tempContext.drawImage(image, 0, 0);
|
||||
const iconData = tempContext.getImageData(
|
||||
0,
|
||||
0,
|
||||
tempCanvas.width,
|
||||
tempCanvas.height,
|
||||
);
|
||||
this.unitIcons.set(unitType, iconData);
|
||||
console.log(
|
||||
`icond data width height: ${iconData.width}, ${iconData.height}`,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private loadIconData() {
|
||||
Object.entries(this.unitConfigs).forEach(([unitType, config]) => {
|
||||
const image = new Image();
|
||||
image.src = config.icon;
|
||||
image.onload = () => {
|
||||
// Create temporary canvas for icon processing
|
||||
const tempCanvas = document.createElement("canvas");
|
||||
const tempContext = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = image.width;
|
||||
tempCanvas.height = image.height;
|
||||
|
||||
// Draw the unit icon
|
||||
tempContext.drawImage(image, 0, 0);
|
||||
const iconData = tempContext.getImageData(
|
||||
0,
|
||||
0,
|
||||
tempCanvas.width,
|
||||
tempCanvas.height,
|
||||
);
|
||||
this.unitIcons.set(unitType, iconData);
|
||||
console.log(
|
||||
`icond data width height: ${iconData.width}, ${iconData.height}`,
|
||||
);
|
||||
};
|
||||
this.loadIcon(unitType, config);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -132,10 +143,17 @@ export class StructureLayer implements Layer {
|
||||
|
||||
private handleUnitRendering(unit: UnitView) {
|
||||
const unitType = unit.constructionType() ?? unit.type();
|
||||
let iconType = unitType;
|
||||
if (!this.isUnitTypeSupported(unitType)) return;
|
||||
|
||||
const config = this.unitConfigs[unitType];
|
||||
const icon = this.unitIcons.get(unitType);
|
||||
let icon: ImageData;
|
||||
|
||||
if (unitType == UnitType.SAMLauncher && unit.isSamCooldown()) {
|
||||
icon = this.unitIcons.get("reloadingSam");
|
||||
} else {
|
||||
icon = this.unitIcons.get(iconType);
|
||||
}
|
||||
|
||||
if (!config || !icon) return;
|
||||
|
||||
@@ -151,6 +169,13 @@ export class StructureLayer implements Layer {
|
||||
return;
|
||||
}
|
||||
|
||||
let borderColor = this.theme.borderColor(unit.owner().info());
|
||||
if (unitType == UnitType.SAMLauncher && unit.isSamCooldown()) {
|
||||
borderColor = reloadingColor;
|
||||
} else if (unit.type() == UnitType.Construction) {
|
||||
borderColor = underConstructionColor;
|
||||
}
|
||||
|
||||
// Draw border and territory
|
||||
for (const tile of this.game.bfs(
|
||||
unit.tile(),
|
||||
@@ -158,9 +183,7 @@ export class StructureLayer implements Layer {
|
||||
)) {
|
||||
this.paintCell(
|
||||
new Cell(this.game.x(tile), this.game.y(tile)),
|
||||
unit.type() == UnitType.Construction
|
||||
? underConstructionColor
|
||||
: this.theme.borderColor(unit.owner().info()),
|
||||
borderColor,
|
||||
255,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ export interface Config {
|
||||
|
||||
export interface Theme {
|
||||
territoryColor(playerInfo: PlayerInfo): Colord;
|
||||
specialBuildingColor(playerInfo: PlayerInfo): Colord;
|
||||
borderColor(playerInfo: PlayerInfo): Colord;
|
||||
defendedBorderColor(playerInfo: PlayerInfo): Colord;
|
||||
terrainColor(gm: GameMap, tile: TileRef): Colord;
|
||||
|
||||
@@ -256,6 +256,15 @@ export const pastelTheme = new (class implements Theme {
|
||||
return playerInfo.playerType == PlayerType.Human ? "#000000" : "#4D4D4D";
|
||||
}
|
||||
|
||||
specialBuildingColor(playerInfo: PlayerInfo): Colord {
|
||||
const tc = this.territoryColor(playerInfo).rgba;
|
||||
return colord({
|
||||
r: Math.max(tc.r - 50, 0),
|
||||
g: Math.max(tc.g - 50, 0),
|
||||
b: Math.max(tc.b - 50, 0),
|
||||
});
|
||||
}
|
||||
|
||||
borderColor(playerInfo: PlayerInfo): Colord {
|
||||
const tc = this.territoryColor(playerInfo).rgba;
|
||||
return colord({
|
||||
|
||||
@@ -256,6 +256,15 @@ export const pastelThemeDark = new (class implements Theme {
|
||||
return playerInfo.playerType == PlayerType.Human ? "#ffffff" : "#e6e6e6";
|
||||
}
|
||||
|
||||
specialBuildingColor(playerInfo: PlayerInfo): Colord {
|
||||
const tc = this.territoryColor(playerInfo).rgba;
|
||||
return colord({
|
||||
r: Math.max(tc.r - 50, 0),
|
||||
g: Math.max(tc.g - 50, 0),
|
||||
b: Math.max(tc.b - 50, 0),
|
||||
});
|
||||
}
|
||||
|
||||
borderColor(playerInfo: PlayerInfo): Colord {
|
||||
const tc = this.territoryColor(playerInfo).rgba;
|
||||
return colord({
|
||||
|
||||
@@ -92,8 +92,15 @@ export class SAMLauncherExecution implements Execution {
|
||||
);
|
||||
})[0] ?? null;
|
||||
|
||||
const cooldown =
|
||||
this.lastMissileAttack != 0 &&
|
||||
this.mg.ticks() - this.lastMissileAttack <= this.missileAttackRate;
|
||||
if (this.post.isSamCooldown() != cooldown) {
|
||||
this.post.setSamCooldown(cooldown);
|
||||
}
|
||||
|
||||
if (this.target != null) {
|
||||
if (this.mg.ticks() - this.lastMissileAttack > this.missileAttackRate) {
|
||||
if (!this.post.isSamCooldown()) {
|
||||
this.lastMissileAttack = this.mg.ticks();
|
||||
this.mg.addExecution(
|
||||
new SAMMissileExecution(
|
||||
|
||||
@@ -235,6 +235,8 @@ export interface Unit {
|
||||
setWarshipTarget(target: Unit): void; // warship only
|
||||
warshipTarget(): Unit;
|
||||
|
||||
setSamCooldown(isCoolingDown: boolean): void; // Only for sam
|
||||
isSamCooldown(): boolean;
|
||||
setDstPort(dstPort: Unit): void;
|
||||
dstPort(): Unit; // Only for trade ships
|
||||
detonationDst(): TileRef; // Only for nukes
|
||||
|
||||
@@ -74,6 +74,7 @@ export interface UnitUpdate {
|
||||
warshipTargetId?: number;
|
||||
health?: number;
|
||||
constructionType?: UnitType;
|
||||
isSamCooldown?: boolean;
|
||||
}
|
||||
|
||||
export interface AttackUpdate {
|
||||
|
||||
@@ -111,6 +111,9 @@ export class UnitView {
|
||||
}
|
||||
return this.data.warshipTargetId;
|
||||
}
|
||||
isSamCooldown(): boolean {
|
||||
return this.data.isSamCooldown;
|
||||
}
|
||||
}
|
||||
|
||||
export class PlayerView {
|
||||
|
||||
@@ -18,6 +18,7 @@ export class UnitImpl implements Unit {
|
||||
|
||||
private _constructionType: UnitType = undefined;
|
||||
|
||||
private _isSamCooldown: boolean;
|
||||
private _dstPort: Unit | null = null; // Only for trade ships
|
||||
private _detonationDst: TileRef | null = null; // Only for nukes
|
||||
private _warshipTarget: Unit | null = null;
|
||||
@@ -59,6 +60,7 @@ export class UnitImpl implements Unit {
|
||||
dstPortId: dstPort ? dstPort.id() : null,
|
||||
warshipTargetId: warshipTarget ? warshipTarget.id() : null,
|
||||
detonationDst: this.detonationDst(),
|
||||
isSamCooldown: this.isSamCooldown() ? this.isSamCooldown() : null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -182,6 +184,15 @@ export class UnitImpl implements Unit {
|
||||
return this._dstPort;
|
||||
}
|
||||
|
||||
setSamCooldown(cooldown: boolean): void {
|
||||
this._isSamCooldown = cooldown;
|
||||
this.mg.addUpdate(this.toUpdate());
|
||||
}
|
||||
|
||||
isSamCooldown(): boolean {
|
||||
return this._isSamCooldown;
|
||||
}
|
||||
|
||||
setDstPort(dstPort: Unit): void {
|
||||
this._dstPort = dstPort;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user