327 lines
6.8 KiB
ActionScript
327 lines
6.8 KiB
ActionScript
import resources;
|
|
import constructible;
|
|
import bool getCheatsEverOn() from "cheats";
|
|
#include "include/resource_constants.as"
|
|
|
|
enum ConstructionCapability {
|
|
CC_Ship = 0x1,
|
|
CC_Orbital = 0x2,
|
|
CC_Asteroid = 0x4,
|
|
CC_Terraform = 0x8,
|
|
CC_Supports = 0x10,
|
|
};
|
|
|
|
tidy class Construction : Component_Construction {
|
|
Constructible[] queue;
|
|
uint capabilities = 0;
|
|
bool buildingSupport = false;
|
|
|
|
double LaborIncome = 0;
|
|
double LaborFactor = 0;
|
|
double DistributedLabor = 0;
|
|
|
|
double laborStorage = 0;
|
|
double storedLabor = 0;
|
|
|
|
bool canExport = true;
|
|
bool canImport = false;
|
|
|
|
int nextID = 0;
|
|
int supportSpeed = 100;
|
|
int shipCost = 100;
|
|
int orbitalCost = 100;
|
|
double orbitalMaint = 1.0;
|
|
double terraformCost = 1.0;
|
|
double constructionCost = 1.0;
|
|
|
|
bool rally = false;
|
|
bool repeating = false;
|
|
Object@ rallyObj;
|
|
vec3d rallyPoint;
|
|
|
|
double get_constructionCostMod() const {
|
|
return constructionCost;
|
|
}
|
|
|
|
bool get_canBuildSupports() {
|
|
return capabilities & CC_Supports != 0;
|
|
}
|
|
|
|
bool get_canBuildShips() {
|
|
return capabilities & CC_Ship != 0;
|
|
}
|
|
|
|
bool get_canBuildOrbitals() {
|
|
return capabilities & CC_Orbital != 0;
|
|
}
|
|
|
|
bool get_canBuildAsteroids() {
|
|
return capabilities & CC_Asteroid != 0;
|
|
}
|
|
|
|
bool get_canTerraform() {
|
|
return capabilities & CC_Terraform != 0;
|
|
}
|
|
|
|
bool get_canExportLabor() {
|
|
return canExport;
|
|
}
|
|
|
|
bool get_canImportLabor() {
|
|
return canImport;
|
|
}
|
|
|
|
double get_terraformCostMod() const {
|
|
return terraformCost;
|
|
}
|
|
|
|
uint get_constructionCount() const {
|
|
return queue.length;
|
|
}
|
|
|
|
bool get_constructingSupport() const {
|
|
return buildingSupport;
|
|
}
|
|
|
|
double get_laborIncome() const {
|
|
return LaborIncome * LaborFactor;
|
|
}
|
|
|
|
bool get_isRepeating() const {
|
|
return repeating;
|
|
}
|
|
|
|
int constructibleIndex(int id) {
|
|
for(uint i = 0, cnt = queue.length; i < cnt; ++i)
|
|
if(queue[i].id == id)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
string get_constructionName(uint num) {
|
|
if(num >= queue.length)
|
|
return "(null)";
|
|
return queue[num].name;
|
|
}
|
|
|
|
float get_constructionProgress() const {
|
|
if(queue.length == 0)
|
|
return -1.f;
|
|
if(queue[0].totalLabor <= 0)
|
|
return 1.f;
|
|
return queue[0].curLabor / queue[0].totalLabor;
|
|
}
|
|
|
|
int get_supportBuildSpeed(const Object& obj) const {
|
|
int cost = 100;
|
|
cost = max(10, cost + (supportSpeed - 100));
|
|
return cost;
|
|
}
|
|
|
|
int get_shipBuildCost(const Object& obj) const {
|
|
int cost = 100;
|
|
cost = max(10, cost + (shipCost - 100));
|
|
return cost;
|
|
}
|
|
|
|
int get_orbitalBuildCost(const Object& obj) const {
|
|
int cost = 100;
|
|
cost = max(10, cost + (orbitalCost - 100));
|
|
return cost;
|
|
}
|
|
|
|
double get_orbitalMaintenanceMod(const Object& obj) const {
|
|
double cost = 1.0;
|
|
cost *= clamp(orbitalMaint, 0.01f, 1.f);
|
|
return cost;
|
|
}
|
|
|
|
void getConstructionQueue() {
|
|
for(uint i = 0, cnt = queue.length; i < cnt; ++i)
|
|
yield(queue[i]);
|
|
}
|
|
|
|
void getConstructionQueue(uint limit) {
|
|
for(uint i = 0, cnt = min(queue.length, limit); i < cnt; ++i)
|
|
yield(queue[i]);
|
|
}
|
|
|
|
const Design@ get_constructionDesign() const {
|
|
if(queue.length == 0)
|
|
return null;
|
|
const Constructible@ top = queue[0];
|
|
if(top.dsg !is null)
|
|
return top.dsg;
|
|
return null;
|
|
}
|
|
|
|
void cancelConstruction(Object& obj, int id) {
|
|
int index = constructibleIndex(id);
|
|
if(index == -1)
|
|
return;
|
|
queue.removeAt(index);
|
|
}
|
|
|
|
void queueConstructible(Object& obj, Constructible@ cons) {
|
|
cons.id = nextID++;
|
|
queue.insertLast(cons);
|
|
if(queue.length == 1)
|
|
cons.started = true;
|
|
}
|
|
|
|
void moveConstruction(Object& obj, int id, int beforeId = -1) {
|
|
int myIndex = constructibleIndex(id);
|
|
if(myIndex == -1)
|
|
return;
|
|
int dropIndex = constructibleIndex(beforeId);
|
|
if(dropIndex == -1) {
|
|
queue.insertLast(queue[myIndex]);
|
|
queue.removeAt(myIndex);
|
|
}
|
|
else {
|
|
Constructible@ copy = queue[myIndex];
|
|
queue.removeAt(myIndex);
|
|
if(myIndex < dropIndex)
|
|
--dropIndex;
|
|
queue.insertAt(dropIndex, copy);
|
|
}
|
|
}
|
|
|
|
void buildOrbital(Object& obj, int type) {
|
|
/*if(capabilities & CC_Orbital == 0)*/
|
|
/* return;*/
|
|
/*const OrbitalDef@ def = getOrbitalDef(type);*/
|
|
/*Constructible cons;*/
|
|
/*cons.type = CT_Orbital;*/
|
|
/*@cons.orbital = def;*/
|
|
/*cons.buildCost = def.buildCost;*/
|
|
/*cons.totalLabor = def.laborCost;*/
|
|
/*cons.buildCost = ceil(double(cons.buildCost) * double(get_orbitalBuildCost(obj)) / 100.0);*/
|
|
|
|
/*if(def !is null)*/
|
|
/* queueConstructible(obj, cons);*/
|
|
}
|
|
|
|
void buildFlagship(Object& obj, const Design@ design) {
|
|
if(capabilities & CC_Ship == 0)
|
|
return;
|
|
if(design is null || design.hasTag(ST_IsSupport)) {
|
|
error("Invalid design for ship construction at " + obj.name);
|
|
return;
|
|
}
|
|
|
|
Constructible@ cons = Constructible(design);
|
|
getBuildCost(design, cons.buildCost, cons.maintainCost, cons.totalLabor, 1);
|
|
cons.buildCost = ceil(double(cons.buildCost) * double(get_shipBuildCost(obj)) / 100.0);
|
|
queueConstructible(obj, cons);
|
|
}
|
|
|
|
void clearRally() {
|
|
rally = false;
|
|
@rallyObj = null;
|
|
}
|
|
|
|
void rallyTo(Object& obj, Object@ dest) {
|
|
if(dest is null || !dest.valid || !dest.isVisibleTo(obj.owner))
|
|
clearRally();
|
|
rally = true;
|
|
@rallyObj = dest;
|
|
rallyPoint = dest.position;
|
|
}
|
|
|
|
void rallyTo(vec3d position) {
|
|
rally = true;
|
|
rallyPoint = position;
|
|
}
|
|
|
|
bool get_isRallying() {
|
|
return rally;
|
|
}
|
|
|
|
vec3d get_rallyPosition() {
|
|
return rallyPoint;
|
|
}
|
|
|
|
Object@ get_rallyObject() {
|
|
return rallyObj;
|
|
}
|
|
|
|
double get_laborStorageCapacity() const {
|
|
return laborStorage;
|
|
}
|
|
|
|
double get_currentLaborStored() const {
|
|
return storedLabor;
|
|
}
|
|
|
|
void constructionTick(Object& obj, double time) {
|
|
if(rally && rallyObj !is null && rallyObj.isVisibleTo(obj.owner))
|
|
rallyPoint = rallyObj.position;
|
|
|
|
if(laborIncome >= LABOR_ACHIEVE_THRESH && obj.owner is playerEmpire && !getCheatsEverOn())
|
|
unlockAchievement("ACH_LABOR200");
|
|
}
|
|
|
|
void readConstructionDelta(Message& msg) {
|
|
if(msg.readBit()) {
|
|
readConstruction(msg);
|
|
}
|
|
else {
|
|
if(msg.readBit()) {
|
|
laborStorage = msg.read_float();
|
|
storedLabor = msg.read_float();
|
|
if(msg.readBit())
|
|
return;
|
|
}
|
|
|
|
if(queue.length == 0)
|
|
queue.length = 1;
|
|
queue[0].read(msg);
|
|
}
|
|
}
|
|
|
|
void readCommon(Message& msg) {
|
|
}
|
|
|
|
void readConstruction(Message& msg) {
|
|
uint cnt = msg.readSmall();
|
|
queue.length = cnt;
|
|
|
|
for(uint i = 0; i < cnt; ++i)
|
|
queue[i].read(msg);
|
|
if(cnt > 0)
|
|
nextID = queue[cnt-1].id + 1;
|
|
|
|
msg >> rally;
|
|
if(rally) {
|
|
if(msg.readBit()) {
|
|
msg >> rallyObj;
|
|
rallyPoint = rallyObj.position;
|
|
}
|
|
else {
|
|
rallyPoint = msg.readMedVec3();
|
|
}
|
|
}
|
|
|
|
msg >> capabilities;
|
|
msg >> repeating;
|
|
msg >> buildingSupport;
|
|
|
|
LaborIncome = msg.read_float();
|
|
LaborFactor = msg.read_float();
|
|
DistributedLabor = msg.read_float();
|
|
constructionCost = msg.read_float();
|
|
msg >> canExport;
|
|
msg >> canImport;
|
|
|
|
msg >> supportSpeed;
|
|
msg >> shipCost;
|
|
msg >> orbitalCost;
|
|
terraformCost = msg.read_float();
|
|
orbitalMaint = msg.read_float();
|
|
|
|
laborStorage = msg.read_float();
|
|
storedLabor = msg.read_float();
|
|
}
|
|
}
|