Files
2018-07-17 14:15:37 +02:00

342 lines
13 KiB
ActionScript

import constructions;
from constructions import ConstructionHook;
import generic_hooks;
import requirement_effects;
import bonus_effects;
import target_filters;
import listed_values;
import consume_effects;
import util.formatting;
#section server
from constructions import Constructible;
#section all
class AddBuildCostAttribute : ConstructionHook {
Document doc("Add build cost based on an empire attribute value.");
Argument attribute(AT_EmpAttribute, doc="Attribute to use.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
Argument power(AT_Decimal, "1", doc="Raise the attribute to this power before multiplying.");
void getBuildCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const override {
double value = obj.owner.getAttribute(attribute.integer);
if(power.decimal != 1.0)
value = pow(value, power.decimal);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddMaintainCostAttribute : ConstructionHook {
Document doc("Add maintenance cost based on an empire attribute value.");
Argument attribute(AT_EmpAttribute, doc="Attribute to use.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
Argument power(AT_Decimal, "1", doc="Raise the attribute to this power before multiplying.");
void getMaintainCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const override {
double value = obj.owner.getAttribute(attribute.integer);
if(power.decimal != 1.0)
value = pow(value, power.decimal);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddLaborCostAttribute : ConstructionHook {
Document doc("Add labor cost based on an empire attribute value.");
Argument attribute(AT_EmpAttribute, doc="Attribute to use.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
Argument power(AT_Decimal, "1", doc="Raise the attribute to this power before multiplying.");
void getLaborCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, double& cost) const override {
double value = obj.owner.getAttribute(attribute.integer);
if(power.decimal != 1.0)
value = pow(value, power.decimal);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddBuildCostTotalPopulation : ConstructionHook {
Document doc("Add build cost based on an empire attribute value.");
Argument add(AT_Decimal, "0", doc="Modify the value by this amount first.");
Argument add_attribute(AT_EmpAttribute, EMPTY_DEFAULT, doc="Attribute to add to the amount first.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
Argument power(AT_Decimal, "1", doc="Raise the attribute to this power before multiplying.");
void getBuildCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const override {
double value = obj.owner.TotalPopulation + add.decimal;
if(add_attribute.integer != 0)
value += obj.owner.getAttribute(add_attribute.integer);
value = max(value, 0.0);
if(power.decimal != 1.0)
value = pow(value, power.decimal);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddMaintainCostTotalPopulation : ConstructionHook {
Document doc("Add maintenance cost based on an empire attribute value.");
Argument add(AT_Decimal, "0", doc="Modify the value by this amount first.");
Argument add_attribute(AT_EmpAttribute, EMPTY_DEFAULT, doc="Attribute to add to the amount first.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
Argument power(AT_Decimal, "1", doc="Raise the attribute to this power before multiplying.");
void getMaintainCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const override {
double value = obj.owner.TotalPopulation + add.decimal;
if(add_attribute.integer != 0)
value += obj.owner.getAttribute(add_attribute.integer);
value = max(value, 0.0);
if(power.decimal != 1.0)
value = pow(value, power.decimal);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddLaborCostTotalPopulation : ConstructionHook {
Document doc("Add labor cost based on an empire attribute value.");
Argument add(AT_Decimal, "0", doc="Modify the value by this amount first.");
Argument add_attribute(AT_EmpAttribute, EMPTY_DEFAULT, doc="Attribute to add to the amount first.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
Argument power(AT_Decimal, "1", doc="Raise the attribute to this power before multiplying.");
void getLaborCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, double& cost) const override {
double value = obj.owner.TotalPopulation + add.decimal;
if(add_attribute.integer != 0)
value += obj.owner.getAttribute(add_attribute.integer);
value = max(value, 0.0);
if(power.decimal != 1.0)
value = pow(value, power.decimal);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
tidy final class OnStart : ConstructionHook {
Document doc("Trigger a hook whenever the construction is started.");
Argument hookID("Hook", AT_Hook, "bonus_effects::BonusEffect", doc="Hook to run.");
BonusEffect@ hook;
bool instantiate() override {
@hook = cast<BonusEffect>(parseHook(hookID.str, "bonus_effects::", required=false));
if(hook is null) {
error("OnStart(): could not find inner hook: "+escape(hookID.str));
return false;
}
return ConstructionHook::instantiate();
}
#section server
void start(Construction@ cons, Constructible@ qitem, any@ data) const override {
if(hook !is null)
hook.activate(cons.obj, cons.obj.owner);
}
#section all
};
tidy final class OnCancel : ConstructionHook {
Document doc("Trigger a hook whenever the construction is canceled.");
Argument hookID("Hook", AT_Hook, "bonus_effects::BonusEffect", doc="Hook to run.");
BonusEffect@ hook;
bool instantiate() override {
@hook = cast<BonusEffect>(parseHook(hookID.str, "bonus_effects::", required=false));
if(hook is null) {
error("OnStart(): could not find inner hook: "+escape(hookID.str));
return false;
}
return ConstructionHook::instantiate();
}
#section server
void cancel(Construction@ cons, Constructible@ qitem, any@ data) const override {
if(hook !is null)
hook.activate(cons.obj, cons.obj.owner);
}
#section all
};
tidy final class Trigger : ConstructionHook {
Document doc("Runs a triggered hook on the target when the construction completes.");
Argument targ(TT_Object);
Argument hookID("Hook", AT_Hook, "bonus_effects::BonusEffect", doc="Hook to run.");
BonusEffect@ hook;
GenericEffect@ eff;
bool instantiate() override {
@hook = cast<BonusEffect>(parseHook(hookID.str, "bonus_effects::", required=false));
if(hook is null)
@eff = cast<GenericEffect>(parseHook(hookID.str, "planet_effects::", required=false));
if(hook is null && eff is null) {
error("Trigger(): could not find inner hook: "+escape(hookID.str));
return false;
}
return ConstructionHook::instantiate();
}
#section server
void finish(Construction@ cons, Constructible@ qitem, any@ data) const {
auto@ objTarg = targ.fromConstTarget(cons.targets);
if(objTarg is null || objTarg.obj is null)
return;
if(hook !is null)
hook.activate(objTarg.obj, cons.obj.owner);
else if(eff !is null)
eff.enable(objTarg.obj, null);
}
#section all
};
class SlowDownDebtGrowthFactor : ConstructionHook {
Document doc("This constructible gets slowed down depending on the current debt factor.");
#section server
void start(Construction@ cons, Constructible@ qitem, any@ data) const override {
double lab = qitem.totalLabor;
data.store(lab);
}
void tick(Construction@ cons, Constructible@ qitem, any@ data, double time) const {
double lab = 0;
data.retrieve(lab);
float growthFactor = 1.f;
float debtFactor = cons.obj.owner.DebtFactor;
for(; debtFactor > 0; debtFactor -= 1.f)
growthFactor *= 0.33f + 0.67f * (1.f - min(debtFactor, 1.f));
qitem.totalLabor = (lab - qitem.curLabor) / max(growthFactor, 0.01f) + qitem.curLabor;
}
void save(Construction@ cons, any@ data, SaveFile& file) const {
double lab = 0;
data.retrieve(lab);
file << lab;
}
void load(Construction@ cons, any@ data, SaveFile& file) const {
double lab = 0;
file >> lab;
data.store(lab);
}
#section all
};
class AddBuildCostStatusCount : ConstructionHook {
Document doc("Add build cost based on the amount of stacks of a status present.");
Argument status(AT_Status, doc="Status to count.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
void getBuildCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const override {
double value = obj.getStatusStackCountAny(status.integer);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddMaintainCostStatusCount : ConstructionHook {
Document doc("Add maintenance cost based on the amount of stacks of a status present.");
Argument status(AT_Status, doc="Status to count.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
void getMaintainCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const override {
double value = obj.getStatusStackCountAny(status.integer);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddLaborCostStatusCount : ConstructionHook {
Document doc("Add labor cost based on the amount of stacks of a status present.");
Argument status(AT_Status, doc="Status to count.");
Argument multiply(AT_Decimal, "1", doc="Multiply attribute value by this much.");
Argument multiply_sqrt(AT_Decimal, "0", doc="Add cost based on the square root of the attribute multiplied by this.");
void getLaborCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, double& cost) const override {
double value = obj.getStatusStackCountAny(status.integer);
cost += value * multiply.decimal;
if(multiply_sqrt.decimal != 0)
cost += sqrt(value) * multiply_sqrt.decimal;
}
};
class AddBuildCostTargetVar : ConstructionHook {
Document doc("Add build cost based on a ship variable of the target.");
Argument targ(TT_Object);
Argument variable(AT_SysVar, doc="Variable to add as build cost.");
Argument multiply(AT_Decimal, "1", doc="Multiply value by this much.");
int get(Object@ obj) const {
if(obj is null || !obj.isShip)
return 0;
auto@ design = cast<Ship>(obj).blueprint.design;
if(design is null)
return 0;
return design.total(SubsystemVariable(variable.integer)) * multiply.decimal;
}
void getBuildCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, int& cost) const override {
if(targs is null)
return;
auto@ objTarg = targ.fromConstTarget(targs);
if(objTarg is null || objTarg.obj is null)
return;
cost += get(objTarg.obj);
}
};
class AddLaborCostTargetVar : ConstructionHook {
Document doc("Add labor cost based on a ship variable of the target.");
Argument targ(TT_Object);
Argument variable(AT_SysVar, doc="Variable to add as labor cost.");
Argument multiply(AT_Decimal, "1", doc="Multiply value by this much.");
double get(Object@ obj) const {
if(obj is null || !obj.isShip)
return 0;
auto@ design = cast<Ship>(obj).blueprint.design;
if(design is null)
return 0;
return design.total(SubsystemVariable(variable.integer)) * multiply.decimal;
}
void getLaborCost(Object& obj, const ConstructionType@ cons, const Targets@ targs, double& cost) const override {
if(targs is null)
return;
auto@ objTarg = targ.fromConstTarget(targs);
if(objTarg is null || objTarg.obj is null)
return;
cost += get(objTarg.obj);
}
};