Files
2018-07-17 14:15:37 +02:00

166 lines
3.8 KiB
ActionScript

import construction.Constructible;
import construction.ShipConstructible;
import resources;
import object_creation;
import ship_groups;
import util.formatting;
tidy class StationConstructible : ShipConstructible {
double laborPenalty = 1.0;
vec3d position;
Orbital@ target;
StationConstructible(const Design@ Design, vec3d pos, double penalty) {
super(Design);
laborPenalty = penalty;
position = pos;
totalLabor *= penalty;
}
StationConstructible(SaveFile& msg) {
super(msg);
msg >> laborPenalty;
msg >> position;
msg >> target;
}
void save(SaveFile& msg) {
ShipConstructible::save(msg);
msg << laborPenalty;
msg << position;
msg << target;
}
ConstructibleType get_type() {
return CT_Station;
}
bool repeat(Object& obj) {
if(!ShipConstructible::repeat(obj))
return false;
@target = null;
double size = stationRadiusFactor * pow(design.size,1.0/shipVolumePower);
vec2d offset = random2d(size * 2.0, size * 4.0);
position.x += offset.x;
position.z += offset.y;
return true;
}
bool pay(Object& obj) {
if(!ShipConstructible::pay(obj))
return false;
double hp = design.totalHP;
string name = format(locale::NAME_SCAFFOLDING, formatShipName(design));
@target = createOrbital(position,
getOrbitalModule("Scaffolding"),
obj.owner, disabled=true,
nameOverride=name);
target.modMaxHealth(hp);
target.setBuildPct(0.0);
return true;
}
void cancel(Object& obj) {
if(buildCost != 0 && target !is null) {
if(!target.valid) {
buildCost = 0;
}
else {
double maxHealth = target.maxHealth + target.maxArmor;
double pct = 0.0;
if(totalLabor > 0)
maxHealth *= curLabor / totalLabor;
if(maxHealth != 0)
pct = clamp((target.health + target.armor) / maxHealth, 0.0, 1.0);
pct = clamp((pct-0.01) / 0.99, 0.0, 1.0);
buildCost = int(double(buildCost) * pct);
}
}
ShipConstructible::cancel(obj);
if(target !is null && target.valid)
target.destroy();
}
TickResult tick(Object& obj, double time) override {
if(target is null || !target.valid) {
cancel(obj);
return TR_Remove;
}
target.setBuildPct(curLabor / totalLabor);
return TR_UsedLabor;
}
void complete(Object& obj) {
Ship@ ship = createShip(target.position, design, obj.owner);
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)
createShip(obj, dsg, obj.owner, ship);
}
obj.doRally(ship);
if(target !is null && target.valid) {
ship.setHealthPct(target.health / target.maxHealth);
target.destroy();
}
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) override {
if(target is null)
return false;
Region@ myRegion = obj.region;
Region@ targRegion = target.region;
if(myRegion is null || myRegion !is targRegion)
return false;
ShipConstructible::addSupports(obj, dsg, amount, cycle=cycle);
return true;
}
double addSupportLabor(double amount) {
if(supports.length == 0)
return amount;
if(!paid)
return amount;
savedLabor += amount / laborPenalty;
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;
}
};