Skip to content

Commit

Permalink
Implemented Skeletonxf's Developer fix, with another round of optimiz…
Browse files Browse the repository at this point in the history
…ation and fixes.
  • Loading branch information
DaloLorn committed Jan 18, 2021
1 parent 8db6e2a commit 025c638
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 33 deletions.
2 changes: 1 addition & 1 deletion OpenSR/data/design_stats/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ GlobalStat: SupportCap
Icon: ActionBarIcons::2
Color: #00cffe

Variable: SupportCapacity
CustomFormula: SupportCap

GlobalStat: Acceleration
Name: #S_ACCEL
Expand Down
3 changes: 3 additions & 0 deletions OpenSR/data/empire_states.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,8 @@ visible:
// Attribute for First compressor workaround, to track bonus mass changes
// on the empire instead of on each ship as design revisions that leak
attribute double EmpireMassFactor = 1;
// Attributes for First developer workaround
attribute double EmpireSupportCapacityFactor = 1;
attribute double EmpireSupportCapacityMassFactor = 1;
// [[ MODIFY BASE GAME END ]]
}
4 changes: 2 additions & 2 deletions OpenSR/data/statuses/traits/AncientDeveloper.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Status: AncientDeveloper
Visible To: Nobody

EnableModifier(SupportCapModule::SupportCapacityFactor(1.05))
EnableModifier(SupportCapModule::MassFactor(1.25))
ModEmpireAttribute(EmpireSupportCapacityMassFactor, Multiply, 1.25)
ModEmpireAttribute(EmpireSupportCapacityFactor, Multiply, 1.05)
2 changes: 1 addition & 1 deletion OpenSR/scripts/definitions/CP_version.as
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace CommunityPatch {
"5095",
};
const string MOD_NAME = "OpenSR Modpack v1.1.0";
const string MOD_REVISION = "175";
const string MOD_REVISION = "176";
const string MOD_VERSION = MOD_NAME + " (revision " + MOD_REVISION + ") for Star Ruler 2 " + VERSIONS[0] + " (revision " + REVISIONS[0]
+ ", currently using " + GAME_VERSION + " " + SCRIPT_VERSION + ")";

