Open source Star Ruler 2 source code!
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
export StrategicIcon;
|
||||
|
||||
bool SHOW_STRATEGIC_ICONS = true;
|
||||
|
||||
bool getStrategicIconsShown() {
|
||||
return SHOW_STRATEGIC_ICONS;
|
||||
}
|
||||
|
||||
void setStrategicIconsShown(bool enabled) {
|
||||
SHOW_STRATEGIC_ICONS = enabled;
|
||||
}
|
||||
|
||||
const double POS_CHANGE_THRES = 1000.0;
|
||||
class StrategicIcon {
|
||||
double animate_pct = 0;
|
||||
float lastDist = -1e10f;
|
||||
float alpha = 1.f;
|
||||
vec3d strategicPos;
|
||||
vec3d originPos;
|
||||
vec3d animPos;
|
||||
bool wasVisible = false;
|
||||
|
||||
StrategicIcon(Node& node) {
|
||||
node.transparent = true;
|
||||
node.fixedSize = true;
|
||||
node.needsTransform = false;
|
||||
node.createPhysics();
|
||||
}
|
||||
|
||||
void setStrategic(Node& node, vec3d position, vec3d origin) {
|
||||
if(animate_pct > 0 && animate_pct < 1)
|
||||
return;
|
||||
|
||||
if(wasVisible && animate_pct >= 1 && strategicPos.distanceToSQ(position) > POS_CHANGE_THRES) {
|
||||
animPos = strategicPos;
|
||||
animate_pct = 0;
|
||||
}
|
||||
strategicPos = position;
|
||||
originPos = origin;
|
||||
}
|
||||
|
||||
void clearStrategic() {
|
||||
originPos = vec3d();
|
||||
strategicPos = vec3d();
|
||||
}
|
||||
|
||||
void update(Node& node, const vec3d& realPos, double SIZE, double OUTSIDE_DISTANCE, double OUTSIDE_SIZE_MAX,
|
||||
double ANIMATE_TIME, double FADE_DIST_MIN, double FADE_DIST_MAX)
|
||||
{
|
||||
vec3d real = animPos.zero ? realPos : animPos;
|
||||
vec3d origin = originPos.zero ? real : originPos;
|
||||
vec3d strategic = strategicPos.zero ? real : strategicPos;
|
||||
|
||||
//Figure out animation state
|
||||
double originDist = getCameraDistance(origin) * config::GFX_DISTANCE_MOD;
|
||||
double dist = node.sortDistance * config::GFX_DISTANCE_MOD;
|
||||
if(abs(dist - lastDist) > OUTSIDE_DISTANCE / 2 || !wasVisible) {
|
||||
//Snap when changing distance rapidly
|
||||
if(originDist > OUTSIDE_DISTANCE)
|
||||
animate_pct = 1.f;
|
||||
else
|
||||
animate_pct = 0.f;
|
||||
}
|
||||
else {
|
||||
//Animate moving to the edge of the system
|
||||
if(originDist > OUTSIDE_DISTANCE)
|
||||
animate_pct = min(animate_pct + frameLength / ANIMATE_TIME, 1.0);
|
||||
else
|
||||
animate_pct = max(0.0, animate_pct - frameLength / ANIMATE_TIME);
|
||||
}
|
||||
|
||||
//Do fading
|
||||
if(dist < FADE_DIST_MAX) {
|
||||
if(dist < FADE_DIST_MIN)
|
||||
alpha = 0.f;
|
||||
else
|
||||
alpha = (dist - FADE_DIST_MIN) / (FADE_DIST_MAX - FADE_DIST_MIN);
|
||||
}
|
||||
else {
|
||||
alpha = 1.f;
|
||||
}
|
||||
|
||||
//Figure out animated position and size
|
||||
vec3d pos;
|
||||
double width;
|
||||
if(animate_pct > 0) {
|
||||
pos = real.interpolate(strategic, animate_pct);
|
||||
width = SIZE * min(node.sortDistance, OUTSIDE_SIZE_MAX / config::GFX_DISTANCE_MOD) / (pixelSizeRatio / uiScale);
|
||||
|
||||
if(animate_pct >= 1)
|
||||
animPos = vec3d();
|
||||
}
|
||||
else {
|
||||
pos = real;
|
||||
width = SIZE * node.sortDistance / (pixelSizeRatio / uiScale);
|
||||
}
|
||||
|
||||
wasVisible = true;
|
||||
|
||||
if(node.position != pos || node.scale != width) {
|
||||
node.scale = width;
|
||||
node.position = pos;
|
||||
node.rebuildTransform();
|
||||
}
|
||||
lastDist = dist;
|
||||
}
|
||||
};
|
||||
|
||||
const double OUTSIDE_DISTANCE = 12000.0;
|
||||
const double OUTSIDE_SIZE_MAX = 25000.0;
|
||||
const double ANIMATE_TIME = 0.45;
|
||||
|
||||
const double FADE_DIST_MIN = 750;
|
||||
const double FADE_DIST_MAX = 1000;
|
||||
|
||||
class StrategicIconNodeScript : StrategicIcon {
|
||||
bool ownerColor = true;
|
||||
Object@ object;
|
||||
const SpriteSheet@ sheet;
|
||||
const Material@ mat;
|
||||
uint icon;
|
||||
Color color;
|
||||
double size;
|
||||
Region@ region;
|
||||
|
||||
StrategicIconNodeScript(Node& node) {
|
||||
node.transparent = true;
|
||||
node.visible = false;
|
||||
node.needsTransform = false;
|
||||
node.fixedSize = true;
|
||||
node.createPhysics();
|
||||
super(node);
|
||||
}
|
||||
|
||||
void establish(Node& node, Object@ obj, double Size, const SpriteSheet& sht, uint index) {
|
||||
@sheet = sht;
|
||||
icon = index;
|
||||
size = Size;
|
||||
establish(node, obj);
|
||||
}
|
||||
|
||||
void establish(Node& node, Object@ obj, double Size, const Material& material) {
|
||||
@mat = material;
|
||||
icon = 0;
|
||||
size = Size;
|
||||
establish(node, obj);
|
||||
}
|
||||
|
||||
void establish(Node& node, Object@ obj) {
|
||||
@node.object = obj;
|
||||
@object = obj;
|
||||
@region = obj.region;
|
||||
node.hintParentObject(region, false);
|
||||
node.position = obj.position;
|
||||
node.rebuildTransform();
|
||||
}
|
||||
|
||||
void setColor(Node& node, uint col) {
|
||||
ownerColor = false;
|
||||
color = Color(col);
|
||||
node.color = Colorf(color);
|
||||
}
|
||||
|
||||
void clearColor() {
|
||||
ownerColor = true;
|
||||
}
|
||||
|
||||
bool preRender(Node& node) {
|
||||
if(object is null)
|
||||
return false;
|
||||
|
||||
double objDist = getCameraDistance(object.position);
|
||||
double fadeDist = 1.0e4 * max(5.0, object.radius);
|
||||
if(objDist > fadeDist)
|
||||
return false;
|
||||
|
||||
bool isMemory = false;
|
||||
if(object.visible) {
|
||||
node.visible = true;
|
||||
}
|
||||
else if(node.memorable && object.known) {
|
||||
node.visible = true;
|
||||
isMemory = true;
|
||||
}
|
||||
else if(!node.visible) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(object.region !is region) {
|
||||
@region = object.region;
|
||||
node.hintParentObject(region, false);
|
||||
}
|
||||
|
||||
double dist = node.sortDistance * config::GFX_DISTANCE_MOD;
|
||||
|
||||
StrategicIcon::update(node, object.node_position, size,
|
||||
OUTSIDE_DISTANCE, OUTSIDE_SIZE_MAX, ANIMATE_TIME,
|
||||
FADE_DIST_MIN, FADE_DIST_MAX);
|
||||
|
||||
if(isMemory)
|
||||
alpha *= 0.7f;
|
||||
if(objDist > 0.8 * fadeDist)
|
||||
alpha *= 1.0 - (objDist - 0.8 * fadeDist) / (0.2 * fadeDist);
|
||||
|
||||
if(alpha < 0.004f || !SHOW_STRATEGIC_ICONS)
|
||||
return false;
|
||||
|
||||
node.color.a = alpha;
|
||||
if(ownerColor) {
|
||||
Empire@ owner = object.owner;
|
||||
if(owner !is null) {
|
||||
color = owner.color;
|
||||
color.a = 0xff * alpha;
|
||||
node.color = Colorf(color);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void render(Node& node) {
|
||||
if(sheet !is null)
|
||||
renderBillboard(sheet, icon, node.abs_position, node.scale, 0, color);
|
||||
else if(mat !is null)
|
||||
renderBillboard(mat, node.abs_position, node.scale, 0, color);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user