From 5ac3e08b1d021070e2d3e5e81869cbf677471f92 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 13 Dec 2021 14:42:16 -0500 Subject: [PATCH] Tungsten walls --- .../blocks/walls/thorium-wall-large.png | Bin 796 -> 794 bytes .../blocks/walls/tungsten-wall-large.png | Bin 0 -> 835 bytes .../sprites/blocks/walls/tungsten-wall.png | Bin 0 -> 289 bytes core/assets/icons/icons.properties | 3 + core/assets/logicids.dat | Bin 3789 -> 3825 bytes core/src/mindustry/content/Blocks.java | 27 ++++++++- core/src/mindustry/content/UnitTypes.java | 46 +------------- core/src/mindustry/entities/Damage.java | 5 ++ .../mindustry/entities/comp/BuildingComp.java | 2 +- .../mindustry/entities/comp/ShieldComp.java | 10 +--- .../src/mindustry/entities/comp/TankComp.java | 32 +++++++++- core/src/mindustry/type/BlockStack.java | 56 ++++++++++++++++++ core/src/mindustry/type/ItemStack.java | 4 +- core/src/mindustry/world/Block.java | 5 ++ .../world/blocks/units/UnitAssembler.java | 40 ++++++++++--- 15 files changed, 164 insertions(+), 66 deletions(-) create mode 100644 core/assets-raw/sprites/blocks/walls/tungsten-wall-large.png create mode 100644 core/assets-raw/sprites/blocks/walls/tungsten-wall.png create mode 100644 core/src/mindustry/type/BlockStack.java diff --git a/core/assets-raw/sprites/blocks/walls/thorium-wall-large.png b/core/assets-raw/sprites/blocks/walls/thorium-wall-large.png index ef8f313f099af415e00faa51dc338197013ba045..20c23043ac9a884bddcaa0e8c784ffee735717ea 100644 GIT binary patch delta 731 zcmV<10wn#M2AT$tF@MxaL_t(|ob6gmQUXB?eNbG0a)(v2@d_@zja8n&1Gw=fp2VeB za06Aaqd0;tbg&uvlXU0P3U9|SGfCdONzy%;JU_jDUSHk73Y*KdUk~gtvowfX7^#L)X zp6dn)f5=rJW;9kRtYA8sia$B~ zECpBvA6^?%f~0-20=(Y&Rsu^${AJD;v8c!^b&k&qm`|IzgQY` z8?9%v8cZp{m4L;3X}V7kBf*V;FmO*2TnMNgc$7j&g87%BT%aD~I$v0(#9DP}X(Ipt N002ovPDHLkV1lPyO&kCK delta 733 zcmV<30wVpI2Al?vF@M%cL_t(|ob6gWQUXB`eNbG0GQ%oKyn>;(vC0#8026QGNesP$ z2~aaiZmJ=332cp1a)cK6%2-Sg?m^V93$`sxN&*zDHX|1Et1fa!L>Dmo>J zT!7ZW1HcpjdLY3gc;K4=z?THC-~nJ3{@CtU0PGy{41B?D~ zTDE^FV8B=jTvbS_NYi$b0N{s&+F&F|(6*f=Kmsi!v=T_UKbivuEauB!V>NkUvs<%s z0yX%OKPB5q1yF)djm5xuo3+8G#&XZgDxmb>lMewNe@=u#ynnnUA7U|e*7Aon4~QA{ zTsKJgL#_fbqp?zHjaGlEXM#NhAEMSDwgPI6wax?=^JOv#w!93s0xW`0-4nA-@h4}W zr2wno!+T>&khD)$fY&$QN?-|U%i-;QCAPgL^$Ep5CV(>w3$OJcL1arT1_}wWYb;6N zs->z7f7W2U(K;r?Ym0oAtFO|?*{RtzYQ<)^{`v%ZnbldYD+XJ~9AH5L#fAk5p^cLy z*ozW0F(z1jTfBFi5YXEWkOszy_T+e68x$KBl_0cnY>==*FDe^In0h#rnk{-XX_(Cf z$4C)x-K4>)0+cc-QA$%v&^Uck*$>blLE~%@e;^W26Oa@M?;mefc|q)Kuq6-)5?Y=? zAt6hEcK{OhOC+%R18Tv2)?&UCwJ*{i(28CcT4%o)Vk@AfcTfYZ{;(9#Qg=voy4+JMYI|=8^&X*?@3u8~3RHW9tdeLcXH<2IbBx8%OYo(QR<;8E zVrk56w4TjsFr@@n0;D%SN{Er*MnD+2CkZYD)HXayAtb^4WGEM?N4w4^Vj#x|e+QQu P00000NkvXXu0mjfpn^-J diff --git a/core/assets-raw/sprites/blocks/walls/tungsten-wall-large.png b/core/assets-raw/sprites/blocks/walls/tungsten-wall-large.png new file mode 100644 index 0000000000000000000000000000000000000000..4c21bf939cb6e9001a018652b8a7b94bebd79279 GIT binary patch literal 835 zcmV-J1HAl+P)Px%{YgYYRCt{2TH8$|F%T^FAb~|I5}4&K=E`VqJZXAKk8L_rvzl@7ue-NTBb#R8uopQY1eyS#O%jf!10*EWiXyB`jl9L?^+`O4MGcFQ%%PFD0Dwa!K{Hl5X6pkEjRY^^ z_MG6Mkl?v>jxK-x`jQHF>kDe|uG8_35UlKyV~mDD#uCDbJ?jRE?9z`B)!d4Csc7=|}2PtS@IyuS}vt(ITDuU1QZe4bz!-nQQu z%UGVC?Tty{<>e1PK2M7MfP5IuZUIeA5VnnrmTU{Q?^OK&!UyDpFbRs*C)6N;(U0;0 zo7X3`W6L?qQon9}p-zO@?2(QF8b#Q}r@jHQty7vS2D4OHviMS)Wmq+>1wybs!xL@< zNEYTvf~y4_BK{LFw*qs+jR5a^0T!+nz%0!Be!=`qFofnT!SYy)CZJ|U7F%e|#Y?P+ zss*NGVyR{}wChJHx`G&jUG`o=Ck zW4c^j-_WviBuqLJ)S9+-%;*!w^T4rfmP1kRs%>{$#M)es#pilMtT{_4q5AdsoKQWJ zvlieDsg9<#fcHB=4b0C3Ydm+eBtaAf*z__~xRxboWS3C=dff7FS;$TjkSjz|f;?*Z z+OpMmgBE7aLL)oXC;Cz}M6HVnw!F2x2nqcN N002ovPDHLkV1jrwa|r+d literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/blocks/walls/tungsten-wall.png b/core/assets-raw/sprites/blocks/walls/tungsten-wall.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c0c18e3327505e2dbec2a393f1b540ece2fc45 GIT binary patch literal 289 zcmV++0p9+JP)Px#+et)0R9J=Wmq8AMFbGAdnWN~&WG|Hv$iOxU)Yw4ye4bT^$ z^y^;lHNwHhu?I`*em{60>H=6ppa7N-Zkm_a56>dWCG*q)0EB%j0wAg4w*|EzPBTyg z;-O8(^_4oz`+&xhx8Ta*oDT*k2GDFsjjssc%6gW@umCx4gLn_rvr`%#vO;o?RnTOMWJlG42N;*!)n-SWho90p+&u5M0ZQF`iTJDz?f0O>>$djJ3c delta 16 Xcmew;dsdc-;rvD>Tb|9yJbg?6G&u!$ diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index a6af38a9b2..68c267de10 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -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 diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index bc2f2a2f53..929e6c6496 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -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; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index df2cd699bc..0ab16352f9 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -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); + } } diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index b5afe88109..4c6f90b4b0 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -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)); diff --git a/core/src/mindustry/entities/comp/ShieldComp.java b/core/src/mindustry/entities/comp/ShieldComp.java index aa77d1e8bc..659630ecf0 100644 --- a/core/src/mindustry/entities/comp/ShieldComp.java +++ b/core/src/mindustry/entities/comp/ShieldComp.java @@ -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 diff --git a/core/src/mindustry/entities/comp/TankComp.java b/core/src/mindustry/entities/comp/TankComp.java index 6dfa5d0044..67168e301c 100644 --- a/core/src/mindustry/entities/comp/TankComp.java +++ b/core/src/mindustry/entities/comp/TankComp.java @@ -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(){ diff --git a/core/src/mindustry/type/BlockStack.java b/core/src/mindustry/type/BlockStack.java new file mode 100644 index 0000000000..0199bbb9a4 --- /dev/null +++ b/core/src/mindustry/type/BlockStack.java @@ -0,0 +1,56 @@ +package mindustry.type; + +import arc.struct.*; +import mindustry.content.*; +import mindustry.world.*; + +public class BlockStack implements Comparable{ + 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 list(Object... items){ + Seq 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 + + '}'; + } +} diff --git a/core/src/mindustry/type/ItemStack.java b/core/src/mindustry/type/ItemStack.java index ec15207760..253d6d4033 100644 --- a/core/src/mindustry/type/ItemStack.java +++ b/core/src/mindustry/type/ItemStack.java @@ -67,9 +67,7 @@ public class ItemStack implements Comparable{ @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 diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 8064ee77e7..9a1e18e1d5 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -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){ diff --git a/core/src/mindustry/world/blocks/units/UnitAssembler.java b/core/src/mindustry/world/blocks/units/UnitAssembler.java index 4b5b915ac2..5617930bda 100644 --- a/core/src/mindustry/world/blocks/units/UnitAssembler.java +++ b/core/src/mindustry/world/blocks/units/UnitAssembler.java @@ -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 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{ + public class UnitAssemblerBuild extends PayloadBlockBuild{ public Seq units = new Seq<>(); - public Seq payloads = new Seq<>(); + + //TODO how should payloads be stored? counts of blocks? intmap? references? + //public Seq 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); } } }