114 lines
2.7 KiB
ActionScript
114 lines
2.7 KiB
ActionScript
import construction.Constructible;
|
|
import orbitals;
|
|
import object_creation;
|
|
import attributes;
|
|
|
|
tidy class OrbitalConstructible : Constructible {
|
|
const OrbitalModule@ def;
|
|
vec3d position;
|
|
Orbital@ target;
|
|
|
|
OrbitalConstructible(Object& obj, const OrbitalModule@ Def, const vec3d& pos) {
|
|
@def = Def;
|
|
buildCost = def.buildCost * obj.owner.OrbitalBuildCostFactor;
|
|
totalLabor = def.laborCost * obj.owner.OrbitalLaborCostFactor;
|
|
position = pos;
|
|
}
|
|
|
|
bool repeat(Object& obj) {
|
|
if(!Constructible::repeat(obj))
|
|
return false;
|
|
if(!def.canBuild(obj, position))
|
|
return false;
|
|
vec2d offset = random2d(def.size * 2.0, def.size * 4.0);
|
|
position.x += offset.x;
|
|
position.z += offset.y;
|
|
return true;
|
|
}
|
|
|
|
OrbitalConstructible(SaveFile& file) {
|
|
Constructible::load(file);
|
|
|
|
uint defId = file.readIdentifier(SI_Orbital);
|
|
@def = getOrbitalModule(defId);
|
|
file >> position;
|
|
file >> target;
|
|
}
|
|
|
|
void save(SaveFile& file) {
|
|
Constructible::save(file);
|
|
file.writeIdentifier(SI_Orbital, def.id);
|
|
file << position;
|
|
file << target;
|
|
}
|
|
|
|
bool pay(Object& obj) {
|
|
for(uint i = 0, cnt = def.hooks.length; i < cnt; ++i) {
|
|
if(!def.hooks[i].consume(obj)) {
|
|
for(uint j = 0; j < i; ++j)
|
|
def.hooks[j].reverse(obj, false);
|
|
return false;
|
|
}
|
|
}
|
|
if(!Constructible::pay(obj)) {
|
|
for(uint i = 0, cnt = def.hooks.length; i < cnt; ++i)
|
|
def.hooks[i].reverse(obj, false);
|
|
return false;
|
|
}
|
|
@target = createOrbital(position, def, obj.owner, disabled=true);
|
|
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);
|
|
}
|
|
}
|
|
for(uint i = 0, cnt = def.hooks.length; i < cnt; ++i)
|
|
def.hooks[i].reverse(obj, true);
|
|
Constructible::cancel(obj);
|
|
if(target !is null && target.valid)
|
|
target.destroy();
|
|
}
|
|
|
|
ConstructibleType get_type() {
|
|
return CT_Orbital;
|
|
}
|
|
|
|
string get_name() {
|
|
return def.name;
|
|
}
|
|
|
|
TickResult tick(Object& obj, double time) override {
|
|
if(target is null || !target.valid || !def.canBuild(obj, target.position, initial=false)) {
|
|
cancel(obj);
|
|
return TR_Remove;
|
|
}
|
|
target.setBuildPct(curLabor / totalLabor);
|
|
return TR_UsedLabor;
|
|
}
|
|
|
|
void complete(Object& obj) {
|
|
if(target !is null) {
|
|
target.setDisabled(false);
|
|
obj.owner.modAttribute(EA_OrbitalsBuilt, AC_Add, 1.0);
|
|
}
|
|
}
|
|
|
|
void write(Message& msg) {
|
|
Constructible::write(msg);
|
|
msg << def.id;
|
|
}
|
|
};
|