mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 07:40:43 +00:00
Move player info panel to top of the screen & simplify (#3087)
related to #2260 ## Description: * Moves the player info panel from the right to the top of the screen * Disable the header ad for now because it would cover up the player info, we'll find a better place for it in the future * Remove the collapsable button/functionality. It's hard to even click the button because the panel disappears when you move away from a player, and I think the info is too valuable to ever need to be collapsed. * Removed the "land" and "irradiated land" since it didn't add much value * Remove all alt text & translation, you can't hover over the player overlay so it's irrelevant. * put troop info inside the troop bar to reduce amount of text <img width="479" height="88" alt="Screenshot 2026-02-01 at 8 57 33 PM" src="https://github.com/user-attachments/assets/3b72eb16-2efa-4c00-a4d0-5e085548fa78" /> <img width="438" height="136" alt="Screenshot 2026-02-01 at 8 58 06 PM" src="https://github.com/user-attachments/assets/285bb2c9-6deb-4ee8-bcc8-743cccd6b77e" /> ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
This commit is contained in:
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125" xmlns:v="https://vecta.io/nano"><path d="M86.946 70.119l-2.417-15.098c-.286-1.419-1.511-2.495-2.982-2.495-.899 0-1.687.385-2.268.997L68.104 63.997c-.176.156-.352.338-.515.56-1.049 1.433-.749 3.465.684 4.527.273.215.573.345.866.462l2.808.931c-2.697 7.641-9.313 13.45-17.417 15.059l.014-45.638h5.992c1.889 0 3.412-1.538 3.412-3.426 0-1.875-1.523-3.413-3.412-3.413h-5.992v-6.78c3.979-1.687 6.721-5.634 6.721-10.206C61.264 9.95 56.314 5 50.192 5c-6.097 0-11.073 4.95-11.073 11.073 0 4.578 2.847 8.52 6.8 10.206l.007 6.78h-6.468c-1.882 0-3.413 1.538-3.413 3.413 0 1.889 1.531 3.426 3.413 3.426h6.468l.021 45.71c-8.292-1.485-15.15-7.354-17.926-15.131l2.827-.931c.299-.117.6-.247.879-.456 1.427-1.067 1.753-3.1.671-4.533-.155-.222-.313-.404-.508-.554L20.706 53.524c-.553-.612-1.361-.997-2.246-.997-1.486 0-2.743 1.075-3.009 2.495L13.027 70.12c-.053.241-.064.508-.064.762 0 1.791 1.446 3.236 3.229 3.236.339 0 .658-.032.959-.137l2.624-.853C23.956 85.816 35.901 95 49.997 95s26.053-9.184 30.221-21.891l2.619.872c.299.105.618.137.963.137 1.785 0 3.237-1.446 3.237-3.236 0-.255-.025-.522-.091-.763M45.659 16.073c0-2.521 2.044-4.553 4.533-4.553 2.527 0 4.552 2.032 4.552 4.553 0 2.514-2.024 4.559-4.552 4.559-2.489 0-4.533-2.046-4.533-4.559"/><path d="M46.821306 94.770829c-9.672125-.972647-18.52814-6.513856-23.771656-14.873922-.868866-1.385288-2.385574-4.487112-2.870545-5.870561l-.343618-.96102c-.0095-.01668-.705224.192731-1.545948.46535s-1.804312.494255-2.141309.492526c-1.598809-.0082-3.122304-1.547171-3.115278-3.146913.000864-.196879.574575-3.918388 1.274912-8.270022 1.419295-8.818969 1.428076-8.850837 2.627499-9.536632.834583-.477189 1.483957-.563323 2.337029-.309989.644845.191499 1.336272.793564 6.866372 5.978939 4.549564 4.26596 6.233135 5.932201 6.471488 6.40487.603214 1.196211.325525 2.693184-.677921 3.654548-.288018.275937-1.002559.607386-2.183926 1.013042-2.007091.68919-1.921853.529349-1.189152 2.229934 2.313522 5.369652 7.064022 9.988932 12.577448 12.230032 1.263767.513697 3.384288 1.159414 4.275471 1.30192l.550027.08795V62.733077 39.805269H42.37799c-3.958889 0-4.236614-.04887-5.126792-.902159-.76147-.729916-1.085823-1.473414-1.081006-2.477941.0071-1.483668.947583-2.699422 2.43431-3.146861.49772-.149791 1.545965-.202707 4.01562-.202707h3.342077v-3.423483-3.423485l-1.109679-.604511c-.793899-.432485-1.482722-.979822-2.420583-1.923389-1.146297-1.15327-1.401076-1.505996-2.029023-2.809061-.858345-1.781165-1.170382-3.086543-1.170382-4.896174 0-6.4184795 5.839733-11.6186738 12.164919-10.8326779 2.656895.3301574 4.668838 1.3296881 6.615711 3.286675 1.070143 1.0757025 1.339007 1.4513238 1.957431 2.7346549.865772 1.796619 1.169155 3.085051 1.169155 4.965255 0 4.023175-2.191435 7.679165-5.755536 9.602011l-.969271.522925-.0024 3.389446-.0024 3.389446 3.472222.04702c3.946037.05344 4.168331.108713 5.177124 1.287261 1.316051 1.53751.926562 3.821223-.837885 4.912821l-.700444.433339-3.555509.04279-3.555508.0428v22.902508l.107388 22.902148c.332248-.0011 2.935079-.780331 4.075018-1.219944 5.752163-2.218302 10.721311-7.144396 13.059805-12.946652.204466-.507318.322918-.966456.263226-1.020307s-.65621-.274921-1.325597-.491268c-1.73484-.560706-2.51001-1.013168-2.998016-1.749923-.680235-1.026966-.727607-2.0483-.14813-3.19361.309132-.610985 12.085183-11.683542 12.854449-12.08653 1.199252-.628243 2.81487-.181005 3.651625 1.010847.392869.559594.481176 1.003292 1.695561 8.519473.875547 5.419011 1.264717 8.190005 1.229335 8.753186-.06941 1.104804-.613524 1.897274-1.670778 2.433394-1.027413.520988-1.635513.502208-3.442467-.106313-.816705-.275039-1.512424-.472563-1.546044-.438944s-.379938.854657-.769596 1.824527c-2.13365 5.310705-5.61865 9.924534-10.123033 13.401993-6.338429 4.893379-14.56767 7.254819-22.501513 6.456977zm4.86827-74.330261c1.140586-.346728 2.230937-1.344337 2.770928-2.535241.21803-.480845.29704-.95557.301498-1.811516.0055-1.049248-.04177-1.253646-.495106-2.142377-1.123467-2.202486-3.642798-3.073429-5.980881-2.067613-.987511.424816-2.068224 1.59611-2.409954 2.611949-1.248434 3.711132 2.053637 7.087771 5.813515 5.944798z" fill="#fff"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" xmlns:v="https://vecta.io/nano"><path d="M86.946 70.119l-2.417-15.098c-.286-1.419-1.511-2.495-2.982-2.495-.899 0-1.687.385-2.268.997L68.104 63.997c-.176.156-.352.338-.515.56-1.049 1.433-.749 3.465.684 4.527.273.215.573.345.866.462l2.808.931c-2.697 7.641-9.313 13.45-17.417 15.059l.014-45.638h5.992c1.889 0 3.412-1.538 3.412-3.426 0-1.875-1.523-3.413-3.412-3.413h-5.992v-6.78c3.979-1.687 6.721-5.634 6.721-10.206C61.264 9.95 56.314 5 50.192 5c-6.097 0-11.073 4.95-11.073 11.073 0 4.578 2.847 8.52 6.8 10.206l.007 6.78h-6.468c-1.882 0-3.413 1.538-3.413 3.413 0 1.889 1.531 3.426 3.413 3.426h6.468l.021 45.71c-8.292-1.485-15.15-7.354-17.926-15.131l2.827-.931c.299-.117.6-.247.879-.456 1.427-1.067 1.753-3.1.671-4.533-.155-.222-.313-.404-.508-.554L20.706 53.524c-.553-.612-1.361-.997-2.246-.997-1.486 0-2.743 1.075-3.009 2.495L13.027 70.12c-.053.241-.064.508-.064.762 0 1.791 1.446 3.236 3.229 3.236.339 0 .658-.032.959-.137l2.624-.853C23.956 85.816 35.901 95 49.997 95s26.053-9.184 30.221-21.891l2.619.872c.299.105.618.137.963.137 1.785 0 3.237-1.446 3.237-3.236 0-.255-.025-.522-.091-.763M45.659 16.073c0-2.521 2.044-4.553 4.533-4.553 2.527 0 4.552 2.032 4.552 4.553 0 2.514-2.024 4.559-4.552 4.559-2.489 0-4.533-2.046-4.533-4.559"/><path d="M46.821306 94.770829c-9.672125-.972647-18.52814-6.513856-23.771656-14.873922-.868866-1.385288-2.385574-4.487112-2.870545-5.870561l-.343618-.96102c-.0095-.01668-.705224.192731-1.545948.46535s-1.804312.494255-2.141309.492526c-1.598809-.0082-3.122304-1.547171-3.115278-3.146913.000864-.196879.574575-3.918388 1.274912-8.270022 1.419295-8.818969 1.428076-8.850837 2.627499-9.536632.834583-.477189 1.483957-.563323 2.337029-.309989.644845.191499 1.336272.793564 6.866372 5.978939 4.549564 4.26596 6.233135 5.932201 6.471488 6.40487.603214 1.196211.325525 2.693184-.677921 3.654548-.288018.275937-1.002559.607386-2.183926 1.013042-2.007091.68919-1.921853.529349-1.189152 2.229934 2.313522 5.369652 7.064022 9.988932 12.577448 12.230032 1.263767.513697 3.384288 1.159414 4.275471 1.30192l.550027.08795V62.733077 39.805269H42.37799c-3.958889 0-4.236614-.04887-5.126792-.902159-.76147-.729916-1.085823-1.473414-1.081006-2.477941.0071-1.483668.947583-2.699422 2.43431-3.146861.49772-.149791 1.545965-.202707 4.01562-.202707h3.342077v-3.423483-3.423485l-1.109679-.604511c-.793899-.432485-1.482722-.979822-2.420583-1.923389-1.146297-1.15327-1.401076-1.505996-2.029023-2.809061-.858345-1.781165-1.170382-3.086543-1.170382-4.896174 0-6.4184795 5.839733-11.6186738 12.164919-10.8326779 2.656895.3301574 4.668838 1.3296881 6.615711 3.286675 1.070143 1.0757025 1.339007 1.4513238 1.957431 2.7346549.865772 1.796619 1.169155 3.085051 1.169155 4.965255 0 4.023175-2.191435 7.679165-5.755536 9.602011l-.969271.522925-.0024 3.389446-.0024 3.389446 3.472222.04702c3.946037.05344 4.168331.108713 5.177124 1.287261 1.316051 1.53751.926562 3.821223-.837885 4.912821l-.700444.433339-3.555509.04279-3.555508.0428v22.902508l.107388 22.902148c.332248-.0011 2.935079-.780331 4.075018-1.219944 5.752163-2.218302 10.721311-7.144396 13.059805-12.946652.204466-.507318.322918-.966456.263226-1.020307s-.65621-.274921-1.325597-.491268c-1.73484-.560706-2.51001-1.013168-2.998016-1.749923-.680235-1.026966-.727607-2.0483-.14813-3.19361.309132-.610985 12.085183-11.683542 12.854449-12.08653 1.199252-.628243 2.81487-.181005 3.651625 1.010847.392869.559594.481176 1.003292 1.695561 8.519473.875547 5.419011 1.264717 8.190005 1.229335 8.753186-.06941 1.104804-.613524 1.897274-1.670778 2.433394-1.027413.520988-1.635513.502208-3.442467-.106313-.816705-.275039-1.512424-.472563-1.546044-.438944s-.379938.854657-.769596 1.824527c-2.13365 5.310705-5.61865 9.924534-10.123033 13.401993-6.338429 4.893379-14.56767 7.254819-22.501513 6.456977zm4.86827-74.330261c1.140586-.346728 2.230937-1.344337 2.770928-2.535241.21803-.480845.29704-.95557.301498-1.811516.0055-1.049248-.04177-1.253646-.495106-2.142377-1.123467-2.202486-3.642798-3.073429-5.980881-2.067613-.987511.424816-2.068224 1.59611-2.409954 2.611949-1.248434 3.711132 2.053637 7.087771 5.813515 5.944798z" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="1200pt" height="1200pt" version="1.1" viewBox="0 0 1200 1200" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m417.86 237.12v-237.12h-40.664v432.45h78.738v-195.34z"/>
|
||||
<path d="m708.33 392.05h302.69v69.617l38.762-0.14453-0.046875-5.3555s-0.5-48.523-0.5-68.785c0-113.14-85.332-204.45-189.74-204.45-104.5 0-190.45 93.094-190.45 206.26 0 20.477-0.5 70.215-0.5 70.238l-0.046875 2.0703h39.809z"/>
|
||||
<path d="m735.59 418.45c-0.26172 2.9062-0.66797 5.7852-0.66797 8.7383 0 68.832 55.809 124.57 124.59 124.57 68.785 0 124.55-55.762 124.55-124.57 0-2.9766-0.45312-5.8555-0.64453-8.7383z"/>
|
||||
<path d="m1030.2 573.67h-331.57c-96.855 0-169.98 56.047-169.98 154.98v409.93c0 33.191 26.953 60.023 60.094 60.023 33.191 0 60.047-26.883 60.047-60.023l0.046875-367.07h37.738v428.5h355.53v-428.52h37.547l0.19141 367.07c0 33.191 26.953 60.023 60.023 60.023 33.238 0 60.094-26.883 60.094-60.023v-409.95c0.046875-98.926-72.953-154.93-169.76-154.93zm-47.5 207-48.785-25.668-48.762 25.668 9.3086-54.309-39.43-38.43 54.5-7.9297 24.383-49.406 24.355 49.406 54.523 7.9297-39.453 38.43z"/>
|
||||
<path d="m489.07 1162-0.90625-396.02-30.668 0.070312-0.71094-311.24-78.523 0.19141 0.71484 293.79s-24.262 41.57-100.19 41.57c-69.332 0-225.52-90.809-225.52-90.809l-53.262 131.71s112.19 55.883 173.67 65.43c23 3.5938 47.617 5.1172 71.191 5.4766-13.883 15.453-22.547 35.668-22.547 58.023 0 28.168 13.617 52.953 34.383 68.953l-133.91 67.977 55.07 97.906 136.24-93.93s13.93-9.8555 26.285-3.332c11.117 5.8828 12.617 20.57 12.617 20.57l0.11719 44.047 46.07-0.30859-0.57031 37.191h53.309l-0.023437-37.262zm-180-159.05c-23.43 0-42.406-19-42.406-42.406s18.977-42.406 42.406-42.406c18.023 0 33.332 11.309 39.477 27.168h-43.57v33.477h42.238c-6.832 14.238-21.262 24.168-38.145 24.168z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -733,29 +733,6 @@
|
||||
"show_control": "Show Control",
|
||||
"show_units": "Show Units"
|
||||
},
|
||||
"player_info_overlay": {
|
||||
"type": "Type",
|
||||
"bot": "Bot",
|
||||
"nation": "Nation",
|
||||
"player": "Player",
|
||||
"team": "Team",
|
||||
"alliance_timeout": "Alliance ends in",
|
||||
"troops": "Troops",
|
||||
"maxtroops": "Max troops",
|
||||
"a_troops": "Attacking troops",
|
||||
"gold": "Gold",
|
||||
"ports": "Ports",
|
||||
"cities": "Cities",
|
||||
"factories": "Factories",
|
||||
"missile_launchers": "Missile launchers",
|
||||
"sams": "SAMs",
|
||||
"warships": "Warships",
|
||||
"health": "Health",
|
||||
"attitude": "Attitude",
|
||||
"levels": "Levels",
|
||||
"wilderness_title": "Wilderness",
|
||||
"irradiated_wilderness_title": "Irradiated Wilderness"
|
||||
},
|
||||
"events_display": {
|
||||
"retreating": "retreating",
|
||||
"retaliate": "Retaliate",
|
||||
|
||||
@@ -21,7 +21,8 @@ export class InGameHeaderAd extends LitElement implements Layer {
|
||||
}
|
||||
|
||||
init() {
|
||||
this.showHeaderAd();
|
||||
// TODO: move ad and re-enable.
|
||||
// this.showHeaderAd();
|
||||
}
|
||||
|
||||
private showHeaderAd(): void {
|
||||
|
||||
@@ -32,6 +32,7 @@ import goldCoinIcon from "/images/GoldCoinIcon.svg?url";
|
||||
import missileSiloIcon from "/images/MissileSiloIconWhite.svg?url";
|
||||
import portIcon from "/images/PortIcon.svg?url";
|
||||
import samLauncherIcon from "/images/SamLauncherIconWhite.svg?url";
|
||||
import soldierIcon from "/images/SoldierIcon.svg?url";
|
||||
|
||||
function euclideanDistWorld(
|
||||
coord: { x: number; y: number },
|
||||
@@ -73,12 +74,6 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
@state()
|
||||
private unit: UnitView | null = null;
|
||||
|
||||
@state()
|
||||
private isWilderness: boolean = false;
|
||||
|
||||
@state()
|
||||
private isIrradiatedWilderness: boolean = false;
|
||||
|
||||
@state()
|
||||
private _isInfoVisible: boolean = false;
|
||||
|
||||
@@ -86,8 +81,6 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
|
||||
private lastMouseUpdate = 0;
|
||||
|
||||
private showDetails = true;
|
||||
|
||||
init() {
|
||||
this.eventBus.on(MouseMoveEvent, (e: MouseMoveEvent) =>
|
||||
this.onMouseEvent(e),
|
||||
@@ -112,8 +105,6 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
this.setVisible(false);
|
||||
this.unit = null;
|
||||
this.player = null;
|
||||
this.isWilderness = false;
|
||||
this.isIrradiatedWilderness = false;
|
||||
}
|
||||
|
||||
public maybeShow(x: number, y: number) {
|
||||
@@ -134,13 +125,6 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
this.playerProfile = p;
|
||||
});
|
||||
this.setVisible(true);
|
||||
} else if (owner && !owner.isPlayer() && this.game.isLand(tile)) {
|
||||
if (this.game.hasFallout(tile)) {
|
||||
this.isIrradiatedWilderness = true;
|
||||
} else {
|
||||
this.isWilderness = true;
|
||||
}
|
||||
this.setVisible(true);
|
||||
} else if (!this.game.isLand(tile)) {
|
||||
const units = this.game
|
||||
.units(UnitType.Warship, UnitType.TradeShip, UnitType.TransportShip)
|
||||
@@ -201,28 +185,17 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
}
|
||||
}
|
||||
|
||||
private displayUnitCount(
|
||||
player: PlayerView,
|
||||
type: UnitType,
|
||||
icon: string,
|
||||
description: string,
|
||||
) {
|
||||
private displayUnitCount(player: PlayerView, type: UnitType, icon: string) {
|
||||
return !this.game.config().isUnitDisabled(type)
|
||||
? html`<div
|
||||
class="flex p-1 w-[calc(50%-0.13rem)] border rounded-md border-gray-500
|
||||
items-center gap-2 text-sm"
|
||||
class="flex items-center justify-center gap-0.5 lg:gap-1 p-0.5 lg:p-1 border rounded-md border-gray-500 text-[10px] lg:text-xs w-9 lg:w-12 h-6 lg:h-7"
|
||||
translate="no"
|
||||
>
|
||||
<img
|
||||
src=${icon}
|
||||
width="20"
|
||||
height="20"
|
||||
alt="${translateText(description)}"
|
||||
class="align-middle"
|
||||
class="w-3 h-3 lg:w-4 lg:h-4 object-contain shrink-0"
|
||||
/>
|
||||
<span class="w-full text-right p-1"
|
||||
>${player.totalUnitLevels(type)}</span
|
||||
>
|
||||
<span>${player.totalUnitLevels(type)}</span>
|
||||
</div>`
|
||||
: "";
|
||||
}
|
||||
@@ -268,7 +241,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
const myPlayer = this.game.myPlayer();
|
||||
const isFriendly = myPlayer?.isFriendly(player);
|
||||
const isAllied = myPlayer?.isAlliedWith(player);
|
||||
let relationHtml: TemplateResult | null = null;
|
||||
let allianceHtml: TemplateResult | null = null;
|
||||
const maxTroops = this.game.config().maxTroops(player);
|
||||
const attackingTroops = player
|
||||
.outgoingAttacks()
|
||||
@@ -276,34 +249,17 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
.reduce((a, b) => a + b, 0);
|
||||
const totalTroops = player.troops();
|
||||
|
||||
if (player.type() === PlayerType.Nation && myPlayer !== null && !isAllied) {
|
||||
const relation =
|
||||
this.playerProfile?.relations[myPlayer.smallID()] ?? Relation.Neutral;
|
||||
const relationClass = this.getRelationClass(relation);
|
||||
const relationName = this.getRelationName(relation);
|
||||
|
||||
relationHtml = html`
|
||||
<span class="ml-auto mr-0 ${relationClass}">${relationName}</span>
|
||||
`;
|
||||
}
|
||||
|
||||
if (isAllied) {
|
||||
const alliance = myPlayer
|
||||
?.alliances()
|
||||
.find((alliance) => alliance.other === player.id());
|
||||
if (alliance !== undefined) {
|
||||
relationHtml = html` <span
|
||||
class="flex gap-2 ml-auto mr-0 text-sm font-bold"
|
||||
allianceHtml = html` <div
|
||||
class="flex flex-col items-center ml-auto mr-0 text-sm font-bold leading-tight"
|
||||
>
|
||||
<img
|
||||
src=${allianceIcon}
|
||||
alt=${translateText("player_info_overlay.alliance_timeout")}
|
||||
width="20"
|
||||
height="20"
|
||||
class="align-middle"
|
||||
/>
|
||||
<img src=${allianceIcon} width="20" height="20" />
|
||||
${this.allianceExpirationText(alliance)}
|
||||
</span>`;
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
let playerType = "";
|
||||
@@ -320,128 +276,83 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="p-2">
|
||||
<button
|
||||
class="items-center text-bold text-sm lg:text-lg font-bold mb-1 inline-flex break-all ${isFriendly
|
||||
? "text-green-500"
|
||||
: "text-white"}"
|
||||
@click=${() => {
|
||||
this.showDetails = !this.showDetails;
|
||||
this.requestUpdate?.();
|
||||
}}
|
||||
>
|
||||
${player.cosmetics.flag
|
||||
? player.cosmetics.flag!.startsWith("!")
|
||||
? html`<div
|
||||
class="h-8 mr-1 aspect-3/4 player-flag"
|
||||
${ref((el) => {
|
||||
if (el instanceof HTMLElement) {
|
||||
requestAnimationFrame(() => {
|
||||
renderPlayerFlag(player.cosmetics.flag!, el);
|
||||
});
|
||||
}
|
||||
})}
|
||||
></div>`
|
||||
: html`<img
|
||||
class="h-8 mr-1 aspect-3/4"
|
||||
src=${"/flags/" + player.cosmetics.flag! + ".svg"}
|
||||
/>`
|
||||
: html``}
|
||||
<span>${player.name()}</span>
|
||||
${this.renderPlayerNameIcons(player)}
|
||||
</button>
|
||||
|
||||
<!-- Collapsible section -->
|
||||
${this.showDetails
|
||||
? html`
|
||||
${player.team() !== null
|
||||
? html`<div class="text-sm">
|
||||
${translateText("player_info_overlay.team")}:
|
||||
${player.team()}
|
||||
</div>`
|
||||
: ""}
|
||||
<div class="flex text-sm">${playerType} ${relationHtml}</div>
|
||||
${player.troops() >= 1
|
||||
? html`<div class="flex gap-2 text-sm" translate="no">
|
||||
${translateText("player_info_overlay.troops")}
|
||||
<span class="ml-auto mr-0 font-bold">
|
||||
${renderTroops(player.troops())}
|
||||
</span>
|
||||
</div>`
|
||||
: ""}
|
||||
${maxTroops >= 1
|
||||
? html`<div class="flex gap-2 text-sm" translate="no">
|
||||
${translateText("player_info_overlay.maxtroops")}
|
||||
<span class="ml-auto mr-0 font-bold">
|
||||
${renderTroops(maxTroops)}
|
||||
</span>
|
||||
</div>`
|
||||
: ""}
|
||||
${attackingTroops >= 1
|
||||
? html`<div class="flex gap-2 text-sm" translate="no">
|
||||
${translateText("player_info_overlay.a_troops")}
|
||||
<span class="ml-auto mr-0 text-red-400 font-bold">
|
||||
${renderTroops(attackingTroops)}
|
||||
</span>
|
||||
</div>`
|
||||
: ""}
|
||||
${this.renderTroopBar(totalTroops, attackingTroops, maxTroops)}
|
||||
<div
|
||||
class="flex p-1 mb-1 mt-1 w-full border rounded-md border-yellow-400
|
||||
font-bold text-yellow-400 text-sm"
|
||||
translate="no"
|
||||
>
|
||||
<img
|
||||
src=${goldCoinIcon}
|
||||
alt=${translateText("player_info_overlay.gold")}
|
||||
width="15"
|
||||
height="15"
|
||||
class="align-middle"
|
||||
/>
|
||||
<span class="w-full text-center"
|
||||
>${renderNumber(player.gold())}</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex flex-wrap max-w-3xl gap-1">
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.City,
|
||||
cityIcon,
|
||||
"player_info_overlay.cities",
|
||||
)}
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.Factory,
|
||||
factoryIcon,
|
||||
"player_info_overlay.factories",
|
||||
)}
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.Port,
|
||||
portIcon,
|
||||
"player_info_overlay.ports",
|
||||
)}
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.MissileSilo,
|
||||
missileSiloIcon,
|
||||
"player_info_overlay.missile_launchers",
|
||||
)}
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.SAMLauncher,
|
||||
samLauncherIcon,
|
||||
"player_info_overlay.sams",
|
||||
)}
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.Warship,
|
||||
warshipIcon,
|
||||
"player_info_overlay.warships",
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
<div class="flex items-start gap-2 lg:gap-3 p-1.5 lg:p-2">
|
||||
<!-- Left: Gold & Troop bar -->
|
||||
<div class="flex flex-col gap-1 shrink-0 w-28">
|
||||
<div
|
||||
class="flex items-center justify-center p-1 border rounded-md border-yellow-400 font-bold text-yellow-400 text-xs w-28"
|
||||
translate="no"
|
||||
>
|
||||
<img src=${goldCoinIcon} width="13" height="13" />
|
||||
<span class="px-0.5">${renderNumber(player.gold())}</span>
|
||||
</div>
|
||||
<div class="w-28" translate="no">
|
||||
${this.renderTroopBar(totalTroops, attackingTroops, maxTroops)}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right: Player identity + Units below -->
|
||||
<div class="flex flex-col justify-between self-stretch">
|
||||
<div
|
||||
class="flex items-center gap-2 font-bold text-sm lg:text-lg ${isFriendly
|
||||
? "text-green-500"
|
||||
: "text-white"}"
|
||||
>
|
||||
${player.cosmetics.flag
|
||||
? player.cosmetics.flag!.startsWith("!")
|
||||
? html`<div
|
||||
class="h-6 aspect-3/4 player-flag"
|
||||
${ref((el) => {
|
||||
if (el instanceof HTMLElement) {
|
||||
requestAnimationFrame(() => {
|
||||
renderPlayerFlag(player.cosmetics.flag!, el);
|
||||
});
|
||||
}
|
||||
})}
|
||||
></div>`
|
||||
: html`<img
|
||||
class="h-6 aspect-3/4"
|
||||
src=${"/flags/" + player.cosmetics.flag! + ".svg"}
|
||||
/>`
|
||||
: html``}
|
||||
<span>${player.name()}</span>
|
||||
${player.team() !== null && player.type() !== PlayerType.Bot
|
||||
? html`<div class="flex flex-col leading-tight">
|
||||
<span class="text-gray-400 text-xs font-normal"
|
||||
>${playerType}</span
|
||||
>
|
||||
<span class="text-xs font-normal text-gray-400"
|
||||
>[<span
|
||||
style="color: ${this.game
|
||||
.config()
|
||||
.theme()
|
||||
.teamColor(player.team()!)
|
||||
.toHex()}"
|
||||
>${player.team()}</span
|
||||
>]</span
|
||||
>
|
||||
</div>`
|
||||
: html`<span class="text-gray-400 text-xs font-normal"
|
||||
>${playerType}</span
|
||||
>`}
|
||||
${this.renderPlayerNameIcons(player)} ${allianceHtml ?? ""}
|
||||
</div>
|
||||
<div class="flex gap-0.5 lg:gap-1 items-center mt-1">
|
||||
${this.displayUnitCount(player, UnitType.City, cityIcon)}
|
||||
${this.displayUnitCount(player, UnitType.Factory, factoryIcon)}
|
||||
${this.displayUnitCount(player, UnitType.Port, portIcon)}
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.MissileSilo,
|
||||
missileSiloIcon,
|
||||
)}
|
||||
${this.displayUnitCount(
|
||||
player,
|
||||
UnitType.SAMLauncher,
|
||||
samLauncherIcon,
|
||||
)}
|
||||
${this.displayUnitCount(player, UnitType.Warship, warshipIcon)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -463,7 +374,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
|
||||
return html`
|
||||
<div
|
||||
class="w-full mt-2 mb-2 h-5 border border-gray-600 rounded-md bg-gray-900/60 overflow-hidden"
|
||||
class="w-full mt-1 lg:mt-2 h-5 lg:h-6 border border-gray-600 rounded-md bg-gray-900/60 overflow-hidden relative"
|
||||
>
|
||||
<div class="h-full flex">
|
||||
${greenPercent > 0
|
||||
@@ -479,6 +390,25 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
></div>`
|
||||
: ""}
|
||||
</div>
|
||||
<div
|
||||
class="absolute inset-0 flex items-center justify-between px-1.5 text-xs font-bold leading-none pointer-events-none"
|
||||
translate="no"
|
||||
>
|
||||
<span class="text-white drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)]"
|
||||
>${renderTroops(totalTroops)}</span
|
||||
>
|
||||
<span class="text-white drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)]"
|
||||
>${renderTroops(maxTroops)}</span
|
||||
>
|
||||
</div>
|
||||
<img
|
||||
src=${soldierIcon}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
width="14"
|
||||
height="14"
|
||||
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 brightness-0 invert drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)] pointer-events-none"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -497,18 +427,12 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
<div class="mt-1">
|
||||
<div class="text-sm opacity-80">${unit.type()}</div>
|
||||
${unit.hasHealth()
|
||||
? html`
|
||||
<div class="text-sm">
|
||||
${translateText("player_info_overlay.health")}:
|
||||
${unit.health()}
|
||||
</div>
|
||||
`
|
||||
? html` <div class="text-sm">Health: ${unit.health()}</div> `
|
||||
: ""}
|
||||
${unit.type() === UnitType.TransportShip
|
||||
? html`
|
||||
<div class="text-sm">
|
||||
${translateText("player_info_overlay.troops")}:
|
||||
${renderTroops(unit.troops())}
|
||||
Troops: ${renderTroops(unit.troops())}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
@@ -528,21 +452,12 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
|
||||
return html`
|
||||
<div
|
||||
class="block lg:flex fixed top-37.5 right-4 w-full z-50 flex-col max-w-45"
|
||||
class="fixed top-0 lg:top-[10px] left-0 right-0 sm:left-1/2 sm:right-auto sm:-translate-x-1/2 z-[1001]"
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
<div
|
||||
class="bg-gray-800/70 backdrop-blur-xs shadow-xs rounded-lg shadow-lg transition-all duration-300 text-white text-lg md:text-base ${containerClasses}"
|
||||
class="bg-gray-800/70 backdrop-blur-xs shadow-xs lg:rounded-lg shadow-lg transition-all duration-300 text-white text-lg lg:text-base w-full sm:w-auto sm:min-w-[400px] overflow-hidden ${containerClasses}"
|
||||
>
|
||||
${this.isWilderness || this.isIrradiatedWilderness
|
||||
? html`<div class="p-2 font-bold">
|
||||
${translateText(
|
||||
this.isIrradiatedWilderness
|
||||
? "player_info_overlay.irradiated_wilderness_title"
|
||||
: "player_info_overlay.wilderness_title",
|
||||
)}
|
||||
</div>`
|
||||
: ""}
|
||||
${this.player !== null ? this.renderPlayerInfo(this.player) : ""}
|
||||
${this.unit !== null ? this.renderUnitInfo(this.unit) : ""}
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@ import { Layer } from "./Layer";
|
||||
import warshipIcon from "/images/BattleshipIconWhite.svg?url";
|
||||
import cityIcon from "/images/CityIconWhite.svg?url";
|
||||
import factoryIcon from "/images/FactoryIconWhite.svg?url";
|
||||
import goldCoinIcon from "/images/GoldCoinIcon.svg?url";
|
||||
import mirvIcon from "/images/MIRVIcon.svg?url";
|
||||
import missileSiloIcon from "/images/MissileSiloIconWhite.svg?url";
|
||||
import hydrogenBombIcon from "/images/MushroomCloudIconWhite.svg?url";
|
||||
@@ -256,11 +257,11 @@ export class UnitDisplay extends LitElement implements Layer {
|
||||
<div class="p-2">
|
||||
${translateText("build_menu.desc." + structureKey)}
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center justify-center gap-1">
|
||||
<img src=${goldCoinIcon} width="13" height="13" />
|
||||
<span class="text-yellow-300"
|
||||
>${renderNumber(this.cost(unitType))}</span
|
||||
>
|
||||
${translateText("player_info_overlay.gold")}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user