348 lines
9.0 KiB
ActionScript
348 lines
9.0 KiB
ActionScript
import overlays.Popup;
|
|
import elements.GuiText;
|
|
import elements.GuiSprite;
|
|
import elements.GuiSkinElement;
|
|
import elements.GuiImage;
|
|
import elements.GuiButton;
|
|
import elements.GuiProgressbar;
|
|
import elements.GuiResources;
|
|
import elements.MarkupTooltip;
|
|
import elements.Gui3DObject;
|
|
import elements.GuiStatusBox;
|
|
import elements.GuiCargoDisplay;
|
|
import biomes;
|
|
import orbitals;
|
|
from obj_selection import isSelected;
|
|
import constructible;
|
|
import util.constructible_view;
|
|
import util.obj_locate;
|
|
import util.icon_view;
|
|
from overlays.ContextMenu import openContextMenu;
|
|
import statuses;
|
|
|
|
const uint CONSTRUCTION_SLIDESHOW_TIMER = 2.0;
|
|
|
|
class PlanetPopup : Popup {
|
|
Constructible[] cons;
|
|
uint consDisp = 0;
|
|
double consDispTimer = 0;
|
|
|
|
GuiText@ name;
|
|
GuiText@ ownerName;
|
|
|
|
array<GuiStatusBox@> statusIcons;
|
|
Gui3DObject@ objView;
|
|
GuiSprite@ defIcon;
|
|
|
|
BaseGuiElement@ popBox;
|
|
GuiSprite@ popIcon;
|
|
GuiText@ popValue;
|
|
|
|
BaseGuiElement@ loyBox;
|
|
GuiSprite@ loyIcon;
|
|
GuiText@ loyValue;
|
|
|
|
GuiResourceGrid@ resources;
|
|
|
|
GuiSkinElement@ statusBox;
|
|
|
|
GuiProgressbar@ health;
|
|
|
|
GuiCargoDisplay@ cargo;
|
|
|
|
Planet@ pl;
|
|
bool selected = false;
|
|
bool showOrbitalConstruction = true;
|
|
double lastUpdate = -INFINITY;
|
|
|
|
PlanetPopup(BaseGuiElement@ parent) {
|
|
super(parent);
|
|
size = vec2i(190, 160);
|
|
|
|
@name = GuiText(this, Alignment(Left+50, Top+6, Right-4, Top+28));
|
|
@ownerName = GuiText(this, Alignment(Left+48, Top+28, Right-6, Top+46));
|
|
ownerName.horizAlign = 1.0;
|
|
|
|
@objView = Gui3DObject(this, Alignment(Left+4, Top+50, Right-4, Top+120));
|
|
|
|
@cargo = GuiCargoDisplay(objView, Alignment(Left, Top, Right, Top+25));
|
|
|
|
@defIcon = GuiSprite(this, Alignment(Left+4, Top+50, Width=40, Height=40));
|
|
defIcon.desc = icons::Defense;
|
|
setMarkupTooltip(defIcon, locale::TT_IS_DEFENDING);
|
|
defIcon.visible = false;
|
|
|
|
GuiSkinElement band(this, Alignment(Left+3, Bottom-35, Right-4, Bottom-2), SS_SubTitle);
|
|
band.color = Color(0xaaaaaaff);
|
|
|
|
@popBox = BaseGuiElement(this, Alignment(Left+3, Bottom-67, Left+50, Bottom-35));
|
|
@popIcon = GuiSprite(popBox, Alignment(Left-12, Top+2, Left+24, Bottom+6));
|
|
popIcon.desc = icons::Population;
|
|
@popValue = GuiText(popBox, Alignment(Left+26, Top+12, Right, Height=20));
|
|
popIcon.tooltip = locale::POPULATION;
|
|
popValue.tooltip = locale::POPULATION;
|
|
|
|
@loyBox = BaseGuiElement(this, Alignment(Right-50, Bottom-67, Right-5, Bottom-35));
|
|
@loyIcon = GuiSprite(loyBox, Alignment(Right-24, Top+8, Right, Bottom-1));
|
|
loyIcon.desc = icons::Loyalty;
|
|
@loyValue = GuiText(loyBox, Alignment(Right-50, Top+12, Right-26, Height=20));
|
|
loyValue.horizAlign = 1.0;
|
|
loyIcon.tooltip = locale::LOYALTY;
|
|
loyValue.tooltip = locale::LOYALTY;
|
|
|
|
@resources = GuiResourceGrid(band, Alignment(Left+4, Top+4, Right-3, Bottom-4));
|
|
|
|
@statusBox = GuiSkinElement(this, Alignment(Right-2, Top, Right+34, Bottom), SS_PlainBox);
|
|
statusBox.noClip = true;
|
|
statusBox.visible = false;
|
|
|
|
@health = GuiProgressbar(this, Alignment(Left+8, Top+53, Right-8, Top+75));
|
|
health.visible = false;
|
|
|
|
auto@ healthIcon = GuiSprite(health, Alignment(Left-8, Top-9, Left+24, Bottom-8), icons::Health);
|
|
healthIcon.noClip = true;
|
|
|
|
updateAbsolutePosition();
|
|
}
|
|
|
|
bool compatible(Object@ obj) {
|
|
return cast<Planet>(obj) !is null;
|
|
}
|
|
|
|
void set(Object@ obj) {
|
|
@pl = cast<Planet>(obj);
|
|
@objView.object = obj;
|
|
@resources.drawFrom = obj;
|
|
lastUpdate = -INFINITY;
|
|
}
|
|
|
|
Object@ get() {
|
|
return pl;
|
|
}
|
|
|
|
void draw() {
|
|
Popup::updatePosition(pl);
|
|
recti bgPos = AbsolutePosition;
|
|
|
|
uint flags = SF_Normal;
|
|
SkinStyle style = isSelectable ? SS_SelectablePopup : SS_PopupBG;
|
|
if(selected)
|
|
flags |= SF_Active;
|
|
if(isSelectable && Hovered)
|
|
flags |= SF_Hovered;
|
|
|
|
Empire@ owner = pl.visibleOwner;
|
|
Color color;
|
|
if(owner !is null) {
|
|
color = owner.color;
|
|
skin.draw(style, flags, bgPos, owner.color);
|
|
if(owner.flag !is null) {
|
|
vec2i s = objView.absolutePosition.size;
|
|
owner.flag.draw(
|
|
objView.absolutePosition
|
|
.resized(s.x*0.5, s.y*0.5, 0.0, 0.0)
|
|
.aspectAligned(1.0, horizAlign=0.0, vertAlign=0.0),
|
|
owner.color * Color(0xffffff40));
|
|
}
|
|
}
|
|
else {
|
|
skin.draw(style, flags, bgPos, Color(0xffffffff));
|
|
}
|
|
|
|
skin.draw(SS_SubTitle, SF_Normal, recti_area(bgPos.topLeft + vec2i(2,2), vec2i(bgPos.width-5, 50-4)), color);
|
|
|
|
if(resources.resources.length != 0)
|
|
drawPlanetIcon(pl, recti_area(bgPos.topLeft+vec2i(2, 2), vec2i(46,46)), resources.resources[0]);
|
|
else
|
|
drawObjectIcon(pl, recti_area(bgPos.topLeft+vec2i(2, 2), vec2i(46,46)));
|
|
|
|
objView.draw();
|
|
|
|
if(cargo.visible)
|
|
drawRectangle(cargo.absolutePosition, Color(0x00000040));
|
|
|
|
//Construction display
|
|
if(cons.length != 0) {
|
|
//Slide through different constructions
|
|
if(consDisp >= cons.length)
|
|
consDisp = 0;
|
|
if(consDispTimer < frameTime) {
|
|
consDispTimer = frameTime + CONSTRUCTION_SLIDESHOW_TIMER;
|
|
consDisp = (consDisp + 1) % cons.length;
|
|
}
|
|
|
|
//Draw the construction
|
|
recti plPos = objView.absolutePosition;
|
|
const Font@ ft = skin.getFont(FT_Small);
|
|
drawConstructible(cons[consDisp], plPos, ft);
|
|
}
|
|
|
|
objView.Visible = false;
|
|
BaseGuiElement::draw();
|
|
objView.Visible = true;
|
|
}
|
|
|
|
bool onGuiEvent(const GuiEvent& evt) {
|
|
switch(evt.type) {
|
|
case GUI_Clicked:
|
|
if(evt.caller is objView) {
|
|
dragging = false;
|
|
if(!dragged) {
|
|
switch(evt.value) {
|
|
case OA_LeftClick:
|
|
emitClicked(PA_Select);
|
|
return true;
|
|
case OA_RightClick:
|
|
openContextMenu(pl);
|
|
return true;
|
|
case OA_MiddleClick:
|
|
emitClicked(PA_Zoom);
|
|
return true;
|
|
case OA_DoubleClick:
|
|
emitClicked(PA_Manage);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return Popup::onGuiEvent(evt);
|
|
}
|
|
|
|
void update() {
|
|
if(frameTime - 0.2 < lastUpdate)
|
|
return;
|
|
if(pl is null)
|
|
return;
|
|
lastUpdate = frameTime;
|
|
|
|
bool owned = pl.owner is playerEmpire;
|
|
auto@ owner = pl.visibleOwner;
|
|
bool colonized = owner !is null && owner.valid;
|
|
if(!isSelectable)
|
|
selected = separated && isSelected(pl);
|
|
const Font@ ft = skin.getFont(FT_Normal);
|
|
|
|
defIcon.visible = playerEmpire.isDefending(pl);
|
|
|
|
//Update planet name
|
|
name.text = pl.name;
|
|
if(ft.getDimension(name.text).x > name.size.width)
|
|
name.font = FT_Detail;
|
|
else
|
|
name.font = FT_Normal;
|
|
|
|
if(colonized && owner !is null) {
|
|
ownerName.color = owner.color;
|
|
ownerName.text = owner.name;
|
|
|
|
if(ft.getDimension(ownerName.text).x > ownerName.size.width)
|
|
ownerName.font = FT_Detail;
|
|
else
|
|
ownerName.font = FT_Normal;
|
|
}
|
|
else {
|
|
ownerName.color = Color(0xaaaaaaff);
|
|
ownerName.text = locale::UNCOLONIZED;
|
|
ownerName.font = FT_Normal;
|
|
}
|
|
|
|
//Update statuses
|
|
{
|
|
array<Status> statuses;
|
|
if(pl.statusEffectCount > 0)
|
|
statuses.syncFrom(pl.getStatusEffects());
|
|
if(!pl.visible) {
|
|
for(uint i = 0, cnt = statuses.length; i < cnt; ++i) {
|
|
if(statuses[i].type.conditionFrequency <= 0 && statuses[i].type.visibility != StV_Global) {
|
|
statuses.removeAt(i);
|
|
--i; --cnt;
|
|
}
|
|
}
|
|
}
|
|
uint prevCnt = statusIcons.length, cnt = statuses.length;
|
|
for(uint i = cnt; i < prevCnt; ++i)
|
|
statusIcons[i].remove();
|
|
statusIcons.length = cnt;
|
|
statusBox.visible = cnt != 0;
|
|
for(uint i = 0; i < cnt; ++i) {
|
|
auto@ icon = statusIcons[i];
|
|
if(icon is null) {
|
|
@icon = GuiStatusBox(statusBox, recti_area(2, 2+32*i, 30, 30));
|
|
icon.noClip = true;
|
|
@statusIcons[i] = icon;
|
|
}
|
|
icon.update(statuses[i]);
|
|
}
|
|
}
|
|
|
|
//Update health
|
|
if(pl.Health < pl.MaxHealth) {
|
|
health.progress = pl.Health / pl.MaxHealth;
|
|
health.frontColor = colors::Red.interpolate(colors::Green, health.progress);
|
|
health.text = standardize(pl.Health)+" / "+standardize(pl.MaxHealth);
|
|
health.visible = true;
|
|
}
|
|
else {
|
|
health.visible = false;
|
|
}
|
|
|
|
//Update resources
|
|
resources.resources.syncFrom(pl.getAllResources());
|
|
resources.resources.sortDesc();
|
|
resources.setSingleMode();
|
|
|
|
//Update cargo
|
|
cargo.visible = pl.cargoTypes > 0;
|
|
if(cargo.visible)
|
|
cargo.update(pl);
|
|
|
|
//Update population display
|
|
if(colonized && owner.HasPopulation != 0) {
|
|
double pop = pl.population, maxPop = pl.maxPopulation;
|
|
if(pop < 1.0)
|
|
popValue.text = toString(pl.population, 1);
|
|
else if(maxPop >= 10.0 || pop >= 10.0)
|
|
popValue.text = toString(pl.population, 0);
|
|
else
|
|
popValue.text = toString(floor(pl.population), 0) + "/" + toString(pl.maxPopulation, 0);
|
|
popValue.color = Color(0xffffffff);
|
|
popValue.visible = true;
|
|
popIcon.visible = true;
|
|
}
|
|
else {
|
|
popValue.visible = false;
|
|
popIcon.visible = false;
|
|
}
|
|
|
|
//Update loyalty display
|
|
if(colonized) {
|
|
loyValue.text = toString(pl.currentLoyalty);
|
|
loyValue.visible = true;
|
|
loyIcon.visible = true;
|
|
}
|
|
else {
|
|
loyValue.visible = false;
|
|
loyIcon.visible = false;
|
|
}
|
|
|
|
//Update construction
|
|
uint consIndex = 0;
|
|
if(owned) {
|
|
if(pl.constructionCount != 0) {
|
|
if(cons.length <= consIndex)
|
|
cons.length = consIndex + 1;
|
|
DataList@ list = pl.getConstructionQueue(1);
|
|
receive(list, cons[consIndex]);
|
|
++consIndex;
|
|
}
|
|
}
|
|
|
|
if(cons.length > consIndex)
|
|
cons.length = consIndex;
|
|
|
|
Popup::update();
|
|
Popup::updatePosition(pl);
|
|
}
|
|
};
|