Better block health scaling system

This commit is contained in:
Anuken 2021-12-28 11:29:31 -05:00
parent 0b9ad22e88
commit ad42861daf
17 changed files with 84 additions and 46 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 833 B

After

Width:  |  Height:  |  Size: 940 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 B

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 B

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -134,7 +134,6 @@ public class Blocks{
basicAssemblerModule,
//payloads
//TODO small deconstructor
payloadConveyor, payloadRouter, payloadPropulsionTower, smallDeconstructor, deconstructor, constructor, largeConstructor, payloadLoader, payloadUnloader,
//logic
@ -1492,7 +1491,7 @@ public class Blocks{
range = 85f;
healPercent = 11f;
phaseBoost = 15f;
health = 80 * size * size;
scaledHealth = 80;
consumes.item(Items.phaseFabric).boost();
}};
@ -2406,14 +2405,14 @@ public class Blocks{
requirements(Category.effect, with(Items.titanium, 100));
size = 2;
itemCapacity = 300;
health = size * size * 55;
scaledHealth = 55;
}};
vault = new StorageBlock("vault"){{
requirements(Category.effect, with(Items.titanium, 250, Items.thorium, 125));
size = 3;
itemCapacity = 1000;
health = size * size * 55;
scaledHealth = 55;
}};
//TODO move tabs?
@ -2428,14 +2427,14 @@ public class Blocks{
size = 3;
//TODO should it really be kept the same, at 1000?
itemCapacity = 1200;
health = size * size * 120;
scaledHealth = 120;
}};
reinforcedVault = new StorageBlock("reinforced-vault"){{
requirements(Category.effect, with(Items.tungsten, 250, Items.carbide, 125));
size = 4;
itemCapacity = 2500;
health = size * size * 120;
scaledHealth = 120;
}};
//endregion
@ -2484,7 +2483,7 @@ public class Blocks{
inaccuracy = 17f;
shootCone = 35f;
health = 200 * size * size;
scaledHealth = 200;
shootSound = Sounds.shootSnap;
limitRange(2);
@ -2541,7 +2540,7 @@ public class Blocks{
liquidCapacity = 10f;
shootEffect = Fx.shootLiquid;
range = 110f;
health = 250 * size * size;
scaledHealth = 250;
flags = EnumSet.of(BlockFlag.turret, BlockFlag.extinguisher);
}};
@ -2562,7 +2561,7 @@ public class Blocks{
chargeBeginEffect = Fx.lancerLaserChargeBegin;
heatColor = Color.red;
size = 2;
health = 280 * size * size;
scaledHealth = 280;
targetAir = false;
shootSound = Sounds.laser;
@ -2609,7 +2608,7 @@ public class Blocks{
scaledForce = 6f;
range = 240f;
damage = 0.3f;
health = 160 * size * size;
scaledHealth = 160;
rotateSpeed = 10;
consumes.powerCond(3f, (TractorBeamBuild e) -> e.target != null);
@ -2629,7 +2628,7 @@ public class Blocks{
range = 240f;
xRand = 6f;
size = 2;
health = 300 * size * size;
scaledHealth = 300;
shootSound = Sounds.missile;
limitRange(5f);
@ -2657,7 +2656,7 @@ public class Blocks{
spread = 0f;
shots = 4;
ammoUseEffect = Fx.casing2;
health = 240 * size * size;
scaledHealth = 240;
shootSound = Sounds.shootBig;
limitRange();
@ -2666,7 +2665,7 @@ public class Blocks{
segment = new PointDefenseTurret("segment"){{
requirements(Category.turret, with(Items.silicon, 130, Items.thorium, 80, Items.phaseFabric, 40, Items.titanium, 40));
health = 250 * size * size;
scaledHealth = 250;
range = 180f;
hasPower = true;
consumes.powerCond(8f, (PointDefenseBuild b) -> b.target != null);
@ -2695,7 +2694,7 @@ public class Blocks{
liquidCapacity = 40f;
shootEffect = Fx.shootLiquid;
range = 190f;
health = 250 * size * size;
scaledHealth = 250;
flags = EnumSet.of(BlockFlag.turret, BlockFlag.extinguisher);
}};
@ -2712,7 +2711,7 @@ public class Blocks{
shootCone = 30;
size = 3;
health = 220 * size * size;
scaledHealth = 220;
shootSound = Sounds.shotgun;
float brange = range + 10f;
@ -2761,7 +2760,7 @@ public class Blocks{
range = 290f;
minRange = 50f;
health = 130 * size * size;
scaledHealth = 130;
shootSound = Sounds.artillery;
}};
@ -2783,7 +2782,7 @@ public class Blocks{
shootCone = 30f;
shootSound = Sounds.shootSnap;
health = 145 * size * size;
scaledHealth = 145;
limitRange();
}};
@ -2824,7 +2823,7 @@ public class Blocks{
coolantMultiplier = 0.4f;
health = 150 * size * size;
scaledHealth = 150;
coolantUsage = 1f;
consumes.powerCond(10f, TurretBuild::isActive);
@ -2852,7 +2851,7 @@ public class Blocks{
shootCone = 24f;
shootSound = Sounds.shootBig;
health = 160 * size * size;
scaledHealth = 160;
coolantUsage = 1f;
limitRange();
@ -2887,7 +2886,7 @@ public class Blocks{
ammoMultiplier = 1f;
}};
health = 200 * size * size;
scaledHealth = 200;
consumes.add(new ConsumeCoolant(0.5f)).update(false);
}};
@ -2943,7 +2942,7 @@ public class Blocks{
restitution = 0.03f;
range = 190;
shootCone = 3f;
health = 360 * size * size;
scaledHealth = 280;
rotateSpeed = 1.6f;
limitRange();
@ -2952,7 +2951,7 @@ public class Blocks{
//TODO bad name
sublimate = new ContinuousTurret("sublimate"){{
//TODO requirements
requirements(Category.turret, with(Items.tungsten, 50, Items.silicon, 60, Items.oxide, 30, Items.carbide, 40));
requirements(Category.turret, with(Items.tungsten, 120, Items.silicon, 160, Items.oxide, 50));
draw = new DrawTurret("reinforced-"){{
liquidDraw = Liquids.ozone;
@ -2988,15 +2987,17 @@ public class Blocks{
}};
outlineColor = Pal.darkOutline;
//TODO also consume hydrogen as a different ammo
consumes.liquids(LiquidStack.with(Liquids.cyanogen, 3f / 60f, Liquids.ozone, 2f / 60f));
range = 170f;
//TODO multi ammo
shootType = new ContinuousFlameBulletType(){{
damage = 4f;
damage = 5f;
length = range;
}};
scaledHealth = 320;
shootLength = 7f;
size = 3;
}};
@ -3006,15 +3007,15 @@ public class Blocks{
ammo(
//TODO 1 more ammo type, decide on base type
Items.fissileMatter, new ArtilleryBulletType(2.5f, 60, "shell"){{
Items.fissileMatter, new ArtilleryBulletType(2.5f, 100, "shell"){{
hitEffect = new MultiEffect(Fx.titanExplosion, Fx.titanSmoke);
despawnEffect = Fx.none;
knockback = 2f;
lifetime = 140f;
height = 17f;
width = 16f;
height = 19f;
width = 17f;
splashDamageRadius = 65f;
splashDamage = 150f;
splashDamage = 250f;
backColor = hitColor = trailColor = Color.valueOf("ea8878").lerp(Color.valueOf("feb380"), 0.5f);
frontColor = Color.white;
ammoMultiplier = 1f;
@ -3022,9 +3023,9 @@ public class Blocks{
status = StatusEffects.blasted;
trailLength = 32;
trailWidth = 2.85f;
trailWidth = 3.35f;
trailSinScl = 2.5f;
trailSinMag = 1f;
trailSinMag = 0.5f;
trailEffect = Fx.none;
despawnShake = 7f;
@ -3040,7 +3041,7 @@ public class Blocks{
targetAir = false;
shootShake = 4f;
recoilAmount = 1f;
reloadTime = 60f * 2f;
reloadTime = 60f * 3f;
shootLength = 7f;
rotateSpeed = 2.5f;
@ -3073,6 +3074,7 @@ public class Blocks{
consumes.liquids(LiquidStack.with(Liquids.hydrogen, 2f / 60f));
scaledHealth = 300;
range = 390f;
size = 4;
}};
@ -3083,7 +3085,7 @@ public class Blocks{
commandCenter = new CommandCenter("command-center"){{
requirements(Category.units, ItemStack.with(Items.copper, 200, Items.lead, 250, Items.silicon, 250, Items.graphite, 100));
size = 2;
health = size * size * 55;
scaledHealth = 55;
}};
groundFactory = new UnitFactory("ground-factory"){{
@ -3411,7 +3413,7 @@ public class Blocks{
hasPower = true;
consumes.power(10f);
buildCostMultiplier = 0.5f;
health = size * size * 80;
scaledHealth = 80;
}};
//endregion campaign

View File

@ -51,6 +51,7 @@ public class Items{
hardness = 4;
radioactivity = 1f;
cost = 1.1f;
healthScaling = 0.2f;
}};
scrap = new Item("scrap", Color.valueOf("777777")){{
@ -65,16 +66,19 @@ public class Items{
flammability = 0.1f;
explosiveness = 0.2f;
cost = 1.3f;
healthScaling = 0.1f;
}};
phaseFabric = new Item("phase-fabric", Color.valueOf("f4ba6e")){{
cost = 1.3f;
radioactivity = 0.6f;
healthScaling = 0.25f;
}};
surgeAlloy = new Item("surge-alloy", Color.valueOf("f3e979")){{
cost = 1.2f;
charge = 0.75f;
healthScaling = 0.25f;
}};
sporePod = new Item("spore-pod", Color.valueOf("7457ce")){{
@ -88,25 +92,29 @@ public class Items{
pyratite = new Item("pyratite", Color.valueOf("ffaa5f")){{
flammability = 1.4f;
explosiveness = 0.4f;
explosiveness = 0.5f;
}};
beryllium = new Item("beryllium", Color.valueOf("3a8f64")){{
hardness = 4;
cost = 1.3f;
healthScaling = 0.6f;
}};
tungsten = new Item("tungsten", Color.valueOf("768a9a")){{
hardness = 5;
cost = 1.5f;
healthScaling = 0.8f;
}};
oxide = new Item("oxide", Color.valueOf("e4ffd6")){{
cost = 1.1f;
cost = 1.2f;
healthScaling = 0.5f;
}};
carbide = new Item("carbide", Color.valueOf("89769a")){{
cost = 1.3f;
cost = 1.6f;
healthScaling = 1.1f;
}};
fissileMatter = new Item("fissile-matter", Color.valueOf("5e988d")){{

View File

@ -2513,7 +2513,7 @@ public class UnitTypes{
rotateSpeed = 3.5f;
accel = 0.1f;
health = 3000f;
armor = 4f;
armor = 5f;
hitSize = 36f;
payloadCapacity = Mathf.sqr(3f) * tilePayload;
@ -2522,6 +2522,7 @@ public class UnitTypes{
abilities.add(new SuppressionFieldAbility(){{
orbRadius = 5.3f;
y = 1f;
}});
float es = 3.9f;

View File

@ -23,6 +23,7 @@ public class SuppressionFieldAbility extends Ability{
public Color color1 = Pal.sap.cpy().mul(1.6f), color2 = Pal.sap;
public float layer = Layer.effect;
public float x = 0f, y = 0f;
public int particles = 15;
public float particleSize = 4f;
public float particleLen = 7f;
@ -78,12 +79,14 @@ public class SuppressionFieldAbility extends Ability{
Draw.z(layer);
float rad = orbRadius + Mathf.absin(orbSinScl, orbSinMag);
Tmp.v1.set(x, y).rotate(unit.rotation - 90f);
float rx = unit.x + Tmp.v1.x, ry = unit.y + Tmp.v1.y;
Draw.color(color2);
Fill.circle(unit.x, unit.y, rad);
Fill.circle(rx, ry, rad);
Draw.color(color1);
Fill.circle(unit.x, unit.y, rad * orbMidScl);
Fill.circle(rx, ry, rad * orbMidScl);
float base = (Time.time / particleLife);
rand.setSeed(unit.id);
@ -93,8 +96,8 @@ public class SuppressionFieldAbility extends Ability{
float angle = rand.random(360f) + (Time.time / rotateScl + unit.rotation) % 360f;
float len = particleLen * particleInterp.apply(fout);
Fill.circle(
unit.x + Angles.trnsx(angle, len),
unit.y + Angles.trnsy(angle, len),
rx + Angles.trnsx(angle, len),
ry + Angles.trnsy(angle, len),
particleSize * Mathf.slope(fin)
);
}
@ -103,7 +106,7 @@ public class SuppressionFieldAbility extends Ability{
if(heat > 0.001f){
Draw.color(Pal.sapBullet);
Lines.stroke(1.2f * heat * Mathf.absin(10f, 1f));
Lines.circle(unit.x, unit.y, range);
Lines.circle(rx, ry, range);
}
Draw.reset();

View File

@ -32,7 +32,9 @@ public class Item extends UnlockableContent{
* 1 cost = 1 tick added to build time
*/
public float cost = 1f;
/** if true, this item is of lowest priority to drills. */
/** When this item is present in the build cost, a block's <b>default</b> health is multiplied by 1 + scaling, where 'scaling' is summed together for all item requirement types. */
public float healthScaling = 0f;
/** if true, this item is of the lowest priority to drills. */
public boolean lowPriority;
/** If >0, this item is animated. */

View File

@ -134,7 +134,9 @@ public class Block extends UnlockableContent{
public @Nullable Item itemDrop = null;
/** Array of affinities to certain things. */
public Attributes attributes = new Attributes();
/** tile entity health */
/** Health per square tile that this block occupies; essentially, this is multiplied by size * size. Overridden if health is > 0. If <0, the default is 40. */
public float scaledHealth = -1;
/** building health; -1 to use scaledHealth */
public int health = -1;
/** damage absorption, similar to unit armor */
public float armor = 0f;
@ -914,7 +916,25 @@ public class Block extends UnlockableContent{
public void init(){
//initialize default health based on size
if(health == -1){
health = size * size * 40;
boolean round = false;
if(scaledHealth < 0){
scaledHealth = 40;
float scaling = 1f;
for(var stack : requirements){
scaling += stack.item.healthScaling;
}
if(scaling > 1){
Log.info("@: @ -> @", name, scaledHealth * size * size, (Mathf.round(scaledHealth * scaling, 5) * size * size));
}
scaledHealth *= scaling;
round = true;
}
health = round ?
Mathf.round(size * size * scaledHealth, 5) :
(int)(size * size * scaledHealth);
}
clipSize = Math.max(clipSize, size * tilesize);

View File

@ -40,6 +40,7 @@ public class ItemTurret extends Turret{
for(var entry : ammoTypes.copy().entries()){
var copy = entry.value.copy();
float realRange = copy.rangeChange + range;
//doesn't handle drag
copy.lifetime = (realRange + margin) / copy.speed;
ammoTypes.put(entry.key, copy);
}
@ -59,7 +60,8 @@ public class ItemTurret extends Turret{
@Override
public void build(Building build, Table table){
MultiReqImage image = new MultiReqImage();
content.items().each(i -> filter.get(i) && i.unlockedNow(), item -> image.add(new ReqImage(new ItemImage(item.uiIcon),
content.items().each(i -> filter.get(i) && i.unlockedNow(),
item -> image.add(new ReqImage(new ItemImage(item.uiIcon),
() -> build instanceof ItemTurretBuild it && !it.ammo.isEmpty() && ((ItemEntry)it.ammo.peek()).item == item)));
table.add(image).size(8 * 4);