2057 lines
57 KiB
ActionScript
2057 lines
57 KiB
ActionScript
import buildings;
|
|
from buildings import IBuildingHook;
|
|
import resources;
|
|
import util.formatting;
|
|
import systems;
|
|
import saving;
|
|
from statuses import IStatusHook, Status, StatusInstance;
|
|
from resources import integerSum, decimalSum;
|
|
import planet_types;
|
|
import planet_levels;
|
|
import generic_effects;
|
|
import hook_globals;
|
|
|
|
//AddPressureCap(<Amount>)
|
|
// Give <amount> extra pressure cap on the planet.
|
|
class AddPressureCap : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the planet's total pressure capacity.");
|
|
Argument amount(AT_Integer, doc="Amount of pressure capacity to add.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPosEffect(locale::EFFECT_ADDPRESSURECAP, "+"+integerSum(hooks, 0));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modPressureCapMod(+arguments[0].integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modPressureCapMod(-arguments[0].integer);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModPressureCapMult(<Percentage>)
|
|
// Give <Percentage> extra base pressure cap on the planet.
|
|
class ModPressureCapMult : GenericEffect, TriggerableGeneric {
|
|
Document doc("Add to the planet's pressure cap multiplier.");
|
|
Argument amount(AT_Decimal, doc="Percentage increase to pressure cap. eg. 0.3 for +30% pressure cap.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modPressureCapFactor(+arguments[0].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modPressureCapFactor(-arguments[0].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModCivResourceMult(<Resource>, <Percentage>)
|
|
// Add <Percentage> to the civilian <Resource> multiplier.
|
|
class ModCivResourceMult : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the civilian resource production multiplier for a particular type of income.");
|
|
Argument type(AT_TileResource, doc="Which income to modify the multiplier for.");
|
|
Argument amount(AT_Decimal, doc="Percentage increase to the income multiplier. eg. 0.15 for +15% income.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
bool mergesEffect(const GenericEffect@ eff) const {
|
|
return eff.arguments[0].integer == arguments[0].integer;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPctEffect(format(locale::EFFECT_MODCIVRESOURCE,
|
|
getTileResourceName(arguments[0].integer)), decimalSum(hooks, 1));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modCivResourceMod(arguments[0].integer, +arguments[1].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modCivResourceMod(arguments[0].integer, -arguments[1].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModTerraformCost(<Percentage>)
|
|
// Modify the cost to terraform things *with* this planet by <Percentage>.
|
|
class ModTerraformCost : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the terraform cost multiplier for terraforming other planets with this object.");
|
|
Argument amount(AT_Decimal, doc="Percentage increase to the terraform cost multiplier. eg. -0.5 for -50% terraform cost.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modTerraformCostMod(+arguments[0].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modTerraformCostMod(-arguments[0].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModPopulationGrowth(<Percentage>)
|
|
// Modify the population growth rate by an amount.
|
|
class ModPopulationGrowth : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the population growth multiplier on this planet.");
|
|
Argument amount(AT_Decimal, doc="Percentage increase to the population growth multiplier. eg. 0.1 for +10% population growth.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modGrowthRate(+arguments[0].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modGrowthRate(-arguments[0].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModTileDevelopRate(<Percentage>)
|
|
// Modify the tile development rate by an amount.
|
|
class ModTileDevelopRate : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the tile development rate multiplier on this planet.");
|
|
Argument amount(AT_Decimal, doc="Percentage increase to the tile development rate multiplier. eg. 0.25 for +25% tile development speed.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modTileDevelopRate(+arguments[0].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modTileDevelopRate(-arguments[0].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModBuildingConstructRate(<Percentage>)
|
|
// Modify the building construction rate by an amount.
|
|
class ModBuildingConstructRate : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the building construction speed multiplier on this planet.");
|
|
Argument amount(AT_Decimal, doc="Percentage increase to the builing construction speed multiplier. eg. 0.25 for +25% building construction speed.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modBuildingConstructRate(+arguments[0].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modBuildingConstructRate(-arguments[0].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddBuildingMaintenanceRefund(<Amount>)
|
|
// Reduces the total maintenance of buildings by a flat <Amount>.
|
|
class AddBuildingMaintenanceRefund : GenericEffect, TriggerableGeneric {
|
|
Document doc("Decrease the total maintenance cost of buildings on this planet by a static amount.");
|
|
Argument amount(AT_Integer, doc="Amount of money to decrease the total maintenance cost by.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
int totalReduction = integerSum(hooks, 0);
|
|
int remaining = 0;
|
|
|
|
if(obj.isPlanet && obj.owner is playerEmpire)
|
|
remaining = obj.buildingMaintenance;
|
|
|
|
string eff;
|
|
if(totalReduction > 10000000) {
|
|
if(remaining == 0)
|
|
eff = "-"+formatMoney(0);
|
|
else
|
|
eff = "-"+formatMoney(totalReduction + remaining);
|
|
}
|
|
else {
|
|
if(remaining < 0) {
|
|
int used = totalReduction + remaining;
|
|
if(used != 0) {
|
|
eff = format("-$1 [color=#fe4]($2)[/color]",
|
|
formatMoney(used),
|
|
formatMoney(-remaining));
|
|
}
|
|
else {
|
|
eff = format("[color=#fe4]($1)[/color]",
|
|
formatMoney(-remaining));
|
|
}
|
|
}
|
|
else
|
|
eff = "-"+formatMoney(totalReduction);
|
|
}
|
|
return formatPosEffect(locale::EFFECT_BLDMAINTREFUND, eff);
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modBuildingMaintenanceRefund(+arguments[0].integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modBuildingMaintenanceRefund(-arguments[0].integer);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddResourceVanishBonus(<Percentage>)
|
|
// Increases the amount of time temporary resources have on this planet by <Percentage>.
|
|
class AddResourceVanishBonus : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increases the amount of time temporary resources consumed by this planet stay active.");
|
|
Argument amount(AT_Decimal, doc="Percentage increase to the temporary resource time. eg. 0.4 for +40% resource time.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPctEffect(locale::EFFECT_VANISHBONUS, decimalSum(hooks, 0), locale::MOD_TIME);
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modResourceVanishBonus(+arguments[0].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modResourceVanishBonus(-arguments[0].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//GiveNativePressure(<Amount>)
|
|
// Give the consuming planet <Amount> extra pressure in its native resource's type
|
|
class GiveNativePressure : GenericEffect {
|
|
Document doc("Give the consuming planet extra pressure of the primary type of pressure its native resource gives.");
|
|
Argument amount(AT_Integer, doc="Amount of extra pressure to give.");
|
|
Argument allow_money(AT_Boolean, "True", doc="Whether to allow giving extra money pressure.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.nativeResourceCount > 0) {
|
|
const ResourceType@ res = getResource(obj.nativeResourceType[0]);
|
|
if(res !is null) {
|
|
int64 resource = -1;
|
|
int best = 0;
|
|
for(uint i = allow_money.boolean ? 0 : 1; i < TR_COUNT; ++i) {
|
|
if(res.tilePressure[i] > best) {
|
|
best = res.tilePressure[i];
|
|
resource = int(i);
|
|
}
|
|
}
|
|
|
|
if(resource != -1)
|
|
obj.modPressure(uint(resource), +arguments[0].integer);
|
|
data.store(resource);
|
|
}
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
int64 reso = -1;
|
|
data.retrieve(reso);
|
|
if(reso != -1)
|
|
obj.modPressure(uint(reso), -arguments[0].integer);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
int64 reso = -1;
|
|
data.retrieve(reso);
|
|
file << reso;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
int64 reso = -1;
|
|
file >> reso;
|
|
data.store(reso);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class GiveNativeProduction : GenericEffect {
|
|
Document doc("Give the consuming planet extra production of the primary type of pressure its native resource gives.");
|
|
Argument amount(AT_Integer, doc="Amount of extra production to give.");
|
|
Argument allow_money(AT_Boolean, "True", doc="Whether to allow giving extra money pressure.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.nativeResourceCount > 0) {
|
|
const ResourceType@ res = getResource(obj.nativeResourceType[0]);
|
|
if(res !is null) {
|
|
int64 resource = -1;
|
|
int best = 0;
|
|
for(uint i = allow_money.boolean ? 0 : 1; i < TR_COUNT; ++i) {
|
|
if(res.tilePressure[i] > best) {
|
|
best = res.tilePressure[i];
|
|
resource = int(i);
|
|
}
|
|
}
|
|
|
|
if(resource != -1)
|
|
obj.modResource(uint(resource), +arguments[0].integer);
|
|
data.store(resource);
|
|
}
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
int64 reso = -1;
|
|
data.retrieve(reso);
|
|
if(reso != -1)
|
|
obj.modResource(uint(reso), -arguments[0].integer);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
int64 reso = -1;
|
|
data.retrieve(reso);
|
|
file << reso;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
int64 reso = -1;
|
|
file >> reso;
|
|
data.store(reso);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//GiveResourcePressure(<Tile Resource>, <Factor>, <Level Filter> = -1)
|
|
// Give the consuming planet <Factor> extra pressure on all its resources.
|
|
class GiveExtraResourcePressure : GenericEffect {
|
|
Document doc("Multiply the pressure each of resources consumed by the planet gives of a particular type.");
|
|
Argument type(AT_TileResource, doc="Type of pressure to multiply.");
|
|
Argument factor(AT_Decimal, doc="Percentage increase to the pressure given. eg. 0.2 for a +20% increase in pressure.");
|
|
Argument level_filter(AT_Integer, "-1", doc="If not -1, only resources of the indicated level receive bonus pressure.");
|
|
Argument allow_uniques(AT_Boolean, "True", doc="If set to false, unique resources will not be boosted by this.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
int reso = 0;
|
|
data.store(reso);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
int current = 0;
|
|
data.retrieve(current);
|
|
|
|
double newValue = 0;
|
|
int resType = arguments[0].integer;
|
|
double factor = arguments[1].decimal;
|
|
int level = arguments[2].integer;
|
|
for(uint i = 0, cnt = obj.availableResourceCount; i < cnt; ++i) {
|
|
if(!obj.availableResourceUsable[i])
|
|
continue;
|
|
auto@ type = getResource(obj.availableResourceType[i]);
|
|
if(type is null)
|
|
continue;
|
|
if(level != -1 && level != int(type.level))
|
|
continue;
|
|
if(!allow_uniques.boolean && (type.unique || type.rarity == RR_Unique))
|
|
continue;
|
|
newValue += double(type.tilePressure[resType]) * factor;
|
|
}
|
|
|
|
int nextValue = int(newValue);
|
|
if(current != nextValue) {
|
|
obj.modPressure(resType, nextValue - current);
|
|
data.store(nextValue);
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
int reso = -1;
|
|
data.retrieve(reso);
|
|
if(reso > 0)
|
|
obj.modPressure(arguments[0].integer, -reso);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
int reso = -1;
|
|
data.retrieve(reso);
|
|
file << reso;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
int reso = -1;
|
|
file >> reso;
|
|
data.store(reso);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class AddPressurePerAffinity : GenericEffect {
|
|
Document doc("For every affinity of a particular type, add an amount of pressure.");
|
|
Argument affinity_type(AT_TileResource, doc="Affinity type to check for.");
|
|
Argument pressure_type(AT_TileResource, doc="Type of pressure to generate.");
|
|
Argument amount(AT_Decimal, "1", doc="Amount of pressure to add per affinity.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
int amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent) {
|
|
int amt = 0;
|
|
data.retrieve(amt);
|
|
if(amt != 0)
|
|
obj.modPressure(pressure_type.integer, -amt);
|
|
}
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double tick) const override {
|
|
if(obj.hasSurfaceComponent) {
|
|
int amt = 0;
|
|
data.retrieve(amt);
|
|
|
|
int newAmt = double(obj.getAffinitiesMatching(affinity_type.integer)) * amount.decimal;
|
|
if(amt != newAmt) {
|
|
obj.modPressure(pressure_type.integer, newAmt - amt);
|
|
data.store(newAmt);
|
|
}
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
int amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
int amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModColonyShipAccel(<Percentage>)
|
|
// Colony ships leaving the consuming planet accelerate <Percentage> faster.
|
|
class ModColonyShipAccel : GenericEffect, TriggerableGeneric {
|
|
Document doc("Multiply the acceleration of outgoing colony ships from this planet by a factor.");
|
|
Argument multiplier(AT_Decimal, "1.0", doc="Multiplier to the acceleration.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPctEffect(locale::PEKELM_EFFECT, decimalSum(hooks, 0));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modColonyShipAccel(arguments[0].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modColonyShipAccel(1.0/arguments[0].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModLoyalty(<Amount>)
|
|
// Add <Amount> extra loyalty to the consuming planet.
|
|
class ModLoyalty : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the loyalty of this planet.");
|
|
Argument amount(AT_Integer, doc="Amount of extra loyalty to give.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPosEffect(locale::SPICE_EFFECT, "+"+integerSum(hooks, 0));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modBaseLoyalty(+arguments[0].integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modBaseLoyalty(-arguments[0].integer);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddPressure(<Resource>, <Amount>)
|
|
// Adds <Amount> <Resource> pressure.
|
|
class AddPressure : GenericEffect, TriggerableGeneric {
|
|
Document doc("Add extra pressure to this planet.");
|
|
Argument type(AT_TileResource, doc="Type of pressure to give.");
|
|
Argument amount(AT_Integer, doc="Amount of pressure.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
bool mergesEffect(const GenericEffect@ eff) const override {
|
|
return eff.arguments[0].integer == arguments[0].integer;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPosEffect(format(locale::EFFECT_ADDPRESSURE,
|
|
getTileResourceName(arguments[0].integer)), "+"+integerSum(hooks, 1));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modPressure(arguments[0].integer, +arguments[1].integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modPressure(arguments[0].integer, -arguments[1].integer);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddResource(<Resource>, <Amount>)
|
|
// Add the equivalent of <Amount> pressure in <Resource> production.
|
|
class AddResource : GenericEffect, TriggerableGeneric {
|
|
Document doc("Add free resource production equivalent to an amount of pressure to this planet.");
|
|
Argument type(AT_TileResource, doc="Type of resource income.");
|
|
Argument amount(AT_Decimal, doc="Amount of pressure to give the equivalent resource production for.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
bool mergesEffect(const GenericEffect@ eff) const override {
|
|
return eff.arguments[0].integer == arguments[0].integer;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPosEffect(format(locale::EFFECT_ADDRESOURCE,
|
|
getTileResourceName(arguments[0].integer)), "+"+integerSum(hooks, 1));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modResource(arguments[0].integer, +arguments[1].decimal);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modResource(arguments[0].integer, -arguments[1].decimal);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class AddIncome : GenericEffect, TriggerableGeneric {
|
|
Document doc("Change the planet's income by an amount.");
|
|
Argument amount(AT_Integer, doc="Amount of income to change the planet's income by.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.modIncome(+amount.integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.modIncome(-amount.integer);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddResourceEmpireAttribute(<Resource>, <Attribute>)
|
|
// Add resource production from an empire attribute.
|
|
class AddResourceEmpireAttribute : GenericEffect {
|
|
Document doc("Add free resource production based on an equivalent amount of pressure stored in an empire attribute.");
|
|
Argument type(AT_TileResource, doc="Type of resource income.");
|
|
Argument attribute(AT_EmpAttribute, doc="Empire attribute to take the amount of income from, can be set to any arbitrary name to be created as a new attribute with starting value 0.");
|
|
Argument multiplier(AT_Decimal, "1.0", doc="Multiplier to amount of resource to generate.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double value = 0;
|
|
data.store(value);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
double value = 0;
|
|
data.retrieve(value);
|
|
|
|
Empire@ owner = obj.owner;
|
|
double newValue = 0;
|
|
if(owner !is null)
|
|
newValue = owner.getAttribute(arguments[1].integer) * multiplier.decimal;
|
|
if(newValue != value) {
|
|
obj.modResource(arguments[0].integer, newValue - value);
|
|
data.store(newValue);
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double value = 0;
|
|
data.retrieve(value);
|
|
if(obj.isPlanet)
|
|
obj.modResource(arguments[0].integer, -value);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class AddPressureEmpireAttribute : GenericEffect {
|
|
Document doc("Add pressure based on an empire attribute.");
|
|
Argument type(AT_TileResource, doc="Type of resource to add pressure for.");
|
|
Argument attribute(AT_EmpAttribute, doc="Empire attribute to take the amount of income from, can be set to any arbitrary name to be created as a new attribute with starting value 0.");
|
|
Argument multiplier(AT_Decimal, "1.0", doc="Multiplier to amount of resource to generate.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
int value = 0;
|
|
data.store(value);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
double value = 0;
|
|
data.retrieve(value);
|
|
|
|
Empire@ owner = obj.owner;
|
|
int newValue = 0;
|
|
if(owner !is null)
|
|
newValue = int(floor(owner.getAttribute(attribute.integer) * multiplier.decimal));
|
|
if(newValue != value) {
|
|
obj.modPressure(type.integer, newValue - value);
|
|
data.store(newValue);
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
int value = 0;
|
|
data.retrieve(value);
|
|
if(obj.isPlanet)
|
|
obj.modPressure(type.integer, -value);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
int amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
int amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddResourceFromGlobal(<Resource>, <Global>, <Factor> = 1.0)
|
|
// Add resource production from an empire attribute.
|
|
class AddResourceFromGlobal : GenericEffect {
|
|
Document doc("Add free resource production based on an equivalent amount of pressure stored in a global value.");
|
|
Argument type(AT_TileResource, doc="Type of resource income.");
|
|
Argument global(AT_Global, doc="Global variable to take value from.");
|
|
Argument factor(AT_Decimal, "1.0", doc="Multiplication factor to the global's value to give in pressure-equivalent income.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double value = 0;
|
|
data.store(value);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
double value = 0;
|
|
data.retrieve(value);
|
|
|
|
double newValue = getGlobal(arguments[1].integer).value * arguments[2].decimal;
|
|
if(newValue != value) {
|
|
obj.modResource(arguments[0].integer, newValue - value);
|
|
data.store(newValue);
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double value = 0;
|
|
data.retrieve(value);
|
|
if(obj.isPlanet)
|
|
obj.modResource(arguments[0].integer, -value);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddResourceFromLevel(<Resource>, <Base> = 0.0, <Factor> = 1.0)
|
|
// Add resource production related to the planet level.
|
|
class AddResourceFromLevel : GenericEffect {
|
|
Document doc("Add free resource production based on the planet's level.");
|
|
Argument type(AT_TileResource, doc="Type of resource income.");
|
|
Argument base(AT_Decimal, "0.0", doc="Base amount of pressure-equilavent income to give.");
|
|
Argument factor(AT_Decimal, "1.0", doc="Multiplication factor to the planet's level to give in pressure-equivalent income.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double value = 0;
|
|
data.store(value);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
double value = 0;
|
|
data.retrieve(value);
|
|
|
|
double newValue = arguments[1].decimal + arguments[2].decimal * obj.level;
|
|
if(newValue != value) {
|
|
obj.modResource(arguments[0].integer, newValue - value);
|
|
data.store(newValue);
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double value = 0;
|
|
data.retrieve(value);
|
|
if(obj.isPlanet)
|
|
obj.modResource(arguments[0].integer, -value);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddMaxPopulation(<Amount>)
|
|
// Add <Amount> maximum population to the planet.
|
|
class AddMaxPopulation : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the planet's maximum population.");
|
|
Argument amount(AT_Integer, doc="Amount of extra maximum population.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modMaxPopulation(arguments[0].integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modMaxPopulation(-arguments[0].integer);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddOverpopulation(<Amount>)
|
|
// Add <Amount> overpopulation to the planet.
|
|
class AddOverpopulation : GenericEffect, TriggerableGeneric {
|
|
Document doc("Increase the planet's overpopulation.");
|
|
Argument amount(AT_Integer, doc="Amount of extra overpopulation.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPosEffect(locale::EFFECT_OVERPOPULATION, toString(integerSum(hooks, 0)));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modOverpopulation(+arguments[0].integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet)
|
|
obj.modOverpopulation(-arguments[0].integer);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//PerResourceAddResource(<Planet Resource>, <Amount>, <Tile Resource>)
|
|
// Adds <Tile Resource> generation equivalent to <Amount> pressure for every
|
|
// <Planet Resource> available on the planet.
|
|
class PerResourceAddResource : GenericEffect {
|
|
Document doc("Add free resource income for every planetary resource of a particular type being consumed on the planet.");
|
|
Argument resource(AT_PlanetResource, doc="Type of planetary resource to count.");
|
|
Argument factor(AT_Decimal, doc="Multiplier to the amount of planetary resources to give in pressure-equivalent income.");
|
|
Argument income(AT_TileResource, doc="Type of income to generate.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
bool mergesEffect(const GenericEffect@ eff) const override {
|
|
return eff.arguments[0].integer == arguments[0].integer
|
|
&& arguments[2].integer == arguments[2].integer;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
return formatPosEffect(format(locale::EFFECT_ADDRESOURCE,
|
|
getTileResourceName(arguments[2].integer)),
|
|
"+"+(decimalSum(hooks, 1) * obj.getAvailableResourceAmount(arguments[0].integer)));
|
|
}
|
|
|
|
#section server
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.isPlanet) {
|
|
int64 prev = 0;
|
|
data.retrieve(prev);
|
|
|
|
int64 resCnt = obj.getAvailableResourceAmount(arguments[0].integer);
|
|
if(resCnt != prev) {
|
|
data.store(resCnt);
|
|
obj.modResource(arguments[2].integer, double(resCnt - prev) * arguments[1].decimal);
|
|
}
|
|
}
|
|
}
|
|
|
|
void enable(Object& obj, any@ data) const override {
|
|
int64 amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
int64 amt = 0;
|
|
data.retrieve(amt);
|
|
obj.modResource(arguments[2].integer, -double(amt) * arguments[1].decimal);
|
|
|
|
amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const {
|
|
int64 amt = 0;
|
|
data.retrieve(amt);
|
|
|
|
file << int(amt);
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const {
|
|
int amt = 0;
|
|
file >> amt;
|
|
|
|
data.store(int64(amt));
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ModExistingResource(<Tile Resource>, <Amount>)
|
|
// Adds <Tile Resource> generation equivalent to <Amount> pressure
|
|
// if the resource is being produced at all. Resources cannot drop below 0.
|
|
class ModExistingResource : GenericEffect {
|
|
Document doc("Modify a particular type of income on this planet, but only if that income is non-zero to begin with.");
|
|
Argument income(AT_TileResource, doc="Type of income to modify.");
|
|
Argument amount(AT_Decimal, doc="Amount of pressure-equivalent income to add or subtract.");
|
|
|
|
#section server
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.isPlanet) {
|
|
double cur = 0;
|
|
data.retrieve(cur);
|
|
|
|
double production = obj.getResourceProduction(arguments[0].integer);
|
|
double next = 0;
|
|
double mod = arguments[1].decimal;
|
|
double net = production - cur;
|
|
|
|
if(mod > 0) {
|
|
if(net > 0)
|
|
next = mod;
|
|
else
|
|
next = 0;
|
|
}
|
|
else {
|
|
if(net >= 0)
|
|
next = max(-net, mod);
|
|
else
|
|
next = 0;
|
|
}
|
|
|
|
if(next != cur) {
|
|
obj.modResource(arguments[0].integer, next - cur);
|
|
data.store(next);
|
|
}
|
|
}
|
|
}
|
|
|
|
void enable(Object& obj, any@ data) const override {
|
|
double amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
if(obj.isPlanet)
|
|
obj.modResource(arguments[0].integer, -amt);
|
|
|
|
amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ModExistingPressure : GenericEffect {
|
|
Document doc("Modify a particular type of pressure on this planet, but only if that pressure is non-zero to begin with.");
|
|
Argument income(AT_TileResource, doc="Type of pressure to modify.");
|
|
Argument amount(AT_Decimal, doc="Amount of pressure to add or subtract.");
|
|
|
|
#section server
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.isPlanet) {
|
|
double cur = 0;
|
|
data.retrieve(cur);
|
|
|
|
double production = obj.getResourcePressure(arguments[0].integer);
|
|
double next = 0;
|
|
double mod = arguments[1].decimal;
|
|
double net = production - cur;
|
|
|
|
if(mod > 0) {
|
|
if(net > 0)
|
|
next = mod;
|
|
else
|
|
next = 0;
|
|
}
|
|
else {
|
|
if(net >= 0)
|
|
next = max(-net, mod);
|
|
else
|
|
next = 0;
|
|
}
|
|
|
|
if(next != cur) {
|
|
obj.modPressure(arguments[0].integer, next - cur);
|
|
data.store(next);
|
|
}
|
|
}
|
|
}
|
|
|
|
void enable(Object& obj, any@ data) const override {
|
|
double amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
if(obj.isPlanet)
|
|
obj.modPressure(arguments[0].integer, -amt);
|
|
|
|
amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ModPressurePct : GenericEffect {
|
|
Document doc("Modify the amount of pressure on the planet of a type by a percentage.");
|
|
Argument income(AT_TileResource, doc="Type of pressure to modify.");
|
|
Argument amount(AT_Decimal, doc="Percentage of pressure to add or subtract.");
|
|
Argument min_amount(AT_Integer, "0", doc="Minimum change to pressure.");
|
|
|
|
#section server
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.isPlanet) {
|
|
double cur = 0;
|
|
data.retrieve(cur);
|
|
|
|
double production = obj.getResourcePressure(income.integer);
|
|
double net = production - cur;
|
|
double next = 0;
|
|
double mod = round((production - cur) * amount.decimal);
|
|
if(min_amount.integer < 0 && net != 0)
|
|
mod = min(double(min_amount.integer), mod);
|
|
else if(min_amount.integer > 0 && net != 0)
|
|
mod = max(double(min_amount.integer), mod);
|
|
|
|
if(mod > 0) {
|
|
if(net > 0)
|
|
next = mod;
|
|
else
|
|
next = 0;
|
|
}
|
|
else {
|
|
if(net >= 0)
|
|
next = max(-net, mod);
|
|
else
|
|
next = 0;
|
|
}
|
|
|
|
if(next != cur) {
|
|
obj.modPressure(income.integer, next - cur);
|
|
data.store(next);
|
|
}
|
|
}
|
|
}
|
|
|
|
void enable(Object& obj, any@ data) const override {
|
|
double amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
if(obj.isPlanet)
|
|
obj.modPressure(income.integer, -amt);
|
|
|
|
amt = 0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//PerIncomeAddResource(<Tile Resource>, <Amount>, <Tile Resource>)
|
|
// Adds <Tile Resource> generation equivalent to <Amount> pressure for every
|
|
// <Tile Resource> being generated on the planet.
|
|
class PerIncomeAddResource : GenericEffect {
|
|
Document doc("Add free resource income for every resource income of a particular type being generated on this planet.");
|
|
Argument resource(AT_TileResource, doc="Type of income resource to count.");
|
|
Argument factor(AT_Decimal, doc="Multiplier to the amount of income resource already generated to give in pressure-equivalent income.");
|
|
Argument income(AT_TileResource, doc="Type of income to generate.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double amt = 0.0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet) {
|
|
double amt = 0.0;
|
|
data.retrieve(amt);
|
|
if(amt != 0.0)
|
|
obj.modResource(arguments[2].integer, -amt);
|
|
}
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double tick) const override {
|
|
if(obj.isPlanet) {
|
|
double amt = 0.0;
|
|
data.retrieve(amt);
|
|
|
|
double newAmt = obj.getResourceProduction(arguments[0].integer) * arguments[1].decimal;
|
|
if(amt != newAmt) {
|
|
obj.modResource(arguments[2].integer, newAmt - amt);
|
|
data.store(newAmt);
|
|
}
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double amt = 0.0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double amt = 0.0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//PerPopulationAddResource(<Tile Resource>, <Amount>)
|
|
// Adds <Tile Resource> generation equivalent to <Amount> pressure for every
|
|
// population on the planet.
|
|
class PerPopulationAddResource : GenericEffect {
|
|
Document doc("Add free resource income based on the planet's current population.");
|
|
Argument factor(AT_Decimal, doc="Multiplier to the planet's current population to give in pressure-equivalent income.");
|
|
Argument income(AT_TileResource, doc="Type of income to generate.");
|
|
Argument overpop_factor(AT_Boolean, "True", doc="Whether to account for the race's OverpopulationBenefitFactor for overpopulation.");
|
|
Argument ignore_first(AT_Decimal, "0", doc="Ignore this amount of population before adding for the remaining population.");
|
|
|
|
bool get_hasEffect() const override {
|
|
return true;
|
|
}
|
|
|
|
bool mergesEffect(const GenericEffect@ eff) const override {
|
|
return eff.arguments[1].integer == arguments[1].integer;
|
|
}
|
|
|
|
string formatEffect(Object& obj, array<const IResourceHook@>& hooks) const override {
|
|
if(arguments[0].integer == TR_Money)
|
|
return formatPosEffect(format(locale::EFFECT_ADDRESOURCE,
|
|
getTileResourceName(arguments[0].integer)),
|
|
"+"+formatMoney(decimalSum(hooks, 1) * obj.population * 100.0));
|
|
else
|
|
return formatMagEffect(format(locale::EFFECT_ADDRESOURCE,
|
|
getTileResourceName(arguments[0].integer)),
|
|
(decimalSum(hooks, 1) * obj.population));
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double amt = 0.0;
|
|
data.store(amt);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.isPlanet) {
|
|
double amt = 0.0;
|
|
data.retrieve(amt);
|
|
if(amt != 0.0)
|
|
obj.modResource(arguments[1].integer, -amt);
|
|
}
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double tick) const override {
|
|
if(obj.isPlanet) {
|
|
double amt = 0.0;
|
|
data.retrieve(amt);
|
|
|
|
double pop = max(obj.population - ignore_first.decimal, 0.0);
|
|
double newAmt = pop * arguments[0].decimal;
|
|
if(overpop_factor.boolean) {
|
|
double maxPop = obj.maxPopulation;
|
|
if(pop > maxPop)
|
|
newAmt = (maxPop + (pop - maxPop) * obj.owner.OverpopulationBenefitFactor) * arguments[0].decimal;
|
|
}
|
|
if(amt != newAmt) {
|
|
obj.modResource(arguments[1].integer, newAmt - amt);
|
|
data.store(newAmt);
|
|
}
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double amt = 0.0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double amt = 0.0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddDummyResource(<Planet Resource>, <Amount>)
|
|
// Add <Amount> <Planet Resource>s solely for the purpose of requirement resolution.
|
|
class AddDummyResource : GenericEffect, TriggerableGeneric {
|
|
Document doc("Add a dummy resource of a particular type. Dummy resources are not listed and have no effects except for being usable for planet levelup.");
|
|
Argument resource(AT_PlanetResource, doc="Type of planetary resource to add a dummy of.");
|
|
Argument amount(AT_Integer, "1", doc="Amount of dummy resources of that type to add.");
|
|
Argument base_chain_only(AT_Boolean, "False", doc="Only add this dummy resource if the planet is using the base levelup chain.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(!base_chain_only.boolean || obj.levelChain == baseLevelChain.id)
|
|
obj.modDummyResource(arguments[0].integer, +arguments[1].integer, true);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(!base_chain_only.boolean || obj.levelChain == baseLevelChain.id)
|
|
obj.modDummyResource(arguments[0].integer, -arguments[1].integer, true);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ConvertToFTL(<Tile Resource>, <Rate>)
|
|
// Convert all <Tile Resource> income into FTL income at <Rate>.
|
|
class ConvertToFTL : GenericEffect {
|
|
Document doc("Convert all income of a particular type to FTL generation.");
|
|
Argument type(AT_TileResource, doc="Type of income to convert.");
|
|
Argument factor(AT_Decimal, doc="Every pressure-equivalent income of the given type is converted to this much FTL per second.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double current = 0.0;
|
|
data.store(current);
|
|
|
|
obj.modCivResourceMod(arguments[0].integer, -1.f);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double current = 0.0;
|
|
data.retrieve(current);
|
|
|
|
if(current > 0) {
|
|
if(obj.owner !is null && obj.owner.valid)
|
|
obj.owner.modFTLIncome(-current);
|
|
}
|
|
|
|
obj.modCivResourceMod(arguments[0].integer, +1.f);
|
|
}
|
|
|
|
void ownerChange(Object& obj, any@ data, Empire@ prevOwner, Empire@ newOwner) const override {
|
|
double current = 0.0;
|
|
data.retrieve(current);
|
|
|
|
if(current > 0) {
|
|
if(prevOwner !is null && prevOwner.valid)
|
|
prevOwner.modFTLIncome(-current);
|
|
if(newOwner !is null && newOwner.valid)
|
|
newOwner.modFTLIncome(+current);
|
|
}
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
double newIncome = obj.getCivilianProduction(arguments[0].integer) * arguments[1].decimal;
|
|
double current = 0.0;
|
|
data.retrieve(current);
|
|
|
|
if(current != newIncome) {
|
|
obj.owner.modFTLIncome(newIncome - current);
|
|
current = newIncome;
|
|
data.store(current);
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double current = 0.0;
|
|
data.retrieve(current);
|
|
file << current;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double current = 0.0;
|
|
file >> current;
|
|
data.store(current);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//ConvertResource(<Tile Resource>, <Rate>, <Tile Resource>)
|
|
// Convert all civilian <Tile Resource> income into <Tile Resource> income at <Rate>.
|
|
tidy final class ConvertData {
|
|
double taken = 0.0;
|
|
double given = 0.0;
|
|
};
|
|
class ConvertResource : GenericEffect {
|
|
Document doc("Convert all civilian income of a particular type to income of a different type.");
|
|
Argument resource(AT_TileResource, doc="Type of income resource to convert.");
|
|
Argument factor(AT_Decimal, doc="Multiplier to the amount of income taken away.");
|
|
Argument income(AT_TileResource, doc="Type of income to generate, after multiplication.");
|
|
Argument maximum_converted(AT_Decimal, "-1", doc="Maximum amount of resource of the first type that is converted.");
|
|
Argument convert_percent(AT_Decimal, "1", doc="Percentage of the original resource to be converted. The rest is left alone.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
ConvertData info;
|
|
data.store(@info);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
ConvertData@ info;
|
|
data.retrieve(@info);
|
|
|
|
if(info.given > 0)
|
|
obj.modResource(income.integer, -info.given);
|
|
if(info.taken > 0)
|
|
obj.modResource(resource.integer, +info.taken);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
ConvertData@ info;
|
|
data.retrieve(@info);
|
|
|
|
//Check rate
|
|
double curProd = obj.getResourceProduction(resource.integer);
|
|
double total = info.taken + curProd;
|
|
|
|
double target = total - (total * (1.0 - convert_percent.decimal));
|
|
target = clamp(target, 0.0, total);
|
|
|
|
double newTaken = total - target;
|
|
if(maximum_converted.decimal >= 0)
|
|
newTaken = min(newTaken, maximum_converted.decimal);
|
|
|
|
if(newTaken != info.taken) {
|
|
obj.modResource(resource.integer, -(newTaken - info.taken));
|
|
info.taken = newTaken;
|
|
}
|
|
|
|
double newGiven = newTaken * factor.decimal;
|
|
if(newGiven != info.given) {
|
|
obj.modResource(income.integer, newGiven - info.given);
|
|
info.given = newGiven;
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
ConvertData@ info;
|
|
data.retrieve(@info);
|
|
file << info.given;
|
|
file << info.taken;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
ConvertData info;
|
|
if(file >= SV_0079) {
|
|
file >> info.given;
|
|
file >> info.taken;
|
|
}
|
|
else {
|
|
double current = 0;
|
|
double rate = 0;
|
|
file >> current;
|
|
if(file >= SV_0049)
|
|
file >> rate;
|
|
}
|
|
data.store(@info);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddToNativeResource(<Hook>(..))
|
|
// Adds the inner effect hook to where the native resource is going.
|
|
tidy final class AddToNativeData {
|
|
Object@ current;
|
|
any data;
|
|
};
|
|
|
|
tidy final class AddToNativeResource : GenericEffect {
|
|
GenericEffect@ hook;
|
|
|
|
Document doc("The inner hook is executed from the context of the native resource's destination, rather than on the planet this effect is active on.");
|
|
Argument hookID("Hook", AT_Hook, "planet_effects::GenericEffect");
|
|
|
|
bool instantiate() {
|
|
@hook = cast<GenericEffect>(parseHook(arguments[0].str, "planet_effects::"));
|
|
if(hook is null) {
|
|
error("AddToNativeResource: could not find inner hook: "+escape(arguments[0].str));
|
|
return false;
|
|
}
|
|
return GenericEffect::instantiate();
|
|
}
|
|
|
|
const IResourceHook@ get_displayHook() const override {
|
|
return null;
|
|
}
|
|
|
|
const IResourceHook@ get_carriedHook() const override {
|
|
return hook.displayHook;
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
AddToNativeData info;
|
|
data.store(@info);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
AddToNativeData@ info;
|
|
data.retrieve(@info);
|
|
|
|
if(info !is null && info.current !is null)
|
|
hook.disable(info.current, info.data);
|
|
|
|
@info = null;
|
|
data.store(@info);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const {
|
|
AddToNativeData@ info;
|
|
data.retrieve(@info);
|
|
|
|
//Make sure the hook is applied to the right object
|
|
Object@ target;
|
|
if(obj.hasResources)
|
|
@target = obj.nativeResourceDestination[0];
|
|
if(target is null)
|
|
@target = obj;
|
|
if(target !is info.current) {
|
|
if(info.current !is null)
|
|
hook.disable(info.current, info.data);
|
|
if(target !is null)
|
|
hook.enable(target, info.data);
|
|
@info.current = target;
|
|
}
|
|
|
|
if(info.current !is null)
|
|
hook.tick(info.current, info.data, time);
|
|
}
|
|
|
|
void ownerChange(Object& obj, any@ data, Empire@ prevOwner, Empire@ newOwner) const {
|
|
AddToNativeData@ info;
|
|
data.retrieve(@info);
|
|
|
|
if(info.current !is null)
|
|
hook.ownerChange(info.current, info.data, prevOwner, newOwner);
|
|
}
|
|
|
|
void regionChange(Object& obj, any@ data, Region@ fromRegion, Region@ toRegion) const {
|
|
AddToNativeData@ info;
|
|
data.retrieve(@info);
|
|
|
|
if(info.current !is null)
|
|
hook.regionChange(info.current, info.data, fromRegion, toRegion);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const {
|
|
AddToNativeData@ info;
|
|
data.retrieve(@info);
|
|
|
|
if(info is null){
|
|
Object@ tmp;
|
|
file << tmp;
|
|
}
|
|
else {
|
|
file << info.current;
|
|
if(info.current !is null)
|
|
hook.save(info.data, file);
|
|
}
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const {
|
|
AddToNativeData info;
|
|
data.store(@info);
|
|
|
|
file >> info.current;
|
|
if(info.current !is null)
|
|
hook.load(info.data, file);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
//AddRandomPressure(<Amount>, <Change Timer>, <Buildup Time>)
|
|
// Adds <Amount> random pressure that changes every <Change Timer>.
|
|
tidy final class PressureData {
|
|
int type;
|
|
int amount;
|
|
double timer;
|
|
};
|
|
|
|
class AddRandomPressure : GenericEffect {
|
|
Document doc("Add randomized pressure to the planet that changes to a different type periodically.");
|
|
Argument amount(AT_Integer, doc="Amount of randomized pressure to give.");
|
|
Argument change_timer(AT_Decimal, doc="Time interval between when the pressure changes types.");
|
|
Argument buildup_time(AT_Decimal, doc="Time period over which the pressure builds up from 0 to its maximum value.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
PressureData info;
|
|
info.type = randomi(0, TR_COUNT-1);
|
|
info.amount = 0;
|
|
info.timer = 0.0;
|
|
|
|
data.store(@info);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
PressureData@ info;
|
|
data.retrieve(@info);
|
|
|
|
if(info.type != -1)
|
|
obj.modPressure(info.type, -info.amount);
|
|
|
|
@info = null;
|
|
data.store(null);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const {
|
|
PressureData@ info;
|
|
data.retrieve(@info);
|
|
|
|
int maxAmount = arguments[0].integer;
|
|
if(info.amount < maxAmount) {
|
|
//Pressure buildup
|
|
int prevAmt = info.amount;
|
|
info.timer += time;
|
|
info.amount = clamp(round(info.timer / arguments[2].decimal * double(maxAmount)), 0, maxAmount);
|
|
|
|
if(info.amount != prevAmt)
|
|
obj.modPressure(info.type, info.amount - prevAmt);
|
|
if(info.amount == maxAmount)
|
|
info.timer = 0.0;
|
|
}
|
|
else {
|
|
//Pressure change
|
|
info.timer += time;
|
|
if(info.timer >= arguments[1].decimal) {
|
|
obj.modPressure(info.type, -info.amount);
|
|
info.type = randomi(0, TR_COUNT-1);
|
|
obj.modPressure(info.type, +info.amount);
|
|
info.timer = 0.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const {
|
|
PressureData@ info;
|
|
data.retrieve(@info);
|
|
|
|
if(info !is null) {
|
|
file << info.type;
|
|
file << info.amount;
|
|
file << info.timer;
|
|
}
|
|
else {
|
|
int tmp = -1;
|
|
file << tmp;
|
|
tmp = 0;
|
|
file << tmp;
|
|
double tmpd = 0.0;
|
|
file << tmpd;
|
|
}
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const {
|
|
PressureData info;
|
|
file >> info.type;
|
|
file >> info.amount;
|
|
file >> info.timer;
|
|
|
|
data.store(@info);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ReplacesCities : GenericEffect, TriggerableGeneric {
|
|
Document doc("The planet this effect is active on needs to construct fewer civilian cities than normal, this effect replaces some.");
|
|
Argument amount(AT_Integer, "1", doc="How many cities this replaces.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.modCityCount(+amount.integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.modCityCount(-amount.integer);
|
|
}
|
|
|
|
//This hook, when used on a building, takes effect immediately, to prevent 'temporary' cities from being built
|
|
void startConstruction(Object& obj, SurfaceBuilding@ bld) const {
|
|
enable(obj, bld.data[hookIndex]);
|
|
}
|
|
|
|
void cancelConstruction(Object& obj, SurfaceBuilding@ bld) const {
|
|
disable(obj, bld.data[hookIndex]);
|
|
}
|
|
|
|
void complete(Object& obj, SurfaceBuilding@ bld) const {
|
|
//Already enabled in startConstruction
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class MakeQuarantined : GenericEffect, TriggerableGeneric {
|
|
Document doc("The planet this is active on is marked 'quarantined', which prevents it from importing, exporting or being colonized.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.setQuarantined(true);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.setQuarantined(false);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class NoNeedPopulationForLevel : GenericEffect {
|
|
Document doc("The planet this is on does not require extra population to level.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.setNeedsPopulationForLevel(false);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.setNeedsPopulationForLevel(true);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class PopulationCannotDie : GenericEffect {
|
|
Document doc("The population on this planet cannot die.");
|
|
|
|
#section server
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.hasSurfaceComponent) {
|
|
double curPop = obj.population;
|
|
double intPop = ceil(curPop);
|
|
if(curPop != intPop)
|
|
obj.addPopulation(intPop - curPop);
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class AlwaysAtMaxPopulation : GenericEffect {
|
|
Document doc("The population of the planet is always at the maximum value.");
|
|
|
|
#section server
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.hasSurfaceComponent) {
|
|
double diff = obj.maxPopulation - obj.population;
|
|
if(diff != 0)
|
|
obj.addPopulation(diff);
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ForceIntegerPopulation : GenericEffect {
|
|
Document doc("The population on this planet dies in integer increments.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double popDmg = 0;
|
|
if(obj.hasSurfaceComponent) {
|
|
double curPop = obj.population;
|
|
double targPop = floor(curPop);
|
|
if(curPop != targPop) {
|
|
popDmg = curPop - targPop;
|
|
obj.addPopulation(targPop - curPop);
|
|
}
|
|
}
|
|
data.store(popDmg);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.hasSurfaceComponent) {
|
|
double popDmg = 0;
|
|
data.retrieve(popDmg);
|
|
|
|
double curPop = obj.population;
|
|
double targPop = max(ceil(curPop - popDmg), 1.0);
|
|
if(curPop != targPop) {
|
|
popDmg += targPop - curPop;
|
|
obj.addPopulation(targPop - curPop);
|
|
data.store(popDmg);
|
|
}
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ProduceAllPressure : GenericEffect {
|
|
Document doc("Produce all pressure of a particular type directly as resource production.");
|
|
Argument type(AT_TileResource, doc="Type of pressure to produce.");
|
|
Argument factor(AT_Decimal, "1", doc="Factor of pressure to produce.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
double prod = 0;
|
|
data.store(prod);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(!obj.hasSurfaceComponent)
|
|
return;
|
|
|
|
double prod = 0;
|
|
data.retrieve(prod);
|
|
|
|
double newProd = obj.getResourcePressure(type.integer) * factor.decimal;
|
|
if(newProd != prod && obj.hasSurfaceComponent) {
|
|
obj.modResource(type.integer, newProd - prod);
|
|
data.store(newProd);
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
double prod = 0;
|
|
data.retrieve(prod);
|
|
|
|
if(prod != 0 && obj.hasSurfaceComponent)
|
|
obj.modResource(type.integer, -prod);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
double amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class SetMaxLevel : GenericEffect {
|
|
Document doc("Set the planet's maximum level, it cannot level up beyond this.");
|
|
Argument level(AT_Integer, doc="Maximum level to set");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.maxLevel = level.integer;
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.maxLevel = level.integer;
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.maxLevel = -1;
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class SetMaxLevelStatusCount : GenericEffect {
|
|
Document doc("Set the planet's maximum level based on how many statuses it has.");
|
|
Argument base(AT_Integer, doc="Base level.");
|
|
Argument status(AT_Status, doc="Status to count.");
|
|
|
|
#section server
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.maxLevel = base.integer + obj.getStatusStackCountAny(status.integer);
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
if(obj.hasSurfaceComponent)
|
|
obj.maxLevel = -1;
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ForceUsefulSurface : GenericEffect {
|
|
Document doc("Force the planet to have a percentage of useful region on its surface.");
|
|
Argument percent(AT_Decimal, doc="Percent of the surface that needs to be useful.");
|
|
Argument biome(AT_PlanetBiome, doc="Biome to fill the planet with to ensure surface.");
|
|
|
|
#section server
|
|
void enable(Object& cur, any@ data) const override {
|
|
if(cur is null || !cur.hasSurfaceComponent)
|
|
return;
|
|
auto@ type = getBiome(biome.str);
|
|
if(type !is null)
|
|
cur.forceUsefulSurface(percent.decimal, type.id);
|
|
else
|
|
print("No such biome: "+biome.str);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class SetOrbitSpin : GenericEffect {
|
|
Document doc("Force the planet to have a particular spin.");
|
|
Argument spin(AT_Range, doc="Time for the planet to complete one spin.");
|
|
|
|
#section server
|
|
void enable(Object& cur, any@ data) const override {
|
|
if(cur.hasOrbit)
|
|
cur.orbitSpin(spin.fromRange(), true);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ChangeNativeResourceTo : GenericEffect {
|
|
Document doc("Change the type of native resource for the duration of this effect.");
|
|
Argument resource(AT_PlanetResource, doc="Type of planetary resource to convert to.");
|
|
|
|
#section server
|
|
void enable(Object& cur, any@ data) const override {
|
|
uint prevType = cur.primaryResourceType;
|
|
data.store(prevType);
|
|
|
|
cur.terraformTo(resource.integer);
|
|
}
|
|
|
|
void disable(Object& cur, any@ data) const override {
|
|
uint prevType = uint(-1);
|
|
data.retrieve(prevType);
|
|
|
|
cur.terraformTo(prevType);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
uint reso = uint(-1);
|
|
data.retrieve(reso);
|
|
file << reso;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
uint reso = uint(-1);
|
|
file >> reso;
|
|
data.store(reso);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ChangeLevelChain : GenericEffect {
|
|
Document doc("Change the planet's level chain and requirements.");
|
|
Argument chain(AT_Custom, doc="Chain to change to.");
|
|
Argument base_only(AT_Boolean, "True", doc="Only apply this chain if the chain was base before.");
|
|
|
|
uint chainId = 0;
|
|
|
|
bool instantiate() override {
|
|
chainId = getLevelChainID(chain.str);
|
|
if(chainId == uint(-1)) {
|
|
chainId = 0;
|
|
error("Cannot find planet level chain: "+chain.str);
|
|
return false;
|
|
}
|
|
return GenericEffect::instantiate();
|
|
}
|
|
|
|
#section server
|
|
void enable(Object& cur, any@ data) const override {
|
|
if(cur.hasSurfaceComponent) {
|
|
if(base_only.boolean) {
|
|
if(cur.levelChain == 0)
|
|
cur.setLevelChain(chainId);
|
|
}
|
|
else {
|
|
if(cur.levelChain != chainId)
|
|
cur.setLevelChain(chainId);
|
|
}
|
|
}
|
|
}
|
|
|
|
void tick(Object& cur, any@ data, double time) const override {
|
|
enable(cur, data);
|
|
}
|
|
|
|
void disable(Object& cur, any@ data) const override {
|
|
if(cur.hasSurfaceComponent) {
|
|
if(cur.levelChain == chainId)
|
|
cur.setLevelChain(0);
|
|
}
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class PlanetLevelIncomeMod : GenericEffect {
|
|
Document doc("Modify the planet's income based on its level.");
|
|
Argument level0(AT_Integer, doc="Income modification at level 0.");
|
|
Argument level1(AT_Integer, doc="Income modification at level 1.");
|
|
Argument step(AT_Integer, doc="Step that is added at every level afterwards.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
int mod = 0;
|
|
data.store(mod);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
if(!obj.hasSurfaceComponent)
|
|
return;
|
|
int prevMod = 0;
|
|
data.retrieve(prevMod);
|
|
|
|
int newMod = 0;
|
|
uint curLevel = obj.level;
|
|
uint chain = obj.levelChain;
|
|
if(curLevel == 0) {
|
|
newMod = level0.integer;
|
|
}
|
|
else {
|
|
double curPop = obj.population;
|
|
auto@ lv0 = getPlanetLevel(chain, 0);
|
|
auto@ lv1 = getPlanetLevel(chain, 1);
|
|
|
|
if(lv0 !is null && lv1 !is null) {
|
|
double startPop = lv0.population;
|
|
double endPop = lv1.population;
|
|
|
|
newMod = level0.integer + double(level1.integer - level0.integer) * clamp(curPop - startPop, 0.0, (endPop - startPop)) / (endPop - startPop);
|
|
|
|
for(uint i = 2; i <= curLevel; ++i) {
|
|
auto@ lv = getPlanetLevel(chain, i);
|
|
if(lv is null)
|
|
break;
|
|
startPop = endPop;
|
|
endPop = lv.population;
|
|
|
|
if(startPop != endPop)
|
|
newMod += double(step.integer) * clamp(curPop - startPop, 0.0, (endPop - startPop)) / (endPop - startPop);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(newMod != prevMod) {
|
|
obj.modIncome(newMod - prevMod);
|
|
data.store(newMod);
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
int mod = 0;
|
|
data.retrieve(mod);
|
|
if(mod != 0 && obj.hasSurfaceComponent)
|
|
obj.modIncome(-mod);
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
int amt = 0;
|
|
data.retrieve(amt);
|
|
file << amt;
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
int amt = 0;
|
|
file >> amt;
|
|
data.store(amt);
|
|
}
|
|
#section all
|
|
};
|
|
|
|
class ProduceAsteroidPressure : GenericEffect {
|
|
Document doc("Produce the pressure given by asteroids on this plaent.");
|
|
Argument factor(AT_Decimal, "1.0", doc="Multiplication to the pressure in production.");
|
|
|
|
#section server
|
|
void enable(Object& obj, any@ data) const override {
|
|
array<double> production(TR_COUNT, 0.0);
|
|
data.store(@production);
|
|
}
|
|
|
|
void tick(Object& obj, any@ data, double time) const override {
|
|
array<double>@ production;
|
|
data.retrieve(@production);
|
|
|
|
for(uint i = 0; i < TR_COUNT; ++i) {
|
|
double prevProd = production[i];
|
|
double newProd = obj.pressureFromAsteroids(i) * factor.decimal;
|
|
if(prevProd != newProd) {
|
|
obj.modResource(i, newProd - prevProd);
|
|
production[i] = newProd;
|
|
}
|
|
}
|
|
}
|
|
|
|
void disable(Object& obj, any@ data) const override {
|
|
array<double>@ production;
|
|
data.retrieve(@production);
|
|
|
|
for(uint i = 0; i < TR_COUNT; ++i) {
|
|
obj.modResource(i, -production[i]);
|
|
production[i] = 0.0;
|
|
}
|
|
}
|
|
|
|
void save(any@ data, SaveFile& file) const override {
|
|
array<double>@ production;
|
|
data.retrieve(@production);
|
|
for(uint i = 0; i < TR_COUNT; ++i)
|
|
file << production[i];
|
|
}
|
|
|
|
void load(any@ data, SaveFile& file) const override {
|
|
array<double> production(TR_COUNT, 0.0);
|
|
data.store(@production);
|
|
for(uint i = 0; i < TR_COUNT; ++i)
|
|
file >> production[i];
|
|
}
|
|
#section all
|
|
};
|