Tungsten walls

This commit is contained in:
Anuken 2021-12-13 14:42:16 -05:00
parent 0e99e121e8
commit 5ac3e08b1d
15 changed files with 164 additions and 66 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

After

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

View File

@ -484,3 +484,6 @@
63222=arkyic-wall|block-arkyic-wall-ui
63221=heat-redirector|block-heat-redirector-ui
63220=vanquish|unit-vanquish-ui
63219=tungsten-wall|block-tungsten-wall-ui
63218=tungsten-wall-large|block-tungsten-wall-large-ui
63217=tank-assembler|block-tank-assembler-ui

Binary file not shown.

View File

@ -72,7 +72,7 @@ public class Blocks{
powerSource, powerVoid, itemSource, itemVoid, liquidSource, liquidVoid, payloadSource, payloadVoid, illuminator,
//defense
copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge,
copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, plastaniumWall, plastaniumWallLarge, tungstenWall, tungstenWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge,
phaseWall, phaseWallLarge, surgeWall, surgeWallLarge,
mender, mendProjector, overdriveProjector, overdriveDome, forceProjector, shockMine,
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
@ -128,6 +128,9 @@ public class Blocks{
additiveReconstructor, multiplicativeReconstructor, exponentialReconstructor, tetrativeReconstructor,
repairPoint, repairTurret,
//unit - erekir
tankAssembler,
//payloads
//TODO small deconstructor
payloadConveyor, payloadRouter, payloadPropulsionTower, smallDeconstructor, deconstructor, constructor, largeConstructor, payloadLoader, payloadUnloader,
@ -1355,6 +1358,19 @@ public class Blocks{
schematicPriority = 10;
}};
tungstenWall = new Wall("tungsten-wall"){{
requirements(Category.defense, with(Items.tungsten, 6));
health = 180 * wallHealthMultiplier;
armor = 7f;
}};
tungstenWallLarge = new Wall("tungsten-wall-large"){{
requirements(Category.defense, ItemStack.mult(tungstenWall.requirements, 4));
health = 180 * wallHealthMultiplier * 4;
armor = 7f;
size = 2;
}};
thoriumWall = new Wall("thorium-wall"){{
requirements(Category.defense, with(Items.thorium, 6));
health = 200 * wallHealthMultiplier;
@ -3293,6 +3309,15 @@ public class Blocks{
acceptCoolant = true;
}};
//endregion
//region units - erekir
tankAssembler = new UnitAssembler("tank-assembler"){{
size = 3;
output = UnitTypes.vanquish;
requirements = BlockStack.list(Blocks.thoriumWallLarge, 4);
}};
//endregion
//region payloads

View File

@ -2446,7 +2446,7 @@ public class UnitTypes{
mirror = false;
x = 0f;
y = 0;
shadow = 30f;
shadow = 28f;
bullet = new BasicBulletType(7f, 50){{
sprite = "missile-large";
@ -2465,45 +2465,6 @@ public class UnitTypes{
trailLength = 8;
hitEffect = despawnEffect = Fx.blastExplosion;
}};
//TODO better bullet / weapon
/*
bullet = new ArtilleryBulletType(2f, 20, "shell"){{
hitEffect = Fx.massiveExplosion;
knockback = 0.8f;
lifetime = 100f;
width = height = 14f;
collidesTiles = false;
splashDamageRadius = 60f;
splashDamage = 60f;
backColor = Color.valueOf("feb380");
frontColor = Color.white;
width = 9f;
height = 15f;
status = StatusEffects.blasted;
lightning = 5;
trailLength = 28;
trailWidth = 4f;
trailEffect = Fx.none;
trailColor = backColor;
shrinkX = 0.1f;
shrinkY = 0.5f;
fragBullets = 9;
fragVelocityMin = 0.7f;
fragLifeMin = 0f;
fragBullet = new BasicBulletType(3.5f, 15){{
width = 7f;
height = 9f;
lifetime = 25f;
backColor = Color.valueOf("feb380");
frontColor = Color.white;
}};
}};*/
}});
int i = 0;
@ -2526,7 +2487,7 @@ public class UnitTypes{
hitColor = backColor = trailColor = Color.valueOf("feb380");
frontColor = Color.white;
trailWidth = 1.5f;
trailLength = 6;
trailLength = 4;
hitEffect = despawnEffect = Fx.hitBulletColor;
}};
}});
@ -2708,9 +2669,6 @@ public class UnitTypes{
height = 12f;
shootEffect = Fx.sparkShoot;
smokeEffect = Fx.shootBigSmoke;
pierceCap = 2;
pierce = true;
pierceBuilding = true;
hitColor = backColor = trailColor = Pal.bulletYellowBack;
frontColor = Color.white;
trailWidth = 1.5f;

View File

@ -510,4 +510,9 @@ public class Damage{
float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff);
return damage * scaled;
}
/** @return resulting armor calculated based off of damage */
public static float applyArmor(float damage, float armor){
return Math.max(damage - armor, minArmorDamage * damage);
}
}

