Files
starruler-linux/scripts/definitions/consume_effects.as
T
2018-07-17 14:15:37 +02:00

544 lines
19 KiB
ActionScript

import hooks;
import cargo;
import buildings;
from buildings import IBuildingHook;
import constructions;
from constructions import IConstructionHook;
import orbitals;
from orbitals import IOrbitalEffect;
import icons;
#section server
from construction.Constructible import Constructible;
#section all
class ConsumeEffect : Hook, IConstructionHook, IBuildingHook, IOrbitalEffect {
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
return true;
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
return false;
}
bool consume(Object& obj, const Targets@ targs) const {
return true;
}
void reverse(Object& obj, const Targets@ targs, bool cancel = false) const {
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
return false;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
return false;
}
//Buildings
uint hookIndex = 0;
void initialize(BuildingType@ type, uint index) { hookIndex = index; }
void startConstruction(Object& obj, SurfaceBuilding@ bld) const {}
void cancelConstruction(Object& obj, SurfaceBuilding@ bld) const {}
void complete(Object& obj, SurfaceBuilding@ bld) const {}
void ownerChange(Object& obj, SurfaceBuilding@ bld, Empire@ prevOwner, Empire@ newOwner) const {}
void remove(Object& obj, SurfaceBuilding@ bld) const {}
void tick(Object& obj, SurfaceBuilding@ bld, double time) const {}
void save(SurfaceBuilding@ bld, SaveFile& file) const {}
void load(SurfaceBuilding@ bld, SaveFile& file) const {}
bool canBuildOn(Object& obj, bool ignoreState = false) const { return canConsume(obj, null, ignoreState); }
bool canRemove(Object& obj) const { return true; }
bool getVariable(Object@ obj, Sprite& sprt, string& name, string& value, Color& color, bool isOption) const {
if(isOption)
return getVariable(obj, sprt, name, value, color);
return false;
}
bool consume(Object& obj) const { return consume(obj, null); }
void reverse(Object& obj) const { reverse(obj, null); }
void modBuildTime(Object& obj, double& time) const {}
bool canProgress(Object& obj) const { return true; }
//Orbitals
void onEnable(Orbital& obj, any@ data) const {}
void onDisable(Orbital& obj, any@ data) const {}
void onCreate(Orbital& obj, any@ data) const {}
void onDestroy(Orbital& obj, any@ data) const {}
void onTick(Orbital& obj, any@ data, double time) const {}
void onOwnerChange(Orbital& obj, any@ data, Empire@ prevOwner, Empire@ newOwner) const {}
void onRegionChange(Orbital& obj, any@ data, Region@ prevRegion, Region@ newRegion) const {}
void onMakeGraphics(Orbital& obj, any@ data, OrbitalNode@ node) const {}
bool checkRequirements(OrbitalRequirements@ reqs, bool apply) const { return true; }
void revertRequirements(OrbitalRequirements@ reqs) const {}
bool canBuildBy(Object@ obj, bool ignoreCost = true) const { return canConsume(obj, null, ignoreCost); }
bool canBuildAt(Object@ obj, const vec3d& pos) const { return true; }
bool canBuildOn(Orbital& obj) const { return true; }
string getBuildError(Object@ obj, const vec3d& pos) const { return ""; }
bool shouldDisable(Orbital& obj, any@ data) const { return false; }
bool shouldEnable(Orbital& obj, any@ data) const { return true; }
void save(any@ data, SaveFile& file) const {}
void load(any@ data, SaveFile& file) const {}
void write(any@ data, Message& msg) const {}
void read(any@ data, Message& msg) const {}
void onKill(Orbital& obj, any@ data, Empire@ killedBy) const {}
bool getValue(Player& pl, Orbital& obj, any@ data, uint index, double& value) const { return false; }
bool sendValue(Player& pl, Orbital& obj, any@ data, uint index, double value) const { return false; }
bool getDesign(Player& pl, Orbital& obj, any@ data, uint index, const Design@& value) const { return false; }
bool sendDesign(Player& pl, Orbital& obj, any@ data, uint index, const Design@ value) const { return false; }
bool getObject(Player& pl, Orbital& obj, any@ data, uint index, Object@& value) const { return false; }
bool sendObject(Player& pl, Orbital& obj, any@ data, uint index, Object@ value) const { return false; }
bool getData(Orbital& obj, string& txt, bool enabled) const { return false; }
void reverse(Object& obj, bool cancel) const { reverse(obj, null, cancel); }
//Constructions
#section server
void start(Construction@ cons, Constructible@ qitem, any@ data) const {}
void cancel(Construction@ cons, Constructible@ qitem, any@ data) const {}
void finish(Construction@ cons, Constructible@ qitem, any@ data) const {}
void tick(Construction@ cons, Constructible@ qitem, any@ data, double time) const {}
#section all
void save(Construction@ cons, any@ data, SaveFile& file) const {}
void load(Construction@ cons, any@ data, SaveFile& file) const {}
bool consume(Construction@ cons, any@ data, const Targets@ targs) const { return consume(cons.obj, targs); }
void reverse(Construction@ cons, any@ data, const Targets@ targs, bool cancel) const { reverse(cons.obj, targs, cancel); }
string getFailReason(Object& obj, const ConstructionType@ cons, uint index, const Target@ targ) const { return ""; }
bool isValidTarget(Object& obj, const ConstructionType@ cons, uint index, const Target@ targ) const { return true; }
bool canBuild(Object& obj, const ConstructionType@ cons, const Targets@ targs, bool ignoreCost) const { return canConsume(obj, targs, ignoreCost); }
void getBuildCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const {}
void getMaintainCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const {}
void getLaborCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, double& cost) const {}
bool getVariable(Object& obj, const ConstructionType@ cons, Sprite& sprt, string& name, string& value, Color& color) const {
return getVariable(obj, sprt, name, value, color);
}
bool formatCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, string& value) const { return formatCost(obj, targs, value); }
bool getCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, string& value, Sprite& icon) const { return getCost(obj, value, icon); }
};
class ConsumeFTL : ConsumeEffect {
Document doc("Requires a payment of FTL to build this construction.");
Argument cost("Amount", AT_Decimal, doc="FTL Cost.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(ignoreCost)
return true;
return obj.owner.FTLStored >= cost.decimal;
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = format(locale::FTL_COST, toString(cost.decimal, 0));
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(cost.decimal, true);
icon = icons::FTL;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
if(obj.owner.consumeFTL(cost.decimal, partial=false, record=false) == 0.0)
return false;
return true;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
if(!cancel)
obj.owner.modFTLStored(cost.decimal);
}
#section all
};
class ConsumeInfluence : ConsumeEffect {
Document doc("Requires a payment of influence to build this construction.");
Argument cost("Amount", AT_Integer, doc="Influence Cost.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(ignoreCost)
return true;
return obj.owner.Influence >= cost.integer;
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = format(locale::RESOURCE_INFLUENCE, toString(cost.integer, 0));
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(cost.integer, true);
icon = icons::Influence;
return true;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
value = standardize(cost.integer, true);
sprt = icons::Influence;
name = locale::RESOURCE_INFLUENCE + " "+locale::COST;
color = colors::Influence;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
if(!obj.owner.consumeInfluence(cost.integer))
return false;
return true;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
if(!cancel)
obj.owner.modInfluence(cost.integer);
}
#section all
};
class ConsumeResearch : ConsumeEffect {
Document doc("Requires a payment of Research to build this construction.");
Argument cost("Amount", AT_Integer, doc="Research Cost.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(ignoreCost)
return true;
return obj.owner.ResearchPoints >= cost.integer;
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = toString(cost.integer, 0)+" "+locale::RESOURCE_RESEARCH;
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(cost.integer, true);
icon = icons::Research;
return true;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
value = standardize(cost.integer, true);
sprt = icons::Research;
name = locale::RESOURCE_RESEARCH + " "+locale::COST;
color = colors::Research;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
if(!obj.owner.consumeResearchPoints(cost.integer))
return false;
return true;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
obj.owner.freeResearchPoints(cost.integer);
}
#section all
};
class ConsumeEnergy : ConsumeEffect {
Document doc("Requires a payment of Energy to build this construction.");
Argument cost("Amount", AT_Decimal, doc="Energy Cost.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(ignoreCost)
return true;
return obj.owner.EnergyStored >= cost.decimal;
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = toString(cost.decimal, 0)+" "+locale::RESOURCE_ENERGY;
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(cost.decimal, true);
icon = icons::Energy;
return true;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
value = standardize(cost.decimal, true);
sprt = icons::Energy;
name = locale::RESOURCE_ENERGY + " "+locale::COST;
color = colors::Energy;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
if(obj.owner.consumeEnergy(cost.decimal, false) == 0.0)
return false;
return true;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
if(!cancel)
obj.owner.modEnergyStored(cost.decimal);
}
#section all
};
class ConsumePopulation : ConsumeEffect {
Document doc("Requires a payment of Population to build this construction.");
Argument cost("Amount", AT_Decimal, doc="Population Cost.");
Argument allow_abandon(AT_Boolean, "False", doc="Whether to allow the planet to build this so it would go below 1 population and abandon.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(!obj.hasSurfaceComponent)
return false;
if(ignoreCost)
return true;
if(!allow_abandon.boolean)
return obj.population - 1.0 > cost.decimal;
return obj.population > cost.decimal;
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = toString(cost.decimal, 0)+" "+locale::POPULATION;
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(cost.decimal, true);
icon = icons::Population;
return true;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
value = standardize(cost.decimal, true);
sprt = icons::Population;
name = locale::POPULATION + " "+locale::COST;
color = colors::White;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
if(!obj.hasSurfaceComponent)
return false;
double avail = obj.population;
if(!allow_abandon.boolean)
avail -= 1.0;
if(avail < cost.decimal)
return false;
obj.addPopulation(-cost.decimal);
return true;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
if(!cancel)
obj.addPopulation(cost.decimal);
}
void tick(Construction@ cons, Constructible@ qitem, any@ data, double time) const {
if(allow_abandon.boolean && cons.obj.population <= 0.1)
cons.obj.forceAbandon();
}
#section all
};
class ConsumeCargo : ConsumeEffect {
Document doc("Requires a payment of cargo to build this construction.");
Argument type(AT_Cargo, doc="Type of cargo to take.");
Argument amount(AT_Decimal, doc="Amount of cargo taken to build.");
Argument hide(AT_Boolean, "False", doc="If the planet has _no_ cargo of this type, hide the project.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(!obj.hasCargo)
return false;
double val = obj.getCargoStored(type.integer);
if(hide.boolean && val < 0.001)
return false;
if(ignoreCost)
return true;
return val >= amount.decimal;
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = standardize(amount.decimal, true)+" "+getCargoType(type.integer).name;
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(amount.decimal, true);
icon = getCargoType(type.integer).icon;
return true;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
auto@ cargo = getCargoType(type.integer);
value = standardize(amount.decimal, true);
sprt = cargo.icon;
name = cargo.name + " "+locale::COST;
color = cargo.color;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
double consAmt = obj.consumeCargo(type.integer, amount.decimal, partial=false);
return consAmt >= amount.decimal - 0.001;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
obj.addCargo(type.integer, amount.decimal);
}
#section all
};
class ConsumeCargoAttribute : ConsumeEffect {
Document doc("Requires a payment of cargo to build this construction based on an attribute.");
Argument type(AT_Cargo, doc="Type of cargo to take.");
Argument attribute(AT_EmpAttribute, doc="Attribute to get value from.");
Argument base_amount(AT_Decimal, "0", doc="Base amount of cargo taken to build.");
Argument multiply(AT_Decimal, "1", doc="Multiply value of attribute.");
Argument hide(AT_Boolean, "False", doc="If the planet has _no_ cargo of this type, hide the project.");
double getCost(Empire& emp) {
return base_amount.decimal + emp.getAttribute(attribute.integer) * multiply.decimal;
}
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(!obj.hasCargo)
return false;
double val = obj.getCargoStored(type.integer);
if(hide.boolean && val < 0.001)
return false;
if(ignoreCost)
return true;
return val >= getCost(obj.owner);
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = standardize(getCost(obj.owner), true)+" "+getCargoType(type.integer).name;
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(getCost(obj.owner), true);
icon = getCargoType(type.integer).icon;
return true;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
auto@ cargo = getCargoType(type.integer);
value = standardize(getCost(obj.owner), true);
sprt = cargo.icon;
name = cargo.name + " "+locale::COST;
color = cargo.color;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
double cost = getCost(obj.owner);
double consAmt = obj.consumeCargo(type.integer, cost, partial=false);
return consAmt >= cost - 0.001;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
obj.addCargo(type.integer, getCost(obj.owner));
}
#section all
};
class ConsumeCargoStatusCount : ConsumeEffect {
Document doc("Requires a payment of cargo to build this construction, based on the amount of stacks of a status present.");
Argument type(AT_Cargo, doc="Type of cargo to take.");
Argument status(AT_Status, doc="Status to count.");
Argument amount(AT_Decimal, doc="Amount of cargo taken to build per status.");
Argument hide(AT_Boolean, "False", doc="If the planet has _no_ cargo of this type, hide the project.");
Argument allow_cancel(AT_Boolean, "False", doc="Refund the cost when canceling. Only use in specific circumstances when you know the status doesn't get added any other way.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(!obj.hasCargo)
return false;
double val = obj.getCargoStored(type.integer);
if(hide.boolean && val < 0.001)
return false;
if(ignoreCost)
return true;
return val >= get(obj);
}
double get(Object& obj) const {
return amount.decimal * obj.getStatusStackCountAny(status.integer);
}
bool formatCost(Object& obj, const Targets@ targs, string& value) const {
value = standardize(get(obj), true)+" "+getCargoType(type.integer).name;
return true;
}
bool getCost(Object& obj, string& value, Sprite& icon) const {
value = standardize(get(obj), true);
icon = getCargoType(type.integer).icon;
return true;
}
bool getVariable(Object& obj, Sprite& sprt, string& name, string& value, Color& color) const {
auto@ cargo = getCargoType(type.integer);
value = standardize(get(obj), true);
sprt = cargo.icon;
name = cargo.name + " "+locale::COST;
color = cargo.color;
return true;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
double consAmt = obj.consumeCargo(type.integer, get(obj), partial=false);
return consAmt >= amount.decimal - 0.001;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
double consAmt = get(obj);
if(!cancel || allow_cancel.boolean)
obj.addCargo(type.integer, consAmt);
}
#section all
};
class ConsumeStatus : ConsumeEffect {
Document doc("Consumes an instance of a status on the object.");
Argument type(AT_Status, doc="Type of status to take.");
Argument amount(AT_Integer, "1", doc="Amount of cargo taken to build per status.");
Argument hide(AT_Boolean, "False", doc="If the object has _no_ statuses of this type, hide the option.");
bool canConsume(Object& obj, const Targets@ targs, bool ignoreCost) const {
if(!obj.hasStatuses)
return false;
int val = obj.getStatusStackCountAny(type.integer);
if(hide.boolean && val < amount.integer)
return false;
if(ignoreCost)
return true;
return val >= amount.integer;
}
#section server
bool consume(Object& obj, const Targets@ targs) const override {
int count = obj.getStatusStackCount(type.integer);
if(count < amount.integer)
return false;
for(int i = 0; i < amount.integer; ++i)
obj.removeStatusInstanceOfType(type.integer);
return true;
}
void reverse(Object& obj, const Targets@ targs, bool cancel) const override {
obj.addStatus(type.integer);
}
#section all
};