Open source Star Ruler 2 source code!
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user