166 lines
3.8 KiB
ActionScript
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;
|
|
}
|
|
};
|