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

396 lines
9.7 KiB
ActionScript

// Diplomacy
// ---------
// Acts as an adaptor for using the generically developed DiplomacyAI.
//
import empire_ai.weasel.WeaselAI;
import empire_ai.weasel.Systems;
import empire_ai.weasel.Planets;
import empire_ai.weasel.Development;
import empire_ai.weasel.Construction;
import empire_ai.weasel.Fleets;
import empire_ai.weasel.Resources;
import empire_ai.weasel.War;
import empire_ai.weasel.Intelligence;
import influence;
from empire_ai.DiplomacyAI import DiplomacyAI, VoteData, CardAI, VoteState;
import systems;
class Diplomacy : DiplomacyAI, IAIComponent {
Systems@ systems;
Fleets@ fleets;
Planets@ planets;
Construction@ construction;
Development@ development;
Resources@ resources;
War@ war;
Intelligence@ intelligence;
//Adapt to AI component
AI@ ai;
double prevFocus = 0;
bool logCritical = false;
bool logErrors = true;
double getPrevFocus() { return prevFocus; }
void setPrevFocus(double value) { prevFocus = value; }
void setLog() { log = true; }
void setLogCritical() { logCritical = true; }
void set(AI& ai) { @this.ai = ai; }
void start() {}
void tick(double time) {}
void turn() {}
void postLoad(AI& ai) {}
void postSave(AI& ai) {}
void loadFinalize(AI& ai) {}
//Actual AI component implementations
void create() {
@systems = cast<Systems>(ai.systems);
@fleets = cast<Fleets>(ai.fleets);
@planets = cast<Planets>(ai.planets);
@development = cast<Development>(ai.development);
@construction = cast<Construction>(ai.construction);
@resources = cast<Resources>(ai.resources);
@war = cast<War>(ai.war);
@intelligence = cast<Intelligence>(ai.intelligence);
}
//IMPLEMENTED BY DiplomacyAI
/*void save(SaveFile& file) {}*/
/*void load(SaveFile& file) {}*/
uint nextStep = 0;
void focusTick(double time) {
summarize();
switch(nextStep++ % 3) {
case 0:
buyCards();
break;
case 1:
considerActions();
break;
case 2:
considerVotes();
break;
}
}
//Adapt to diplomacy AI
Empire@ get_empire() {
return ai.empire;
}
uint get_allyMask() {
return ai.allyMask;
}
int getStanding(Empire@ emp) {
//TODO: Use relations module for this generically
if(emp.isHostile(ai.empire))
return -50;
if(ai.allyMask & emp.mask != 0)
return 100;
return 0;
}
void print(const string& str) {
ai.print(str);
}
Object@ considerImportantPlanets(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = development.focuses.length; i < cnt; ++i) {
Object@ obj = development.focuses[i].obj;
double w = hook.consider(this, targets, vote, card, obj);
if(w > bestWeight) {
@best = obj;
bestWeight = w;
}
}
return best;
}
Object@ considerOwnedPlanets(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
//Consider our important ones first
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = development.focuses.length; i < cnt; ++i) {
Object@ obj = development.focuses[i].obj;
double w = hook.consider(this, targets, vote, card, obj);
if(w > bestWeight) {
@best = obj;
bestWeight = w;
}
}
//Consider some random other ones
uint planetCount = planets.planets.length;
if(planetCount != 0) {
uint offset = randomi(0, planetCount-1);
for(uint n = 0; n < 5; ++n) {
Object@ obj = planets.planets[(offset+n) % planetCount].obj;
double w = hook.consider(this, targets, vote, card, obj);
if(w > bestWeight) {
@best = obj;
bestWeight = w;
}
}
}
return best;
}
Object@ considerImportantSystems(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = development.focuses.length; i < cnt; ++i) {
Object@ obj = development.focuses[i].obj.region;
if(obj is null)
continue;
double w = hook.consider(this, targets, vote, card, obj);
if(w > bestWeight) {
@best = obj;
bestWeight = w;
}
}
return best;
}
Object@ considerOwnedSystems(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
//Consider our important ones first
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = development.focuses.length; i < cnt; ++i) {
Object@ obj = development.focuses[i].obj.region;
if(obj is null)
continue;
double w = hook.consider(this, targets, vote, card, obj);
if(w > bestWeight) {
@best = obj;
bestWeight = w;
}
}
//Consider some random other ones
uint sysCount = systems.owned.length;
if(sysCount != 0) {
uint offset = randomi(0, sysCount-1);
for(uint n = 0; n < 5; ++n) {
Object@ obj = systems.owned[(offset+n) % sysCount].obj;
double w = hook.consider(this, targets, vote, card, obj);
if(w > bestWeight) {
@best = obj;
bestWeight = w;
}
}
}
return best;
}
Object@ considerDefendingSystems(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = war.battles.length; i < cnt; ++i) {
auto@ battle = war.battles[i];
Region@ sys = battle.system.obj;
if(sys.SiegedMask & empire.mask == 0)
continue;
double w = hook.consider(this, targets, vote, card, sys);
if(w > bestWeight) {
@best = sys;
bestWeight = w;
}
}
return best;
}
Object@ considerDefendingPlanets(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = war.battles.length; i < cnt; ++i) {
auto@ battle = war.battles[i];
Region@ sys = battle.system.obj;
if(sys.SiegedMask & empire.mask == 0)
continue;
for(uint n = 0, ncnt = battle.system.planets.length; n < ncnt; ++n) {
Object@ pl = battle.system.planets[n];
if(pl.owner !is empire)
continue;
double w = hook.consider(this, targets, vote, card, pl);
if(w > bestWeight) {
@best = pl;
bestWeight = w;
}
}
}
return best;
}
Object@ considerEnemySystems(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = getEmpireCount(); i < cnt; ++i) {
Empire@ emp = getEmpire(i);
if(!emp.major)
continue;
if(!empire.isHostile(emp))
continue;
auto@ intel = intelligence.get(emp);
if(intel is null)
continue;
for(uint n = 0, ncnt = intel.theirBorder.length; n < ncnt; ++n) {
auto@ sysIntel = intel.theirBorder[n];
double w = hook.consider(this, targets, vote, card, sysIntel.obj);
if(w > bestWeight) {
@best = sysIntel.obj;
bestWeight = w;
}
}
}
return best;
}
Object@ considerEnemyPlanets(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = getEmpireCount(); i < cnt; ++i) {
Empire@ emp = getEmpire(i);
if(!emp.major)
continue;
if(!empire.isHostile(emp))
continue;
auto@ intel = intelligence.get(emp);
if(intel is null)
continue;
for(uint n = 0, ncnt = intel.theirBorder.length; n < ncnt; ++n) {
auto@ sysIntel = intel.theirBorder[n];
for(uint j = 0, jcnt = sysIntel.planets.length; j < jcnt; ++j) {
Planet@ pl = sysIntel.planets[j];
if(pl.visibleOwnerToEmp(empire) !is emp)
continue;
double w = hook.consider(this, targets, vote, card, pl);
if(w > bestWeight) {
@best = pl;
bestWeight = w;
}
}
}
}
return best;
}
Object@ considerFleets(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
Object@ best;
double bestWeight = 0.0;
for(uint i = 0, cnt = fleets.fleets.length; i < cnt; ++i) {
Object@ fleet = fleets.fleets[i].obj;
if(fleet !is null) {
double w = hook.consider(this, targets, vote, card, fleet);
if(w > bestWeight) {
@best = fleet;
bestWeight = w;
}
}
}
return best;
}
Object@ considerEnemyFleets(const CardAI& hook, Targets& targets, VoteState@ vote = null, const InfluenceCard@ card = null) {
double bestWeight = 0.0;
Object@ best;
for(uint i = 0, cnt = getEmpireCount(); i < cnt; ++i) {
Empire@ emp = getEmpire(i);
if(!emp.major)
continue;
if(!empire.isHostile(emp))
continue;
auto@ intel = intelligence.get(emp);
if(intel is null)
continue;
for(uint n = 0, ncnt = intel.fleets.length; n < ncnt; ++n) {
auto@ flIntel = intel.fleets[n];
if(!flIntel.known)
continue;
double w = hook.consider(this, targets, vote, card, flIntel.obj);
if(w > bestWeight) {
@best = flIntel.obj;
bestWeight = w;
}
}
}
return best;
}
Object@ considerMatchingImportRequests(const CardAI& hook, Targets& targets, VoteState@ vote, const InfluenceCard@ card, const ResourceType@ type, bool considerExisting) {
Object@ best;
double bestWeight = 0.0;
for(uint i = 0, cnt = resources.requested.length; i < cnt; ++i) {
ImportData@ req = resources.requested[i];
if(req.spec.meets(type)) {
double w = hook.consider(this, targets, vote, card, req.obj, null);
if(w > bestWeight) {
bestWeight = w;
@best = req.obj;
}
}
}
if(considerExisting) {
for(uint i = 0, cnt = resources.used.length; i < cnt; ++i) {
ExportData@ res = resources.used[i];
ImportData@ req = res.request;
if(req !is null && req.spec.meets(type)) {
double w = hook.consider(this, targets, vote, card, req.obj, res.obj);
if(w > bestWeight) {
bestWeight = w;
@best = req.obj;
}
}
}
}
return best;
}
};
IAIComponent@ createDiplomacy() {
return Diplomacy();
}