Files
starruler-linux/scripts/server/empire_ai/weasel/Orbitals.as
T
2018-07-17 14:15:37 +02:00

239 lines
4.7 KiB
ActionScript

import empire_ai.weasel.WeaselAI;
import empire_ai.weasel.Budget;
import empire_ai.weasel.Systems;
from ai.orbitals import AIOrbitals, OrbitalAIHook, OrbitalUse;
import ai.consider;
import orbitals;
import saving;
final class OrbitalAI {
Object@ obj;
const OrbitalModule@ type;
double prevTick = 0;
Object@ around;
void init(AI& ai, Orbitals& orbitals) {
if(obj.isOrbital)
@type = getOrbitalModule(cast<Orbital>(obj).coreModule);
}
void save(Orbitals& orbitals, SaveFile& file) {
file << obj;
}
void load(Orbitals& orbitals, SaveFile& file) {
file >> obj;
}
void remove(AI& ai, Orbitals& orbitals) {
}
void tick(AI& ai, Orbitals& orbitals, double time) {
//Deal with losing planet ownership
if(obj is null || !obj.valid || obj.owner !is ai.empire) {
orbitals.remove(this);
return;
}
//Record what we're orbiting around
if(around !is null) {
if(!obj.isOrbitingAround(around))
@around = obj.getOrbitingAround();
}
else {
if(obj.hasOrbitCenter)
@around = obj.getOrbitingAround();
}
}
};
class Orbitals : AIComponent, AIOrbitals {
Budget@ budget;
Systems@ systems;
array<OrbitalAI@> orbitals;
uint orbIdx = 0;
void create() {
@budget = cast<Budget>(ai.budget);
@systems = cast<Systems>(ai.systems);
//Register specialized orbital types
for(uint i = 0, cnt = getOrbitalModuleCount(); i < cnt; ++i) {
auto@ type = getOrbitalModule(i);
for(uint n = 0, ncnt = type.ai.length; n < ncnt; ++n) {
auto@ hook = cast<OrbitalAIHook>(type.ai[n]);
if(hook !is null)
hook.register(this, type);
}
}
}
Empire@ get_empire() {
return ai.empire;
}
Considerer@ get_consider() {
return cast<Considerer>(ai.consider);
}
OrbitalAI@ getInSystem(const OrbitalModule@ module, Region@ reg) {
if(module is null)
return null;
for(uint i = 0, cnt = orbitals.length; i < cnt; ++i) {
if(orbitals[i].type is module) {
if(orbitals[i].obj.region is reg)
return orbitals[i];
}
}
return null;
}
bool haveInSystem(const OrbitalModule@ module, Region@ reg) {
if(module is null)
return false;
for(uint i = 0, cnt = orbitals.length; i < cnt; ++i) {
if(orbitals[i].type is module) {
if(orbitals[i].obj.region is reg)
return true;
}
}
return false;
}
bool haveAround(const OrbitalModule@ module, Object@ around) {
if(module is null)
return false;
for(uint i = 0, cnt = orbitals.length; i < cnt; ++i) {
if(orbitals[i].type is module) {
if(orbitals[i].around is around)
return true;
}
}
return false;
}
void registerUse(OrbitalUse use, const OrbitalModule& type) {
switch(use) {
case OU_Shipyard:
@ai.defs.Shipyard = type;
break;
}
}
void save(SaveFile& file) {
uint cnt = orbitals.length;
file << cnt;
for(uint i = 0; i < cnt; ++i) {
auto@ data = orbitals[i];
saveAI(file, data);
data.save(this, file);
}
}
void load(SaveFile& file) {
uint cnt = 0;
file >> cnt;
for(uint i = 0; i < cnt; ++i) {
auto@ data = loadAI(file);
if(data !is null)
data.load(this, file);
else
OrbitalAI().load(this, file);
}
}
OrbitalAI@ loadAI(SaveFile& file) {
Object@ obj;
file >> obj;
if(obj is null)
return null;
OrbitalAI@ data = getAI(obj);
if(data is null) {
@data = OrbitalAI();
@data.obj = obj;
data.prevTick = gameTime;
orbitals.insertLast(data);
}
return data;
}
void saveAI(SaveFile& file, OrbitalAI@ ai) {
Object@ obj;
if(ai !is null)
@obj = ai.obj;
file << obj;
}
void start() {
checkForOrbitals();
}
void checkForOrbitals() {
auto@ data = ai.empire.getOrbitals();
Object@ obj;
while(receive(data, obj)) {
if(obj !is null)
register(obj);
}
}
void tick(double time) {
double curTime = gameTime;
if(orbitals.length != 0) {
orbIdx = (orbIdx+1) % orbitals.length;
auto@ data = orbitals[orbIdx];
data.tick(ai, this, curTime - data.prevTick);
data.prevTick = curTime;
}
}
uint prevCount = 0;
double checkTimer = 0;
void focusTick(double time) override {
//Check for any newly obtained planets
uint curCount = ai.empire.orbitalCount;
checkTimer += time;
if(curCount != prevCount || checkTimer > 60.0) {
checkForOrbitals();
prevCount = curCount;
checkTimer = 0;
}
}
OrbitalAI@ getAI(Object& obj) {
for(uint i = 0, cnt = orbitals.length; i < cnt; ++i) {
if(orbitals[i].obj is obj)
return orbitals[i];
}
return null;
}
OrbitalAI@ register(Object& obj) {
OrbitalAI@ data = getAI(obj);
if(data is null) {
@data = OrbitalAI();
@data.obj = obj;
data.prevTick = gameTime;
orbitals.insertLast(data);
data.init(ai, this);
}
return data;
}
void remove(OrbitalAI@ data) {
data.remove(ai, this);
orbitals.remove(data);
}
};
AIComponent@ createOrbitals() {
return Orbitals();
}