Expand Down
18 changes: 17 additions & 1 deletion OpenSR/scripts/definitions/ancient_buffs.as
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,23 @@ double getMassFor(Ship& ship) {

double getMassFor(const Design@ dsg, Empire@ emp) {
double mass = dsg.total(HV_Mass);
if(emp !is null)
if(emp !is null) {
mass += dsg.total(HV_SupportCapacityMass) * max(emp.EmpireSupportCapacityMassFactor - 1.0, 0.0);
mass *= emp.EmpireMassFactor;
}
return mass;
}

int getSupportCommandFor(Ship& ship) {
double command = ship.blueprint.getEfficiencySum(SV_SupportCapacity);
if(ship.owner !is null)
command *= ship.owner.EmpireSupportCapacityFactor;
return floor(command);
}

int getSupportCommandFor(const Design@ dsg, Empire@ emp) {
double command = dsg.total(SV_SupportCapacity);
if(emp !is null)
command *= emp.EmpireSupportCapacityFactor;
return floor(command);
}
57 changes: 47 additions & 10 deletions OpenSR/scripts/definitions/generic_effects.as
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import research;
import empire_effects;
import repeat_hooks;
import planet_types;
import ancient_buffs;
#section server
import object_creation;
from components.ObjectManager import getDefenseDesign;
Expand Down Expand Up @@ -5003,68 +5004,104 @@ class AddBonusShield : GenericEffect {
#section all
};

class SupportCapacityData {
double multiplier = 1;
any data;

This comment has been minimized.

Copy link
@Skeletonxf

Skeletonxf Jan 18, 2021

Member

shouldn't this be const Design@ instead of any?

otherwise looks good, I'll be porting this back

This comment has been minimized.

Copy link
@DaloLorn

DaloLorn Jan 18, 2021

Author Member

I decided to err on the side of whatever was least likely to throw an error at me for daring to make the attempt.

}

class AddBonusSupportCapPct : GenericEffect {
Document doc("Add a percentage bonus support capacity to this fleet.");
Argument percentage(AT_Decimal, "0", doc="Percentage of maximum support cap to add.");

#section server
void enable(Object& obj, any@ data) const override {
const Design@ dsg = null;
data.store(@dsg);
SupportCapacityData info;
info.data.store(@dsg);
if(obj.owner !is null)
info.multiplier = obj.owner.EmpireSupportCapacityFactor;
data.store(@info);
}

void tick(Object& obj, any@ data, double time) const override {
Ship@ ship = cast<Ship>(obj);
if(ship is null)
return;

SupportCapacityData@ info;
const Design@ newDesign = ship.blueprint.design;
const Design@ oldDesign;
data.retrieve(@oldDesign);
data.retrieve(@info);
info.data.retrieve(@oldDesign);

// Account for Developer changes.
int given = 0, newGiven = 0;
if(obj.owner !is null) {
if(info.multiplier != obj.owner.EmpireSupportCapacityFactor) {
const Design@ dsg = oldDesign !is null ? oldDesign : newDesign;
given = dsg.total(SV_SupportCapacity) * percentage.decimal * info.multiplier;

This comment has been minimized.

Copy link
@Skeletonxf

Skeletonxf Jan 18, 2021

Member

shouldn't this use getSupportCommandFor as well?

This comment has been minimized.

Copy link
@DaloLorn

DaloLorn Jan 18, 2021

Author Member

Nope, because that would use the new multiplier. We need to do it manually here, using the old multiplier.

This comment has been minimized.

Copy link
@Skeletonxf

Skeletonxf Jan 18, 2021

Member

actually it looks like this doesn't compare old design to new design, if the ship design changes at the same time as an empire stat this could malfunction?

This comment has been minimized.

Copy link
@DaloLorn

DaloLorn Jan 18, 2021

Author Member

No. The multiplier is adjusted on the old design (unless there is no old design), then the design-swapping is done afterwards. Both occur in the same tick.

newGiven = getSupportCommandFor(dsg, obj.owner) * percentage.decimal;

if(given != newGiven)
ship.modSupplyCapacity(newGiven - given);
}
info.multiplier = obj.owner.EmpireSupportCapacityFactor;
}

if(oldDesign !is newDesign) {
int given = 0;
if(oldDesign !is null)
given = oldDesign.total(SV_SupportCapacity) * percentage.decimal;
given = getSupportCommandFor(oldDesign, obj.owner) * percentage.decimal;

This comment has been minimized.

Copy link
@DaloLorn

DaloLorn Jan 18, 2021

Author Member

No, it's not. See above - the multipliers are adjusted, using the last non-null design available, and then the designs are swapped using the current multiplier.

This comment has been minimized.

Copy link
@DaloLorn

DaloLorn Jan 18, 2021

Author Member

I do see that there's some redundant variable definition/initialization going on, but this only impacts code readability. Not urgent, but something to fix regardless.

int newGiven = 0;
if(newDesign !is null)
newGiven = newDesign.total(SV_SupportCapacity) * percentage.decimal;
newGiven = getSupportCommandFor(newDesign, obj.owner) * percentage.decimal;

if(given != newGiven)
ship.modSupplyCapacity(newGiven - given);
data.store(@newDesign);
info.data.store(@newDesign);
}
data.store(@info);
}

void disable(Object& obj, any@ data) const override {
Ship@ ship = cast<Ship>(obj);
if(ship is null)
return;

SupportCapacityData@ info;
const Design@ oldDesign;
data.retrieve(@oldDesign);
data.retrieve(@info);
info.data.retrieve(@oldDesign);

int given = 0;
if(oldDesign !is null)
given = oldDesign.total(SV_SupportCapacity) * percentage.decimal;
given = getSupportCommandFor(oldDesign, obj.owner) * percentage.decimal;
if(given != 0.0) {
ship.modSupplyCapacity(-given);

@oldDesign = null;
data.store(@oldDesign);
info.data.store(@oldDesign);
}
info.multiplier = 1;
data.store(@info);
}

void save(any@ data, SaveFile& file) const override {
SupportCapacityData@ info;
const Design@ dsg;
data.retrieve(@dsg);
data.retrieve(@info);
info.data.retrieve(@dsg);
file << dsg;
file << info.multiplier;
}

void load(any@ data, SaveFile& file) const override {
SupportCapacityData info;
const Design@ dsg;
file >> dsg;
data.store(@dsg);
info.data.store(@dsg);
file >> info.multiplier;
data.store(@info);
}
#section all
};
Expand Down
18 changes: 17 additions & 1 deletion OpenSR/scripts/gui/design_stats.as
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum CustomStatFormula {
CSF_None,
CSF_Mass,
CSF_Acceleration,
CSF_SupportCap,
};

class DesignStat {
Expand Down Expand Up @@ -153,43 +154,52 @@ namespace design_stats {

double getMass(const Design@ dsg, const Subsystem@ sys, vec2u hex, SysVariableType type, int aggregate = 0) {
double baseMass = 0;
double supportMass = 0;
if(type == SVT_HexVariable) {
if(hex != vec2u(uint(-1))) {
baseMass = dsg.variable(hex, HV_Mass);
supportMass = dsg.variable(hex, HV_SupportCapacityMass);
}
else if(sys !is null) {
switch(aggregate) {
case ::SA_Sum:
baseMass = sys.total(HV_Mass);
supportMass = sys.total(HV_SupportCapacityMass);
break;
}
}
else {
switch(aggregate) {
case ::SA_Sum:
baseMass = dsg.total(HV_Mass);
supportMass = dsg.total(HV_SupportCapacityMass);
break;
}
}
}
else if(type == SVT_SubsystemVariable) {
if(sys !is null) {
baseMass = sys.total(HV_Mass);
supportMass = sys.total(HV_SupportCapacityMass);
}
else {
switch(aggregate) {
case ::SA_Sum:
baseMass = dsg.total(HV_Mass);
supportMass = dsg.total(HV_SupportCapacityMass);
break;
}
}
}
else if(type == SVT_ShipVariable) {
baseMass = dsg.total(HV_Mass);
supportMass = dsg.total(HV_SupportCapacityMass);
}

if(playerEmpire !is null)
if(playerEmpire !is null) {
baseMass += supportMass * max(playerEmpire.EmpireSupportCapacityMassFactor - 1.0, 0.0);
baseMass *= playerEmpire.EmpireMassFactor;
}
return baseMass;
}

Expand Down Expand Up @@ -222,6 +232,9 @@ DesignStats@ getDesignStats(const Design@ dsg) {
val /= mass;
}
break;
case CSF_SupportCap:
val = getSupportCommandFor(dsg, playerEmpire);
break;
case CSF_None:
default:
val = design_stats::getValue(dsg, null, vec2u(uint(-1)),
Expand Down Expand Up @@ -421,6 +434,9 @@ void loadStats(const string& filename) {
else if(value.equals_nocase("Acceleration")) {
stat.customFormula = CSF_Acceleration;
}
else if(value.equals_nocase("SupportCap")) {
stat.customFormula = CSF_SupportCap;
}
}
else if(key == "Secondary") {
int sec = -1;
Expand Down
3 changes: 2 additions & 1 deletion OpenSR/scripts/server/construction/Construction.as
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import object_creation;
import resources;
import systems;
import buildings;
import ancient_buffs;
import bool getCheatsEverOn() from "cheats";
from regions.regions import getRegion;
#include "include/resource_constants.as"
Expand Down Expand Up @@ -982,7 +983,7 @@ tidy class Construction : Component_Construction, Savable {
if(cons is null)
return;

uint maxAmount = floor(cons.getSupportSupplyFree() / dsg.size);
uint maxAmount = floor(cons.getSupportSupplyFree(obj) / dsg.size);

This comment has been minimized.

Copy link
@Skeletonxf

Skeletonxf Jan 18, 2021

Member

also looks good, I missed this too

amount = min(amount, maxAmount);
if(amount == 0)
return;
Expand Down
5 changes: 3 additions & 2 deletions OpenSR/scripts/server/construction/ShipConstructible.as
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import resources;
import object_creation;
import ship_groups;
import cargo;
import ancient_buffs;

tidy class ShipConstructible : Constructible {
const Design@ design;
Expand Down Expand Up @@ -214,8 +215,8 @@ tidy class ShipConstructible : Constructible {
return false;
}

double getSupportSupplyFree() {
double supply = design.total(SV_SupportCapacity);
double getSupportSupplyFree(Object& obj) {
double supply = getSupportCommandFor(design, obj.owner);
for(uint i = 0, cnt = supports.length; i < cnt; ++i) {
GroupData@ d = supports[i];
supply -= double(d.totalSize) * d.dsg.size;
Expand Down
5 changes: 3 additions & 2 deletions OpenSR/scripts/server/empire_ai/include/bai_act_fleets.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//Locates a system to explore
import systems;
import ftl;
import ancient_buffs;
from pings import sendPing;
import design_settings;
#include "include/resource_constants.as"
Expand Down Expand Up @@ -1157,7 +1158,7 @@ class BuildFleet : Action {
int buildID = buildAt.constructionID[0];
if(buildID != -1) {
//Pre-order supports
uint supports = dsg.total(SV_SupportCapacity);
uint supports = getSupportCommandFor(dsg, ai.empire);
if(ai.skillEconomy < DIFF_Hard)
supports /= 2;

Expand Down Expand Up @@ -2654,7 +2655,7 @@ class MakeDesign : Action {
double supportSize = support is null ? 1.0 : double(support.size);

if(dsg.hasTag(ST_SupportCap))
str += dsg.total(SV_SupportCapacity) / supportSize * supportStr;
str += getSupportCommandFor(dsg, ai.empire) / supportSize * supportStr;

//Avoid wasting resources
double commandUsed = dsg.variable(ShV_REQUIRES_Command);
Expand Down
5 changes: 3 additions & 2 deletions OpenSR/scripts/server/empire_ai/weasel/Designs.as
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import empire_ai.weasel.WeaselAI;

import util.design_export;
import util.random_designs;
import ancient_buffs;

interface RaceDesigns {
bool preCompose(DesignTarget@ target);
Expand Down Expand Up @@ -173,7 +174,7 @@ tidy final class DesignTarget {

//Value support capacity where appropriate
if(purpose == DP_Combat) {
double supCap = dsg.total(SV_SupportCapacity);
double supCap = getSupportCommandFor(dsg, ai.empire);

This comment has been minimized.

Copy link
@Skeletonxf

Skeletonxf Jan 18, 2021

Member

I left the AI's ship design heuristics based on the non building modified values because I thought that would make the AI design better ships.

With the stats applied after the AI picks their design, the AI gets extra thrust and support cap it didn't budget for. I'd be concerned that with the stat changes known to the AI it decides to fill a load of hexes with something useless because it has 'enough' thrust/support cap already.

I suppose there is also the consideration that it should probably be matching desired supply against support command so this can go either way really.

double avgHP = 0, avgDPS = 0, avgDrain = 0.0;
cast<Designs>(ai.designs).getSupportAverages(avgHP, avgDPS, avgDrain);

Expand Down Expand Up @@ -591,7 +592,7 @@ final class Designs : AIComponent {
return DP_Miner;
if(dsg.size == 16.0 && dsg.total(SV_DPS) < 2.0)
return DP_Scout;
if(dps > 0.1 * dsg.size || dsg.total(SV_SupportCapacity) > 0)
if(dps > 0.1 * dsg.size || getSupportCommandFor(dsg, ai.empire) > 0)
return DP_Combat;
return defaultPurpose;
}
Expand Down
Loading

1 comment on commit 025c638

@DaloLorn
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Skeletonxf You will want to review the diffs for Constructible, ShipConstructible, and generic_effects. The other files are less relevant, to varying degrees: For instance, I'll be extremely surprised if BasicAI sees use at all, much less in a context where my changes will have an effect on it, but something like, say, WeaselAI or the Remnant ship spawner, could conceivably be put in a position where there was a measurable difference in support capacity.

(Also, I've fixed my mass updating oversight now. I think.)

Please sign in to comment.