256 lines
5.4 KiB
ActionScript
256 lines
5.4 KiB
ActionScript
import construction.Constructible;
|
|
import resources;
|
|
import object_creation;
|
|
import ship_groups;
|
|
import cargo;
|
|
|
|
tidy class ShipConstructible : Constructible {
|
|
const Design@ design;
|
|
array<GroupData@> supports;
|
|
double savedLabor = 0;
|
|
Object@ constructFrom;
|
|
|
|
ShipConstructible(const Design@ Design) {
|
|
if(Design.outdated)
|
|
@Design = Design.owner.updateDesign(Design, true);
|
|
@design = Design;
|
|
getBuildCost(design, buildCost, maintainCost, totalLabor, 1);
|
|
}
|
|
|
|
ShipConstructible(SaveFile& msg) {
|
|
Constructible::load(msg);
|
|
|
|
uint dsgId = 0;
|
|
Empire@ owner;
|
|
msg >> owner;
|
|
msg >> dsgId;
|
|
@design = owner.getDesign(dsgId);
|
|
|
|
if(msg >= SV_0149)
|
|
msg >> constructFrom;
|
|
|
|
uint cnt = 0;
|
|
msg >> cnt;
|
|
supports.length = cnt;
|
|
for(uint i = 0; i < cnt; ++i) {
|
|
GroupData dat;
|
|
msg >> dat;
|
|
@supports[i] = dat;
|
|
}
|
|
msg >> savedLabor;
|
|
}
|
|
|
|
void save(SaveFile& msg) {
|
|
Constructible::save(msg);
|
|
msg << design.owner;
|
|
msg << design.id;
|
|
msg << constructFrom;
|
|
|
|
uint cnt = supports.length;
|
|
msg << cnt;
|
|
for(uint i = 0; i < cnt; ++i)
|
|
msg << supports[i];
|
|
msg << savedLabor;
|
|
}
|
|
|
|
bool pay(Object& obj) {
|
|
if(!payDesignCosts(obj, design))
|
|
return false;
|
|
if(!Constructible::pay(obj)) {
|
|
reverseDesignCosts(obj, design);
|
|
return false;
|
|
}
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i)
|
|
supports[i].orderCycle = obj.owner.BudgetCycleId;
|
|
return true;
|
|
}
|
|
|
|
bool repeat(Object& obj) {
|
|
if(!Constructible::repeat(obj))
|
|
return false;
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
|
|
@supports[i].dsg = supports[i].dsg.mostUpdated();
|
|
supports[i].ordered += supports[i].amount;
|
|
supports[i].amount = 0;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void cancel(Object& obj) {
|
|
reverseDesignCosts(obj, design, cancel=true);
|
|
Constructible::cancel(obj);
|
|
}
|
|
|
|
string get_name() {
|
|
return design.name;
|
|
}
|
|
|
|
ConstructibleType get_type() {
|
|
return CT_Flagship;
|
|
}
|
|
|
|
void complete(Object& obj) {
|
|
double hpBonus = obj.constructionHPBonus;
|
|
|
|
Object@ spawnFrom;
|
|
if(constructFrom !is null && constructFrom.valid && constructFrom.owner is obj.owner)
|
|
@spawnFrom = constructFrom;
|
|
else
|
|
@spawnFrom = obj;
|
|
|
|
Ship@ ship = createShip(spawnFrom, design);
|
|
if(hpBonus != 0)
|
|
ship.modHPFactor(+hpBonus);
|
|
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
|
|
GroupData@ d = supports[i];
|
|
const Design@ dsg = d.dsg.mostUpdated();
|
|
ship.addSupportOrdered(dsg, d.ordered);
|
|
for(uint n = 0; n < d.amount; ++n) {
|
|
Ship@ sup = createShip(spawnFrom, dsg, obj.owner, ship);
|
|
if(hpBonus != 0)
|
|
sup.modHPFactor(+hpBonus);
|
|
}
|
|
}
|
|
|
|
spawnFrom.doRally(ship);
|
|
|
|
obj.owner.recordStatDelta(stat::ShipsBuilt, 1);
|
|
obj.owner.notifyFlagship(ship);
|
|
}
|
|
|
|
void write(Message& msg) {
|
|
Constructible::write(msg);
|
|
msg << design;
|
|
|
|
uint cnt = supports.length;
|
|
msg << cnt;
|
|
for(uint i = 0; i < cnt; ++i)
|
|
msg << supports[i];
|
|
}
|
|
|
|
bool addSupports(Object& obj, const Design@ dsg, uint amount, int cycle = -1) {
|
|
GroupData@ d;
|
|
@dsg = dsg.mostUpdated();
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
|
|
if(supports[i].dsg.mostUpdated() is dsg) {
|
|
@d = supports[i];
|
|
@d.dsg = dsg;
|
|
}
|
|
}
|
|
|
|
if(d is null) {
|
|
@d = GroupData();
|
|
@d.dsg = dsg;
|
|
supports.insertLast(d);
|
|
}
|
|
|
|
d.ordered += amount;
|
|
|
|
if(cycle == d.orderCycle) {
|
|
d.orderAmount += amount;
|
|
}
|
|
else {
|
|
d.orderCycle = cycle;
|
|
d.orderAmount = amount;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
uint removeSupports(const Design@ dsg, uint amount, Object@ refund = null) {
|
|
GroupData@ d;
|
|
@dsg = dsg.mostUpdated();
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
|
|
if(supports[i].dsg.mostUpdated() is dsg) {
|
|
@d = supports[i];
|
|
@d.dsg = dsg;
|
|
}
|
|
}
|
|
|
|
if(d is null)
|
|
return 0;
|
|
|
|
uint prev = d.totalSize;
|
|
uint take = min(d.ordered, amount);
|
|
d.ordered -= take;
|
|
amount -= take;
|
|
|
|
if(amount > 0)
|
|
d.amount -= min(amount, d.amount);
|
|
|
|
uint removed = prev - d.totalSize;
|
|
if(refund !is null) {
|
|
int cost = getBuildCost(dsg, removed);
|
|
int maint = getMaintenanceCost(dsg, removed);
|
|
maintainCost -= maint;
|
|
buildCost -= cost;
|
|
|
|
if(d.orderCycle != -1) {
|
|
uint refd = min(d.orderAmount, removed);
|
|
refund.owner.refundBudget(getBuildCost(dsg, refd), d.orderCycle);
|
|
d.orderAmount -= refd;
|
|
}
|
|
if(started)
|
|
refund.owner.modMaintenance(-maint, MoT_Construction);
|
|
reverseDesignCosts(refund, dsg, removed, true);
|
|
}
|
|
|
|
if(d.totalSize <= 0)
|
|
supports.remove(d);
|
|
return removed;
|
|
}
|
|
|
|
bool get_hasSupports() {
|
|
return supports.length != 0;
|
|
}
|
|
|
|
bool get_hasSupportsBuilding() {
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
|
|
GroupData@ d = supports[i];
|
|
if(d.ordered > 0)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
double getSupportSupplyFree() {
|
|
double supply = design.total(SV_SupportCapacity);
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
|
|
GroupData@ d = supports[i];
|
|
supply -= double(d.totalSize) * d.dsg.size;
|
|
}
|
|
return supply;
|
|
}
|
|
|
|
double addSupportLabor(double amount) {
|
|
if(supports.length == 0)
|
|
return amount;
|
|
if(!paid)
|
|
return amount;
|
|
|
|
savedLabor += amount;
|
|
|
|
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
|
|
GroupData@ d = supports[i];
|
|
if(d.ordered > 0) {
|
|
double laborCost = getLaborCost(d.dsg);
|
|
if(savedLabor < laborCost)
|
|
return 0.0;
|
|
|
|
while(d.ordered > 0 && savedLabor >= laborCost) {
|
|
savedLabor -= laborCost;
|
|
d.amount += 1;
|
|
d.ordered -= 1;
|
|
}
|
|
|
|
if(d.ordered > 0)
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
savedLabor = 0.0;
|
|
return savedLabor;
|
|
}
|
|
};
|