339 lines
9.3 KiB
ActionScript
339 lines
9.3 KiB
ActionScript
import hooks;
|
|
import artifacts;
|
|
import resources;
|
|
|
|
import ai.consider;
|
|
|
|
#section server
|
|
from empire import Creeps;
|
|
#section all
|
|
|
|
interface Artifacts {
|
|
Empire@ get_empire();
|
|
Considerer@ get_consider();
|
|
}
|
|
|
|
class ArtifactAI : Hook, ConsiderHook {
|
|
double consider(Considerer& cons, Object@ obj) const {
|
|
return 0.0;
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class Value : ArtifactAI {
|
|
Document doc("Sets the value for the artifact to a basic amount.");
|
|
Argument value(AT_Decimal, doc="Value to set for the artifact.");
|
|
|
|
#section server
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ActivateOnBestFleet : ArtifactAI {
|
|
Document doc("This artifact should be activated on our strongest fleet that it can be.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating on the best fleet.");
|
|
Argument min_strength(AT_Decimal, "1000", doc="Minimum strength for a fleet to be considered for this.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ fleet) const override {
|
|
double str = fleet.getFleetStrength() * 0.001;
|
|
if(str < min_strength.decimal)
|
|
return 0.0;
|
|
if(!cons.artifact.canTarget(fleet))
|
|
return 0.0;
|
|
return str;
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
@ai.consider.artifact = c;
|
|
Object@ best = ai.consider.Fleets(this);
|
|
if(best !is null) {
|
|
c.setTarget(best);
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ActivateOnBestPlanet : ArtifactAI {
|
|
Document doc("This artifact should be activated on our best planet that it can be.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating on the best planet.");
|
|
Argument min_population(AT_Decimal, "10", doc="Minimum population for a planet to be considered for this.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ planet) const override {
|
|
double pop = planet.population;
|
|
if(pop < min_population.decimal)
|
|
return 0.0;
|
|
if(!cons.artifact.canTarget(planet))
|
|
return 0.0;
|
|
return pop;
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
@ai.consider.artifact = c;
|
|
Object@ best = ai.consider.ImportantPlanets(this);
|
|
if(best !is null) {
|
|
c.setTarget(best);
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class AsCreatedResource : ArtifactAI {
|
|
Document doc("This artifact is used to spawn a new resource type on a planet that needs it.");
|
|
Argument resource(AT_PlanetResource, doc="Resource to match import requests to.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating this.");
|
|
Argument replaces_existing(AT_Boolean, "True", doc="Whether this can be used to replace an existing import of that type or not.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ requestedAt) const override {
|
|
if(!cons.artifact.canTarget(requestedAt))
|
|
return 0.0;
|
|
if(cons.currentSupplier !is null)
|
|
return 0.5;
|
|
return 1.0;
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
@ai.consider.artifact = c;
|
|
Object@ best = ai.consider.MatchingImportRequests(this, getResource(resource.integer), replaces_existing.boolean);
|
|
if(best !is null) {
|
|
c.setTarget(best);
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ActivateInOwnedSystem : ArtifactAI {
|
|
Document doc("Activate this artifact on a position in an arbitrary owned system.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating this.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ obj) const override {
|
|
Region@ sys = cast<Region>(obj);
|
|
if(sys.PlanetsMask & ~cons.empire.mask != 0)
|
|
return randomd(0.4, 0.6);
|
|
return randomd(0.9, 1.1);
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
Region@ best = cast<Region>(ai.consider.OwnedSystems(this));
|
|
if(best !is null) {
|
|
vec3d position = best.position;
|
|
vec2d offset = random2d(best.radius * 0.4, best.radius * 0.85);
|
|
position.x += offset.x;
|
|
position.z += offset.y;
|
|
|
|
if(!c.canTargetPosition(position))
|
|
return false;
|
|
|
|
c.setTargetPosition(position);
|
|
if(best.PlanetsMask & ~ai.empire.mask != 0)
|
|
value *= 0.5;
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ActivateNearOwnedSystem : ArtifactAI {
|
|
Document doc("Activate this artifact on a position placed outside an arbitrary owned system.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating this.");
|
|
Argument min_distance(AT_Decimal, "2000", doc="Minimum distance from the system boundary to place it.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ obj) const override {
|
|
Region@ sys = cast<Region>(obj);
|
|
if(sys.PlanetsMask & ~cons.empire.mask != 0)
|
|
return randomd(0.4, 0.6);
|
|
return randomd(0.9, 1.1);
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
Region@ best = cast<Region>(ai.consider.OwnedSystems(this));
|
|
if(best !is null) {
|
|
vec3d position = best.position;
|
|
vec2d offset = random2d(best.radius + min_distance.decimal, best.radius + min_distance.decimal * 2.0);
|
|
position.x += offset.x;
|
|
position.z += offset.y;
|
|
position.y += min_distance.decimal * randomd(0.0, 0.25);
|
|
|
|
if(!c.canTargetPosition(position))
|
|
return false;
|
|
|
|
c.setTargetPosition(position);
|
|
if(best.PlanetsMask & ~ai.empire.mask != 0)
|
|
value *= 0.5;
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class AsVisionGain : ArtifactAI {
|
|
Document doc("Activate this to gain vision over systems with other people in them we want to see.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating this.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ obj) const override {
|
|
Region@ sys = cast<Region>(obj);
|
|
if(sys.VisionMask & cons.empire.visionMask != 0)
|
|
return 0.0;
|
|
if(!cons.artifact.canTarget(sys))
|
|
return 0.0;
|
|
double w = 1.0;
|
|
if(sys.PlanetsMask & cons.empire.hostileMask != 0)
|
|
w *= 2.0;
|
|
return w * randomd(0.9, 1.1);
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
@ai.consider.artifact = c;
|
|
Region@ best = cast<Region>(ai.consider.OtherSystems(this));
|
|
if(best !is null) {
|
|
c.setTarget(best);
|
|
value *= this.value.decimal;
|
|
if(best.PlanetsMask & ai.empire.hostileMask != 0)
|
|
value *= 2.0;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class RevenantPart : ArtifactAI {
|
|
Document doc("Special AI to deal with using parts of the revenant.");
|
|
|
|
#section server
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
//If we are subjugated don't use these
|
|
if(ai.empire.SubjugatedBy !is null)
|
|
return false;
|
|
|
|
value *= 10.0;
|
|
//If we have parts ourselves, weight more
|
|
value *= pow(2.0, ai.empire.RevenantParts);
|
|
|
|
//If an enemy has multilple parts, weight more
|
|
for(uint i = 0, cnt = getEmpireCount(); i < cnt; ++i) {
|
|
Empire@ other = getEmpire(i);
|
|
if(!other.major || other !is ai.empire)
|
|
value *= pow(3.0, other.RevenantParts);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ActivateAsPressureBoost : ArtifactAI {
|
|
Document doc("Activate this artifact on a planet to boost its pressure.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating on the best planet.");
|
|
Argument pressure_amount(AT_Decimal, "1.0", doc="Amount of pressure that is added.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ planet) const override {
|
|
auto@ res = getResource(planet.primaryResourceType);
|
|
if(res is null)
|
|
return 0.0;
|
|
if(res.totalPressure < 1)
|
|
return 0.0;
|
|
double pres = planet.totalPressure;
|
|
double cap = planet.pressureCap;
|
|
if(pres + pressure_amount.decimal > cap * 1.5)
|
|
return 0.0;
|
|
if(!cons.artifact.canTarget(planet))
|
|
return 0.0;
|
|
return 1.0;
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
@ai.consider.artifact = c;
|
|
Object@ best = ai.consider.SomePlanets(this);
|
|
Object@ existing = c.getTarget();
|
|
if(existing !is null && consider(ai.consider, existing) > ai.consider.selectedWeight)
|
|
@best = existing;
|
|
if(best !is null) {
|
|
c.setTarget(best);
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ActivateOnRemnantStation : ArtifactAI {
|
|
Document doc("Find remnant stations to trigger this on.");
|
|
Argument value(AT_Decimal, "1.0", doc="Value for activating on the best station.");
|
|
|
|
#section server
|
|
double consider(Considerer& cons, Object@ obj) const override {
|
|
Region@ reg = cast<Region>(obj);
|
|
if(reg.getStrength(Creeps) > 0)
|
|
return 1.0;
|
|
return 0.0;
|
|
}
|
|
|
|
bool consider(Artifacts& ai, ArtifactConsider& c, double& value) const override {
|
|
@ai.consider.artifact = c;
|
|
Object@ best;
|
|
|
|
Object@ reg = cast<Region>(ai.consider.OwnedSystems(this));
|
|
if(reg !is null) {
|
|
Object@ en = reg.findEnemy(ai.empire, Creeps.mask, fleets=false, stations=true);
|
|
if(en !is null) {
|
|
if(c.canTarget(en))
|
|
@best = en;
|
|
}
|
|
}
|
|
Object@ existing = c.getTarget();
|
|
if(best is null && existing !is null && existing.valid && c.canTarget(existing))
|
|
@best = existing;
|
|
|
|
if(best !is null) {
|
|
c.setTarget(best);
|
|
value *= this.value.decimal;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#section all
|
|
};
|