376 lines
9.9 KiB
ActionScript
376 lines
9.9 KiB
ActionScript
import resources;
|
|
import planet_types;
|
|
import util.convar;
|
|
import nodes.StrategicIcon;
|
|
import planet_levels;
|
|
|
|
const double APPROACH_EPSILON = 0.002;
|
|
const double OUTSIDE_DISTANCE = 12000.0;
|
|
const double OUTSIDE_SIZE_MAX = 25000.0;
|
|
const double ANIMATE_TIME = 0.45;
|
|
const double GRAVITY_DISC_MAX_DIST = 1000.0;
|
|
|
|
const double FADE_DIST_MIN = 250;
|
|
const double FADE_DIST_MAX = 300;
|
|
const double VERY_DISTANT_START = 56000.0;
|
|
const double VERY_DISTANT_END = 80000.0;
|
|
|
|
vec4f DISABLE_NORMAL, DISABLE_POPULATION;
|
|
|
|
ConVar PlanetIconSize("planet_icon_size", 0.0225);
|
|
ConVar PlanetResourceSize("planet_resource_size", 0.4);
|
|
ConVar PlanetTypeSize("planet_type_size", 0.7);
|
|
ConVar PlanetSelectedSize("planet_selected_size", 1.0);
|
|
const ResourceClass@ foodClass;
|
|
const ResourceClass@ scalableClass;
|
|
|
|
void init() {
|
|
@foodClass = getResourceClass("Food");
|
|
@scalableClass = getResourceClass("Scalable");
|
|
|
|
colors::Red.toVec4(DISABLE_NORMAL);
|
|
Color(0xff6300ff).toVec4(DISABLE_POPULATION);
|
|
}
|
|
|
|
bool SHOW_PLANET_PLANES = true;
|
|
bool SHOW_PLANET_ICONS = true;
|
|
|
|
void setPlanetPlanesShown(bool enabled) {
|
|
SHOW_PLANET_PLANES = enabled;
|
|
}
|
|
|
|
bool getPlanetPlanesShown() {
|
|
return SHOW_PLANET_PLANES;
|
|
}
|
|
|
|
void setPlanetIconsShown(bool enabled) {
|
|
SHOW_PLANET_ICONS = enabled;
|
|
}
|
|
|
|
bool getPlanetIconsShown() {
|
|
return SHOW_PLANET_ICONS;
|
|
}
|
|
|
|
final class PlanetIconNodeScript : StrategicIcon {
|
|
Planet@ pl;
|
|
uint level;
|
|
uint typeIcon;
|
|
uint resourceIcon = uint(-1);
|
|
ResourceSheet@ rs;
|
|
const Material@ levelMat, flag;
|
|
vec4f disableColor;
|
|
Color color;
|
|
const ResourceType@ type;
|
|
|
|
Empire@ captureEmp;
|
|
float capturePct = 0.f;
|
|
|
|
float resourceClass = -1.f;
|
|
bool plane = false;
|
|
bool isPlayer = false;
|
|
bool isDisabled = true;
|
|
bool isExported = false;
|
|
bool isMaterial = false;
|
|
bool isDecaying = false;
|
|
bool isBeingColonized = false;
|
|
bool isMemory = false;
|
|
bool isLowPop = false;
|
|
|
|
PlanetIconNodeScript(Node& node) {
|
|
node.visible = false;
|
|
super(node);
|
|
}
|
|
|
|
void establish(Node& node, Planet& planet) {
|
|
@pl = planet;
|
|
typeIcon = getPlanetType(planet.PlanetType).distantIcon.index;
|
|
@node.object = planet;
|
|
node.position = planet.position;
|
|
node.rebuildTransform();
|
|
}
|
|
|
|
void setOwner(Empire@ owner) {
|
|
if(owner !is null && owner.valid) {
|
|
color = owner.color;
|
|
@flag = owner.flag;
|
|
isPlayer = true;
|
|
}
|
|
else {
|
|
color = Color(0xb0b0b0ff);
|
|
isPlayer = false;
|
|
}
|
|
}
|
|
|
|
void setLevel(uint lvl) {
|
|
level = lvl;
|
|
if(rs !is null) {
|
|
@levelMat = rs.getMaterial(level);
|
|
}
|
|
else switch(level) {
|
|
case 0: @levelMat = material::PlanetLevel0; break;
|
|
case 1: @levelMat = material::PlanetLevel1; break;
|
|
case 2: @levelMat = material::PlanetLevel2; break;
|
|
case 3: @levelMat = material::PlanetLevel3; break;
|
|
case 4: @levelMat = material::PlanetLevel4; break;
|
|
case 5: default: @levelMat = material::PlanetLevel5; break;
|
|
}
|
|
}
|
|
|
|
void setResource(uint id) {
|
|
@type = getResource(id);
|
|
if(type is null) {
|
|
resourceIcon = uint(-1);
|
|
resourceClass = -1.f;
|
|
}
|
|
else {
|
|
@rs = type.distantSheet;
|
|
resourceIcon = type.smallIcon.index;
|
|
if(type.level > 0 && type.level <= 3)
|
|
resourceClass = 3.f + float(type.level);
|
|
else if(type.cls is foodClass)
|
|
resourceClass = 7.f;
|
|
else if(type.cls is scalableClass)
|
|
resourceClass = 16.f;
|
|
else
|
|
resourceClass = -1.f;
|
|
}
|
|
setLevel(level);
|
|
}
|
|
|
|
void setState(bool dis, bool exp, bool mat, bool decay) {
|
|
isDisabled = dis;
|
|
isExported = exp;
|
|
isMaterial = mat;
|
|
isDecaying = decay;
|
|
}
|
|
|
|
void setBeingColonized(bool value) {
|
|
isBeingColonized = value;
|
|
}
|
|
|
|
void setCapture(Empire@ emp, float pct) {
|
|
@captureEmp = emp;
|
|
capturePct = pct;
|
|
}
|
|
|
|
bool preRender(Node& node) {
|
|
if(!SHOW_PLANET_ICONS && !SHOW_PLANET_PLANES)
|
|
return false;
|
|
if(pl is null)
|
|
return false;
|
|
|
|
isMemory = false;
|
|
|
|
{
|
|
if(pl.visible) {
|
|
node.visible = true;
|
|
}
|
|
else if(pl.known) {
|
|
isMemory = true;
|
|
node.visible = true;
|
|
}
|
|
else if(!node.visible) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if(!isMemory) {
|
|
Empire@ owner = pl.owner;
|
|
if(owner !is null && owner.valid) {
|
|
color = owner.color;
|
|
isPlayer = true;
|
|
}
|
|
else {
|
|
color = Color(0xb0b0b0ff);
|
|
isPlayer = false;
|
|
}
|
|
}
|
|
|
|
double dist = node.sortDistance * config::GFX_DISTANCE_MOD;
|
|
plane = dist < GRAVITY_DISC_MAX_DIST;
|
|
|
|
vec3d plPos = pl.node_position;
|
|
StrategicIcon::update(node, plPos, PlanetIconSize.value,
|
|
OUTSIDE_DISTANCE, OUTSIDE_SIZE_MAX, ANIMATE_TIME,
|
|
FADE_DIST_MIN * 10, FADE_DIST_MAX * 10);
|
|
|
|
if(pl.owner is playerEmpire) {
|
|
if(isDisabled) {
|
|
isLowPop = false;
|
|
if(type is null) {
|
|
disableColor = DISABLE_NORMAL;
|
|
}
|
|
else {
|
|
if(pl.resourceLevel >= type.level &&
|
|
pl.population < getPlanetLevelRequiredPop(pl, type.level)) {
|
|
disableColor = DISABLE_POPULATION;
|
|
}
|
|
else {
|
|
disableColor = DISABLE_NORMAL;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
isLowPop = pl.resourceLevel > pl.level;
|
|
disableColor = DISABLE_POPULATION;
|
|
}
|
|
}
|
|
|
|
if(isMemory)
|
|
alpha *= 0.7f;
|
|
|
|
return true;
|
|
}
|
|
|
|
void render(Node& node) {
|
|
Empire@ owner = pl.owner;
|
|
Color col = color;
|
|
col.a = alpha * 255;
|
|
|
|
double dist = node.sortDistance * config::GFX_DISTANCE_MOD;
|
|
float iconFade = 1.0;
|
|
if(dist > VERY_DISTANT_START) {
|
|
iconFade = float(clamp(1.0 - ((dist - VERY_DISTANT_START) / (VERY_DISTANT_END - VERY_DISTANT_START)), 0.0, 1.0));
|
|
|
|
//Distant planet icons are very simple and more numerous, so we check for that first
|
|
if(iconFade < 0.01) {
|
|
if(pl.selected) {
|
|
Color scol(0xffffffff);
|
|
scol.a = col.a;
|
|
|
|
renderBillboard(material::DistantPlanetSelected, node.abs_position,
|
|
node.abs_scale * 2.0 * PlanetSelectedSize.value, 0, scol);
|
|
shader::APPROACH += APPROACH_EPSILON;
|
|
}
|
|
renderBillboard(material::FadedPlanet, node.abs_position, node.abs_scale * 2.0, 0, col);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//Capturing stuff
|
|
if(captureEmp !is null && !isMemory) {
|
|
captureEmp.color.toVec4(shader::CAPTURE_COLOR);
|
|
shader::CAPTURE_PROGRESS = capturePct;
|
|
}
|
|
else if(pl.Population < 1.0 && !isMemory) {
|
|
shader::CAPTURE_PROGRESS = pl.Population;
|
|
owner.color.toVec4(shader::CAPTURE_COLOR);
|
|
}
|
|
else if(isDecaying) {
|
|
shader::CAPTURE_PROGRESS = pl.decayTime / (config::LEVEL_DECAY_TIMER / owner.PlanetDecaySpeed);
|
|
float pct = abs((frameTime % 1.0) - 0.5f) * 2.f;
|
|
colors::Red.interpolate(colors::Orange, pct).toVec4(shader::CAPTURE_COLOR);
|
|
}
|
|
else {
|
|
shader::CAPTURE_COLOR = vec4f();
|
|
}
|
|
|
|
double orbitCircleFadeIn = FADE_DIST_MAX * 10;
|
|
|
|
//Draw the orbit plane
|
|
if(dist < orbitCircleFadeIn && dist > 100.0 && SHOW_PLANET_PLANES) {
|
|
double orbitSize = pl.OrbitSize;
|
|
shader::CIRCLE_MIN = (pl.radius + 0.5f) / orbitSize;
|
|
shader::CIRCLE_MAX = 1.f;
|
|
Color orbitColor(0xffffff05);
|
|
|
|
|
|
double orbitCircleFadeOut = FADE_DIST_MIN * 10;
|
|
|
|
double a = 0.025;
|
|
if(pl.selected)
|
|
a = 0.035;
|
|
else if(dist < 250.0)
|
|
a *= (dist - 150.0) / 100.0;
|
|
else if(dist > orbitCircleFadeOut)
|
|
a *= 1.0 - (dist - orbitCircleFadeOut) / (orbitCircleFadeIn - orbitCircleFadeOut);
|
|
|
|
if(a <= 0.0)
|
|
orbitColor.a = 0;
|
|
else if(a >= 1.0)
|
|
orbitColor.a = 255;
|
|
else
|
|
orbitColor.a = uint8(a * 255.0);
|
|
|
|
vec3d center = node.abs_position;
|
|
if(orbitColor.a > 0)
|
|
renderPlane(material::OrbitCircle, center, orbitSize, orbitColor);
|
|
|
|
float prevA = shader::CAPTURE_COLOR.w;
|
|
Color flagColor = color;
|
|
if(isPlayer && dist > 150.0 && dist < 1850.0) {
|
|
//NOTE: The node can be setup before the empire has a flag specified
|
|
if(flag is null)
|
|
@flag = owner.flag;
|
|
flagColor.a = min(a * (6.0 * 255.0) * (1.0 - (dist - 150.0) / 1700.0), 255.0);
|
|
if(prevA > 0.f)
|
|
shader::CAPTURE_COLOR.w = float(flagColor.a) / 255.f * 1.5f;
|
|
}
|
|
else {
|
|
flagColor.a = 0;
|
|
shader::CAPTURE_COLOR.w = 0.f;
|
|
}
|
|
|
|
if(flagColor.a > 4) {
|
|
center.y += 0.1;
|
|
shader::CAPTURE_COLOR.w = float(flagColor.a) / 255.f;
|
|
|
|
renderPlane(flag, center + vec3d(orbitSize * -0.9, 0.0, 0.0), orbitSize * 0.1, flagColor, pi * 0.5);
|
|
renderPlane(flag, center + vec3d(orbitSize * 0.9, 0.0, 0.0), orbitSize * 0.1, flagColor, pi * 1.5);
|
|
renderPlane(flag, center + vec3d(0.0, 0.0, orbitSize * 0.9), orbitSize * 0.1, flagColor, 0.0);
|
|
renderPlane(flag, center + vec3d(0.0, 0.0, orbitSize * -0.9), orbitSize * 0.1, flagColor, pi);
|
|
}
|
|
shader::CAPTURE_COLOR.w = prevA;
|
|
}
|
|
|
|
if(col.a > 2 && SHOW_PLANET_ICONS) {
|
|
//Draw selected border
|
|
shader::APPROACH = APPROACH_EPSILON * (col.a != 255 ? -8.0 : 1.0);
|
|
if(pl.selected) {
|
|
Color scol(0xffffffff);
|
|
scol.a = col.a;
|
|
|
|
renderBillboard(material::DistantPlanetSelected, node.abs_position,
|
|
node.abs_scale * 2.0 * PlanetSelectedSize.value, 0, scol);
|
|
shader::APPROACH += APPROACH_EPSILON;
|
|
}
|
|
|
|
shader::DISTANT_SPRITE_FADE = iconFade;
|
|
|
|
spritesheet::DistantPlanetType.getSourceUV(typeIcon, shader::DISTANT_SPRITE1);
|
|
|
|
if(rs !is null)
|
|
rs.getUV(resourceIcon, shader::DISTANT_SPRITE2);
|
|
else if(resourceIcon < 0xffffffff)
|
|
spritesheet::ResourceIconsSmall.getSourceUV(resourceIcon, shader::DISTANT_SPRITE2);
|
|
else
|
|
shader::DISTANT_SPRITE2 = vec4f();
|
|
|
|
//Draw planet level icon
|
|
shader::DISTANT_SPRITE_SCALE1 = PlanetTypeSize.value;
|
|
shader::DISTANT_SPRITE_SCALE2 = PlanetResourceSize.value;
|
|
shader::IS_COLONIZING = isBeingColonized ? 1.f : 0.f;
|
|
shader::IS_OWNED = (isPlayer && levelMat !is null) ? 1.f : 0.f;
|
|
shader::IS_EXPORTED = isExported ? 1.f : 0.f;
|
|
shader::IS_DECAYING = isDecaying ? 1.f : 0.f;
|
|
shader::RESOURCE_CLASS = resourceClass;
|
|
|
|
if(owner is playerEmpire) {
|
|
shader::IS_DISABLED = (isDisabled || isLowPop) ? 1.f : 0.f;
|
|
shader::IS_USED = (isMaterial || isDisabled || isDecaying || isLowPop) ? 1.f : 0.f;
|
|
if(isDisabled || isLowPop)
|
|
shader::DISABLE_COLOR = disableColor;
|
|
}
|
|
else {
|
|
shader::IS_DISABLED = 0.f;
|
|
shader::IS_USED = 1.f;
|
|
}
|
|
|
|
if(levelMat is null)
|
|
renderBillboard(material::PlanetLevel0, node.abs_position, node.abs_scale * 2.0, 0, col);
|
|
else
|
|
renderBillboard(levelMat, node.abs_position, node.abs_scale * 2.0, 0, col);
|
|
}
|
|
}
|
|
};
|