View File

@ -1549,7 +1549,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
if(Mathf.zero(dm)){
damage = health + 1;
}else{
damage /= dm;
damage = Damage.applyArmor(damage, block.armor) / dm;
}
Call.tileDamage(self(), health - handleDamage(damage));

View File

@ -3,11 +3,10 @@ package mindustry.entities.comp;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.game.*;
import mindustry.gen.*;
import static mindustry.Vars.*;
@Component
abstract class ShieldComp implements Healthc, Posc{
@Import float health, hitTime, x, y, healthMultiplier;
@ -24,11 +23,8 @@ abstract class ShieldComp implements Healthc, Posc{
@Replace
@Override
public void damage(float amount){
//apply armor
amount = Math.max(amount - armor, minArmorDamage * amount);
amount /= healthMultiplier;
rawDamage(amount);
//apply armor and scaling effects
rawDamage(Damage.applyArmor(amount, armor) / healthMultiplier);
}
@Replace

View File

@ -3,20 +3,24 @@ package mindustry.entities.comp;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.environment.*;
import static mindustry.Vars.*;
@Component
abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec{
@Import float x, y, hitSize, rotation;
@Import float x, y, hitSize, rotation, speedMultiplier;
@Import boolean hovering;
@Import UnitType type;
transient private float treadEffectTime;
transient private float treadEffectTime, lastSlowdown = 1f;
transient float treadTime;
transient boolean walked;
@ -43,6 +47,22 @@ abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec
}
}
//calculate overlapping tiles so it slows down when going "over" walls
//TODO is this a necessary mechanic?
int r = Math.max(Math.round(hitSize * 0.6f / tilesize), 1);
int solids = 0, total = (r*2+1)*(r*2+1);
for(int dx = -r; dx <= r; dx++){
for(int dy = -r; dy <= r; dy++){
Tile t = Vars.world.tileWorld(x + dx*tilesize, y + dy*tilesize);
if(t == null || t.solid()){
solids ++;
}
}
}
lastSlowdown = Mathf.lerp(1f, type.crawlSlowdown, Mathf.clamp((float)solids / total / type.crawlSlowdownFrac));
//trigger animation only when walking manually
if(walked || net.client()){
float len = deltaLen();
@ -51,6 +71,14 @@ abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec
}
}
@Override
@Replace
public float floorSpeedMultiplier(){
Floor on = isFlying() || hovering ? Blocks.air.asFloor() : floorOn();
//TODO take into account extra blocks
return on.speedMultiplier * speedMultiplier * lastSlowdown;
}
@Replace
@Override
public @Nullable Floor drownFloor(){

View File

@ -0,0 +1,56 @@
package mindustry.type;
import arc.struct.*;
import mindustry.content.*;
import mindustry.world.*;
public class BlockStack implements Comparable<BlockStack>{
public Block block = Blocks.router;
public int amount = 1;
public BlockStack(Block block, int amount){
this.block = block;
this.amount = amount;
}
public BlockStack(Block block){
this.block = block;
}
public BlockStack(){
}
public static BlockStack[] with(Object... items){
var stacks = new BlockStack[items.length / 2];
for(int i = 0; i < items.length; i += 2){
stacks[i / 2] = new BlockStack((Block)items[i], ((Number)items[i + 1]).intValue());
}
return stacks;
}
public static Seq<BlockStack> list(Object... items){
Seq<BlockStack> stacks = new Seq<>(items.length / 2);
for(int i = 0; i < items.length; i += 2){
stacks.add(new BlockStack((Block)items[i], ((Number)items[i + 1]).intValue()));
}
return stacks;
}
@Override
public int compareTo(BlockStack stack){
return block.compareTo(stack.block);
}
@Override
public boolean equals(Object o){
return this == o || (o instanceof BlockStack stack && stack.amount == amount && block == stack.block);
}
@Override
public String toString(){
return "BlockStack{" +
"block=" + block +
", amount=" + amount +
'}';
}
}

View File

@ -67,9 +67,7 @@ public class ItemStack implements Comparable<ItemStack>{
@Override
public boolean equals(Object o){
if(this == o) return true;
if(!(o instanceof ItemStack stack)) return false;
return amount == stack.amount && item == stack.item;
return this == o || (o instanceof ItemStack stack && stack.amount == amount && item == stack.item);
}
@Override

View File

@ -134,6 +134,8 @@ public class Block extends UnlockableContent{
public Attributes attributes = new Attributes();
/** tile entity health */
public int health = -1;
/** damage absorption, similar to unit armor */
public float armor = 0f;
/** base block explosiveness */
public float baseExplosiveness = 0f;
/** bullet that this block spawns when destroyed */
@ -429,6 +431,9 @@ public class Block extends UnlockableContent{
if(synthetic()){
stats.add(Stat.health, health, StatUnit.none);
if(armor > 0){
stats.add(Stat.armor, armor, StatUnit.none);
}
}
if(canBeBuilt() && requirements.length > 0){

View File

@ -3,6 +3,7 @@ package mindustry.world.blocks.units;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.content.*;
import mindustry.gen.*;
import mindustry.graphics.*;
@ -20,8 +21,12 @@ import static mindustry.Vars.*;
* */
public class UnitAssembler extends PayloadBlock{
public int areaSize = 10;
public UnitType unitType;
public int unitsCreated = 4;
public UnitType droneType;
public int dronesCreated = 4;
//TODO should be different for every tier.
public Seq<BlockStack> requirements = new Seq<>();
public UnitType output = UnitTypes.vanquish;
public UnitAssembler(String name){
super(name);
@ -47,17 +52,19 @@ public class UnitAssembler extends PayloadBlock{
Drawf.dashRect(valid ? Pal.accent : Pal.remove, Tmp.r1);
}
public class UnitAssemblerBuild extends PayloadBlockBuild<Payload>{
public class UnitAssemblerBuild extends PayloadBlockBuild<BuildPayload>{
public Seq<Unit> units = new Seq<>();
public Seq<BuildPayload> payloads = new Seq<>();
//TODO how should payloads be stored? counts of blocks? intmap? references?
//public Seq<BuildPayload> payloads = new Seq<>();
@Override
public void updateTile(){
units.removeAll(u -> !u.isAdded() || u.dead);
if(consValid() && units.size < unitsCreated){
if(consValid() && units.size < dronesCreated){
//TODO build animation? distribute spawning?
var unit = unitType.create(team);
var unit = droneType.create(team);
if(unit instanceof BuildingTetherc bt){
bt.building(this);
}
@ -69,12 +76,29 @@ public class UnitAssembler extends PayloadBlock{
units.add(unit);
}
//TODO drones need to indicate that they are in position
//TODO drones need to indicate that they are in position and actually play an animation
}
@Override
public void handlePayload(Building source, Payload payload){
//super.handlePayload(source, payload);
//payloads.add((BuildPayload)payload);
}
@Override
public boolean acceptPayload(Building source, Payload payload){
return super.acceptPayload(source, payload);
return payload instanceof BuildPayload bp && requirements.contains(b -> b.block == bp.block());
}
@Override
public void write(Writes write){
super.write(write);
}
@Override
public void read(Reads read, byte revision){
super.read(read, revision);
}
}
}