From 0a07458186496e0fdf1cbeafb37816bf9bee4423 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 24 Sep 2020 13:05:39 -0400 Subject: [PATCH] Power-based ammo / Refactoring / IP kicks / Fixes --- .../annotations/impl/AssetsProcess.java | 13 +++ core/assets/icons/icons.properties | 8 -- core/src/mindustry/ai/BlockIndexer.java | 6 ++ core/src/mindustry/content/Blocks.java | 2 +- core/src/mindustry/content/TechTree.java | 4 + core/src/mindustry/content/UnitTypes.java | 82 ++++++++++------- core/src/mindustry/core/ContentLoader.java | 1 + core/src/mindustry/core/NetServer.java | 2 +- core/src/mindustry/ctype/ContentType.java | 3 +- .../src/mindustry/entities/comp/MechComp.java | 53 +++++++++++ .../mindustry/entities/comp/PlayerComp.java | 2 +- .../src/mindustry/entities/comp/UnitComp.java | 20 +++-- .../src/mindustry/graphics/FloorRenderer.java | 2 +- core/src/mindustry/input/InputHandler.java | 4 +- core/src/mindustry/net/Administration.java | 15 ++++ core/src/mindustry/net/NetConnection.java | 4 +- core/src/mindustry/type/AmmoType.java | 28 ++++++ core/src/mindustry/type/AmmoTypes.java | 86 ++++++++++++++++++ core/src/mindustry/type/StatusEffect.java | 2 +- core/src/mindustry/type/UnitType.java | 87 +++++-------------- core/src/mindustry/ui/Bar.java | 2 +- core/src/mindustry/ui/ContentDisplay.java | 2 +- core/src/mindustry/ui/dialogs/JoinDialog.java | 6 ++ .../ui/dialogs/SettingsMenuDialog.java | 2 +- .../mindustry/ui/fragments/HudFragment.java | 2 +- .../mindustry/world/blocks/power/Battery.java | 3 + .../world/blocks/units/ResupplyPoint.java | 5 +- core/src/mindustry/world/meta/BlockFlag.java | 2 + 28 files changed, 322 insertions(+), 126 deletions(-) create mode 100644 core/src/mindustry/type/AmmoType.java create mode 100644 core/src/mindustry/type/AmmoTypes.java diff --git a/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java b/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java index e3e70e8ddd..8e22e33db9 100644 --- a/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java +++ b/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java @@ -3,6 +3,8 @@ package mindustry.annotations.impl; import arc.files.*; import arc.scene.style.*; import arc.struct.*; +import arc.util.*; +import arc.util.io.*; import arc.util.serialization.*; import com.squareup.javapoet.*; import mindustry.annotations.Annotations.*; @@ -33,6 +35,17 @@ public class AssetsProcess extends BaseProcessor{ String resources = rootDirectory + "/core/assets-raw/sprites/ui"; Jval icons = Jval.read(Fi.get(rootDirectory + "/core/assets-raw/fontgen/config.json").readString()); + ObjectMap texIcons = new OrderedMap<>(); + PropertiesUtils.load(texIcons, Fi.get(rootDirectory + "/core/assets/icons/icons.properties").reader()); + + texIcons.each((key, val) -> { + String[] split = val.split("\\|"); + String name = Strings.kebabToCamel(split[1]).replace("Medium", "").replace("Icon", ""); + if(SourceVersion.isKeyword(name) || name.equals("char")) name = name + "i"; + + ichtype.addField(FieldSpec.builder(char.class, name, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("(char)" + key).build()); + }); + ictype.addField(FieldSpec.builder(ParameterizedTypeName.get(ObjectMap.class, String.class, TextureRegionDrawable.class), "icons", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("new ObjectMap<>()").build()); diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties index 8ef81ab8de..e5778f6442 100755 --- a/core/assets/icons/icons.properties +++ b/core/assets/icons/icons.properties @@ -21,15 +21,8 @@ 63723=ice|block-ice-medium 63722=ice-snow|block-ice-snow-medium 63721=cliffs|block-cliffs-medium -63720=rocks|block-rocks-medium -63719=sporerocks|block-sporerocks-medium 63718=rock|block-rock-medium 63717=snowrock|block-snowrock-medium -63716=icerocks|block-icerocks-medium -63715=snowrocks|block-snowrocks-medium -63714=dunerocks|block-dunerocks-medium -63713=sandrocks|block-sandrocks-medium -63712=saltrocks|block-saltrocks-medium 63711=spore-pine|block-spore-pine-medium 63710=snow-pine|block-snow-pine-medium 63709=pine|block-pine-medium @@ -38,7 +31,6 @@ 63706=white-tree|block-white-tree-medium 63705=spore-cluster|block-spore-cluster-medium 63704=shale|block-shale-medium -63703=shalerocks|block-shalerocks-medium 63702=shale-boulder|block-shale-boulder-medium 63701=sand-boulder|block-sand-boulder-medium 63700=moss|block-moss-medium diff --git a/core/src/mindustry/ai/BlockIndexer.java b/core/src/mindustry/ai/BlockIndexer.java index a7cf9b2cca..25aec37c97 100644 --- a/core/src/mindustry/ai/BlockIndexer.java +++ b/core/src/mindustry/ai/BlockIndexer.java @@ -6,6 +6,7 @@ import arc.math.*; import arc.math.geom.*; import arc.struct.EnumSet; import arc.struct.*; +import arc.util.ArcAnnotate.*; import mindustry.content.*; import mindustry.game.EventType.*; import mindustry.game.*; @@ -165,6 +166,11 @@ public class BlockIndexer{ return flagMap[team.id][type.ordinal()]; } + @Nullable + public Tile findClosestFlag(float x, float y, Team team, BlockFlag flag){ + return Geometry.findClosest(x, y, getAllied(team, flag)); + } + public boolean eachBlock(Teamc team, float range, Boolf pred, Cons cons){ return eachBlock(team.team(), team.getX(), team.getY(), range, pred, cons); } diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 7a7ac22ea0..498bed9295 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -265,7 +265,7 @@ public class Blocks implements ContentList{ variants = 3; status = StatusEffects.muddy; statusDuration = 30f; - attributes.set(Attribute.water, 2f); + attributes.set(Attribute.water, 1f); cacheLayer = CacheLayer.mud; albedo = 0.35f; }}; diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index 38c5b2f214..b1a17c7ef9 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -378,7 +378,11 @@ public class TechTree implements ContentList{ node(nova, () -> { node(pulsar, () -> { node(quasar, () -> { + node(vela, () -> { + node(corvus, () -> { + }); + }); }); }); }); diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index c90302855d..8e2a5f0734 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -69,7 +69,7 @@ public class UnitTypes implements ContentList{ dagger = new UnitType("dagger"){{ speed = 0.5f; - hitsize = 8f; + hitSize = 8f; health = 140; weapons.add(new Weapon("large-weapon"){{ reload = 14f; @@ -83,7 +83,7 @@ public class UnitTypes implements ContentList{ mace = new UnitType("mace"){{ speed = 0.4f; - hitsize = 9f; + hitSize = 9f; health = 500; armor = 4f; @@ -114,7 +114,7 @@ public class UnitTypes implements ContentList{ fortress = new UnitType("fortress"){{ speed = 0.38f; - hitsize = 13f; + hitSize = 13f; rotateSpeed = 3f; targetAir = false; health = 790; @@ -147,7 +147,7 @@ public class UnitTypes implements ContentList{ scepter = new UnitType("scepter"){{ speed = 0.35f; - hitsize = 20f; + hitSize = 20f; rotateSpeed = 2.1f; health = 9000; armor = 11f; @@ -207,7 +207,7 @@ public class UnitTypes implements ContentList{ reign = new UnitType("reign"){{ speed = 0.35f; - hitsize = 26f; + hitSize = 26f; rotateSpeed = 1.65f; health = 24000; armor = 14f; @@ -269,13 +269,14 @@ public class UnitTypes implements ContentList{ canBoost = true; boostMultiplier = 1.5f; speed = 0.55f; - hitsize = 8f; + hitSize = 8f; health = 110f; buildSpeed = 0.8f; armor = 1f; commandLimit = 8; abilities.add(new HealFieldAbility(10f, 60f * 4, 60f)); + ammoType = AmmoTypes.power; weapons.add(new Weapon("heal-weapon"){{ top = false; @@ -295,7 +296,7 @@ public class UnitTypes implements ContentList{ canBoost = true; boostMultiplier = 1.5f; speed = 0.65f; - hitsize = 10f; + hitSize = 10f; health = 320f; buildSpeed = 0.9f; armor = 4f; @@ -305,6 +306,7 @@ public class UnitTypes implements ContentList{ commandLimit = 15; abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f)); + ammoType = AmmoTypes.power; weapons.add(new Weapon("heal-shotgun-weapon"){{ top = false; @@ -335,7 +337,7 @@ public class UnitTypes implements ContentList{ quasar = new UnitType("quasar"){{ mineTier = 1; - hitsize = 12f; + hitSize = 12f; boostMultiplier = 2f; itemCapacity = 80; health = 650f; @@ -346,9 +348,10 @@ public class UnitTypes implements ContentList{ commandLimit = 18; mechFrontSway = 0.55f; + ammoType = AmmoTypes.power; speed = 0.4f; - hitsize = 10f; + hitSize = 10f; mineTier = 2; mineSpeed = 7f; @@ -377,7 +380,7 @@ public class UnitTypes implements ContentList{ }}; vela = new UnitType("vela"){{ - hitsize = 23f; + hitSize = 23f; rotateSpeed = 1.6f; canDrown = false; @@ -385,6 +388,7 @@ public class UnitTypes implements ContentList{ mechStepParticles = true; mechStepShake = 0.15f; + ammoType = AmmoTypes.powerHigh; speed = 0.35f; boostMultiplier = 2.1f; @@ -439,7 +443,7 @@ public class UnitTypes implements ContentList{ corvus = new UnitType("corvus"){{ mineTier = 1; - hitsize = 29f; + hitSize = 29f; itemCapacity = 80; health = 19000f; buildSpeed = 1.7f; @@ -457,6 +461,7 @@ public class UnitTypes implements ContentList{ hovering = true; visualElevation = 0.2f; allowLegStep = true; + ammoType = AmmoTypes.powerHigh; speed = 0.3f; @@ -513,7 +518,7 @@ public class UnitTypes implements ContentList{ defaultController = SuicideAI::new; speed = 0.85f; - hitsize = 8f; + hitSize = 8f; health = 180; mechSideSway = 0.25f; range = 40f; @@ -541,7 +546,7 @@ public class UnitTypes implements ContentList{ itemCapacity = 80; speed = 0.5f; drag = 0.4f; - hitsize = 10f; + hitSize = 10f; rotateSpeed = 3f; targetAir = false; health = 600; @@ -581,7 +586,7 @@ public class UnitTypes implements ContentList{ spiroct = new UnitType("spiroct"){{ speed = 0.4f; drag = 0.4f; - hitsize = 12f; + hitSize = 12f; rotateSpeed = 3f; health = 760; immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting); @@ -592,6 +597,7 @@ public class UnitTypes implements ContentList{ legBaseOffset = 2f; hovering = true; armor = 5f; + ammoType = AmmoTypes.power; buildSpeed = 0.75f; @@ -646,7 +652,7 @@ public class UnitTypes implements ContentList{ arkyid = new UnitType("arkyid"){{ drag = 0.1f; speed = 0.5f; - hitsize = 21f; + hitSize = 21f; health = 8000; armor = 6f; @@ -663,6 +669,7 @@ public class UnitTypes implements ContentList{ legLengthScl = 0.96f; rippleScale = 2f; legSpeed = 0.2f; + ammoType = AmmoTypes.power; legSplashDamage = 32; legSplashRange = 30; @@ -744,7 +751,7 @@ public class UnitTypes implements ContentList{ toxopid = new UnitType("toxopid"){{ drag = 0.1f; speed = 0.5f; - hitsize = 21f; + hitSize = 21f; health = 22000; armor = 13f; @@ -761,6 +768,7 @@ public class UnitTypes implements ContentList{ legLengthScl = 0.93f; rippleScale = 3f; legSpeed = 0.19f; + ammoType = AmmoTypes.powerHigh; legSplashDamage = 80; legSplashRange = 60; @@ -888,7 +896,7 @@ public class UnitTypes implements ContentList{ accel = 0.08f; drag = 0.016f; flying = true; - hitsize = 9f; + hitSize = 9f; targetAir = false; engineOffset = 7.8f; range = 140f; @@ -925,7 +933,7 @@ public class UnitTypes implements ContentList{ drag = 0.016f; flying = true; range = 140f; - hitsize = 18f; + hitSize = 18f; lowAltitude = true; armor = 5f; @@ -973,7 +981,7 @@ public class UnitTypes implements ContentList{ armor = 9f; engineOffset = 21; engineSize = 5.3f; - hitsize = 56f; + hitSize = 56f; BulletType missiles = new MissileBulletType(2.7f, 10){{ width = 8f; @@ -1045,7 +1053,7 @@ public class UnitTypes implements ContentList{ health = 20000; engineOffset = 38; engineSize = 7.3f; - hitsize = 58f; + hitSize = 58f; destructibleWreck = false; armor = 13f; @@ -1128,6 +1136,8 @@ public class UnitTypes implements ContentList{ range = 50f; isCounted = false; + ammoType = AmmoTypes.powerLow; + mineTier = 1; mineSpeed = 2.5f; }}; @@ -1145,10 +1155,12 @@ public class UnitTypes implements ContentList{ health = 400; buildSpeed = 0.5f; engineOffset = 6.5f; - hitsize = 8f; + hitSize = 8f; lowAltitude = true; isCounted = false; + ammoType = AmmoTypes.power; + mineTier = 2; mineSpeed = 3.5f; @@ -1197,11 +1209,13 @@ public class UnitTypes implements ContentList{ flying = true; engineOffset = 10.5f; rotateShooting = false; - hitsize = 15f; + hitSize = 15f; engineSize = 3f; payloadCapacity = (2 * 2) * tilePayload; buildSpeed = 2.5f; + ammoType = AmmoTypes.power; + weapons.add( new Weapon("heal-weapon-mount"){{ reload = 25f; @@ -1231,12 +1245,14 @@ public class UnitTypes implements ContentList{ engineOffset = 12f; engineSize = 6f; rotateShooting = false; - hitsize = 32f; + hitSize = 32f; payloadCapacity = (3 * 3) * tilePayload; buildSpeed = 2.5f; range = 140f; targetAir = false; + ammoType = AmmoTypes.powerHigh; + weapons.add( new Weapon(){{ x = y = 0f; @@ -1291,7 +1307,7 @@ public class UnitTypes implements ContentList{ engineOffset = 46f; engineSize = 7.8f; rotateShooting = false; - hitsize = 60f; + hitSize = 60f; payloadCapacity = (5.3f * 5.3f) * tilePayload; buildSpeed = 4f; drawShields = false; @@ -1306,7 +1322,7 @@ public class UnitTypes implements ContentList{ risso = new UnitType("risso"){{ speed = 1.1f; drag = 0.13f; - hitsize = 9f; + hitSize = 9f; health = 280; accel = 0.4f; rotateSpeed = 3.3f; @@ -1357,7 +1373,7 @@ public class UnitTypes implements ContentList{ health = 600; speed = 0.9f; drag = 0.15f; - hitsize = 11f; + hitSize = 11f; armor = 4f; accel = 0.3f; rotateSpeed = 2.6f; @@ -1400,7 +1416,7 @@ public class UnitTypes implements ContentList{ accel = 0.2f; rotateSpeed = 1.8f; drag = 0.17f; - hitsize = 16f; + hitSize = 16f; armor = 7f; rotateShooting = false; @@ -1493,7 +1509,7 @@ public class UnitTypes implements ContentList{ speed = 0.73f; drag = 0.17f; - hitsize = 39f; + hitSize = 39f; accel = 0.2f; rotateSpeed = 1.3f; rotateShooting = false; @@ -1576,7 +1592,7 @@ public class UnitTypes implements ContentList{ health = 22000; speed = 0.62f; drag = 0.18f; - hitsize = 50f; + hitSize = 50f; armor = 16f; accel = 0.19f; rotateSpeed = 0.9f; @@ -1639,7 +1655,7 @@ public class UnitTypes implements ContentList{ itemCapacity = 30; health = 120f; engineOffset = 6f; - hitsize = 8f; + hitSize = 8f; weapons.add(new Weapon("small-basic-weapon"){{ reload = 17f; @@ -1673,7 +1689,7 @@ public class UnitTypes implements ContentList{ itemCapacity = 50; health = 150f; engineOffset = 6f; - hitsize = 9f; + hitSize = 9f; rotateShooting = false; lowAltitude = true; @@ -1713,7 +1729,7 @@ public class UnitTypes implements ContentList{ itemCapacity = 70; health = 190f; engineOffset = 6f; - hitsize = 10f; + hitSize = 10f; weapons.add(new Weapon("small-mount-weapon"){{ top = false; @@ -1743,7 +1759,7 @@ public class UnitTypes implements ContentList{ block = new UnitType("block"){ { speed = 0f; - hitsize = 0f; + hitSize = 0f; health = 1; rotateSpeed = 360f; itemCapacity = 0; diff --git a/core/src/mindustry/core/ContentLoader.java b/core/src/mindustry/core/ContentLoader.java index 3a3fe0d2a3..56e46d8be2 100644 --- a/core/src/mindustry/core/ContentLoader.java +++ b/core/src/mindustry/core/ContentLoader.java @@ -33,6 +33,7 @@ public class ContentLoader{ new StatusEffects(), new Liquids(), new Bullets(), + new AmmoTypes(), new UnitTypes(), new Blocks(), new Loadouts(), diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 994b3a273e..9b298f9924 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -131,7 +131,7 @@ public class NetServer implements ApplicationListener{ return; } - if(Time.millis() < info.lastKicked){ + if(Time.millis() < admins.getKickTime(uuid, con.address)){ con.kick(KickReason.recentKick); return; } diff --git a/core/src/mindustry/ctype/ContentType.java b/core/src/mindustry/ctype/ContentType.java index bc147d8c81..e62377628c 100644 --- a/core/src/mindustry/ctype/ContentType.java +++ b/core/src/mindustry/ctype/ContentType.java @@ -15,7 +15,8 @@ public enum ContentType{ loadout_UNUSED, typeid_UNUSED, error, - planet; + planet, + ammo; public static final ContentType[] all = values(); } diff --git a/core/src/mindustry/entities/comp/MechComp.java b/core/src/mindustry/entities/comp/MechComp.java index ffbf0ce92c..44969416e9 100644 --- a/core/src/mindustry/entities/comp/MechComp.java +++ b/core/src/mindustry/entities/comp/MechComp.java @@ -1,13 +1,23 @@ package mindustry.entities.comp; +import arc.graphics.*; import arc.math.*; import arc.math.geom.*; import arc.util.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; +import mindustry.entities.*; import mindustry.gen.*; +import mindustry.type.*; +import mindustry.world.*; + +import static mindustry.Vars.*; @Component abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, ElevationMovec{ + @Import float x, y, hitSize; + @Import UnitType type; + @SyncField(false) @SyncLocal float baseRotation; transient float walkTime, walkExtension; transient private boolean walked; @@ -21,6 +31,49 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati walkTime += len; walked = false; } + + //update mech effects + float extend = walkExtend(false); + float base = walkExtend(true); + float extendScl = base % 1f; + + float lastExtend = walkExtension; + + if(extendScl < lastExtend && base % 2f > 1f){ + int side = -Mathf.sign(extend); + float width = hitSize / 2f * side, length = type.mechStride * 1.35f; + + float cx = x + Angles.trnsx(baseRotation, length, width), + cy = y + Angles.trnsy(baseRotation, length, width); + + if(type.mechStepShake > 0){ + Effect.shake(type.mechStepShake, type.mechStepShake, cx, cy); + } + + if(type.mechStepParticles){ + Tile tile = world.tileWorld(cx, cy); + if(tile != null){ + Color color = tile.floor().mapColor; + Fx.unitLand.at(cx, cy, hitSize/8f, color); + } + } + } + + walkExtension = extendScl; + } + + public float walkExtend(boolean scaled){ + + //now ranges from -maxExtension to maxExtension*3 + float raw = walkTime % (type.mechStride * 4); + + if(scaled) return raw / type.mechStride; + + if(raw > type.mechStride*3) raw = raw - type.mechStride * 4; + else if(raw > type.mechStride*2) raw = type.mechStride * 2 - raw; + else if(raw > type.mechStride) raw = type.mechStride * 2 - raw; + + return raw; } @Override diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index 61168fdece..ca52705964 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -92,7 +92,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra @Replace public float clipSize(){ - return unit.isNull() ? 20 : unit.type().hitsize * 2f; + return unit.isNull() ? 20 : unit.type().hitSize * 2f; } @Override diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index f67a06f4ce..695703dd2f 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -30,9 +30,8 @@ import static mindustry.Vars.*; @Component(base = true) abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Displayable, Senseable{ - @Import boolean hovering; - @Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health; - @Import boolean dead; + @Import boolean hovering, dead; + @Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo; @Import Team team; @Import int id; @@ -41,6 +40,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I boolean spawnedByCore; transient Seq abilities = new Seq<>(0); + private transient float resupplyTime = Mathf.random(10f); public void moveAt(Vec2 vector){ moveAt(vector, type.accel); @@ -191,7 +191,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I this.maxHealth = type.health; this.drag = type.drag; this.armor = type.armor; - this.hitSize = type.hitsize; + this.hitSize = type.hitSize; this.hovering = type.hovering; if(controller == null) controller(type.createController()); @@ -245,6 +245,16 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I type.update(self()); + if(state.rules.unitAmmo && ammo < type.ammoCapacity - 0.0001f){ + resupplyTime += Time.delta; + + //resupply only at a fixed interval to prevent lag + if(resupplyTime > 10f){ + type.ammoType.resupply(self()); + resupplyTime = 0f; + } + } + if(abilities.size > 0){ for(Ability a : abilities){ a.update(self()); @@ -366,7 +376,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I if(!headless){ for(int i = 0; i < type.wreckRegions.length; i++){ if(type.wreckRegions[i].found()){ - float range = type.hitsize/4f; + float range = type.hitSize /4f; Tmp.v1.rnd(range); Effect.decal(type.wreckRegions[i], x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90); } diff --git a/core/src/mindustry/graphics/FloorRenderer.java b/core/src/mindustry/graphics/FloorRenderer.java index 3598a0ad09..d6ec756910 100644 --- a/core/src/mindustry/graphics/FloorRenderer.java +++ b/core/src/mindustry/graphics/FloorRenderer.java @@ -228,7 +228,7 @@ public class FloorRenderer implements Disposable{ int chunksx = Mathf.ceil((float)(world.width()) / chunksize), chunksy = Mathf.ceil((float)(world.height()) / chunksize); cache = new Chunk[chunksx][chunksy]; - cbatch = new MultiCacheBatch(chunksize * chunksize * 7); + cbatch = new MultiCacheBatch(chunksize * chunksize * 8); Time.mark(); diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 3f102890e2..bbca06d7e0 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -113,7 +113,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ Payloadc pay = (Payloadc)unit; if(target.isAI() && target.isGrounded() && pay.canPickup(target) - && target.within(unit, unit.type().hitsize * 2f + target.type().hitsize * 2f)){ + && target.within(unit, unit.type().hitSize * 2f + target.type().hitSize * 2f)){ Call.pickedUnitPayload(player, target); } } @@ -395,7 +395,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(!(unit instanceof Payloadc)) return; Payloadc pay = (Payloadc)unit; - Unit target = Units.closest(player.team(), pay.x(), pay.y(), unit.type().hitsize * 2.5f, u -> u.isAI() && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize * 1.2f)); + Unit target = Units.closest(player.team(), pay.x(), pay.y(), unit.type().hitSize * 2.5f, u -> u.isAI() && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize * 1.2f)); if(target != null){ Call.requestUnitPayload(player, target); }else{ diff --git a/core/src/mindustry/net/Administration.java b/core/src/mindustry/net/Administration.java index fde1a9c4fc..7e5eb65339 100644 --- a/core/src/mindustry/net/Administration.java +++ b/core/src/mindustry/net/Administration.java @@ -24,6 +24,7 @@ public class Administration{ public Seq chatFilters = new Seq<>(); public Seq actionFilters = new Seq<>(); public Seq subnetBans = new Seq<>(); + public ObjectMap kickedIPs = new ObjectMap<>(); /** All player info. Maps UUIDs to info. This persists throughout restarts. Do not access directly. */ private ObjectMap playerInfo = new ObjectMap<>(); @@ -86,6 +87,20 @@ public class Administration{ }); } + /** @return time at which a player would be pardoned for a kick (0 means they were never kicked) */ + public long getKickTime(String uuid, String ip){ + return Math.max(getInfo(uuid).lastKicked, kickedIPs.get(ip, 0L)); + } + + /** Sets up kick duration for a player. */ + public void handleKicked(String uuid, String ip, long duration){ + kickedIPs.put(ip, Math.max(kickedIPs.get(ip, 0L), Time.millis() + duration)); + + PlayerInfo info = getInfo(uuid); + info.timesKicked++; + info.lastKicked = Math.max(Time.millis() + duration, info.lastKicked); + } + public Seq getSubnetBans(){ return subnetBans; } diff --git a/core/src/mindustry/net/NetConnection.java b/core/src/mindustry/net/NetConnection.java index 07de024e7f..976bea5a74 100644 --- a/core/src/mindustry/net/NetConnection.java +++ b/core/src/mindustry/net/NetConnection.java @@ -65,9 +65,7 @@ public abstract class NetConnection{ Log.info("Kicking connection @; Reason: @", address, reason.replace("\n", " ")); - PlayerInfo info = netServer.admins.getInfo(uuid); - info.timesKicked++; - info.lastKicked = Math.max(Time.millis() + kickDuration, info.lastKicked); + netServer.admins.handleKicked(uuid, address, kickDuration); Call.kick(this, reason); diff --git a/core/src/mindustry/type/AmmoType.java b/core/src/mindustry/type/AmmoType.java new file mode 100644 index 0000000000..afe0a9818a --- /dev/null +++ b/core/src/mindustry/type/AmmoType.java @@ -0,0 +1,28 @@ +package mindustry.type; + +import arc.graphics.*; +import mindustry.ctype.*; +import mindustry.gen.*; +import mindustry.graphics.*; + +/** Type of ammo that a unit uses. */ +public class AmmoType extends Content{ + public String icon = Iconc.itemCopper + ""; + public Color color = Pal.ammo; + public Color barColor = Pal.ammo; + + public AmmoType(char icon, Color color){ + this.icon = icon + ""; + this.color = color; + } + + public AmmoType(){ + } + + public void resupply(Unit unit){} + + @Override + public ContentType getContentType(){ + return ContentType.ammo; + } +} diff --git a/core/src/mindustry/type/AmmoTypes.java b/core/src/mindustry/type/AmmoTypes.java new file mode 100644 index 0000000000..0dafe2ba8b --- /dev/null +++ b/core/src/mindustry/type/AmmoTypes.java @@ -0,0 +1,86 @@ +package mindustry.type; + +import arc.util.ArcAnnotate.*; +import mindustry.*; +import mindustry.content.*; +import mindustry.ctype.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.world.*; +import mindustry.world.meta.*; + +public class AmmoTypes implements ContentList{ + public static AmmoType + powerLow, + power, + powerHigh, + copper, + thorium; + + @Override + public void load(){ + powerLow = new PowerAmmoType(500); + power = new PowerAmmoType(1000); + powerHigh = new PowerAmmoType(2000); + copper = new ItemAmmoType(Items.copper); + thorium = new ItemAmmoType(Items.thorium); + } + + public static class PowerAmmoType extends AmmoType{ + public float totalPower = 1000; + + public PowerAmmoType(){ + super(Iconc.power, Pal.powerLight); + barColor = color; + } + + public PowerAmmoType(float totalPower){ + this(); + this.totalPower = totalPower; + } + + @Override + public void resupply(Unit unit){ + float range = unit.hitSize + 60f; + Tile closest = Vars.indexer.findClosestFlag(unit.x, unit.y, unit.team, BlockFlag.powerResupply); + + if(closest != null && closest.build != null && unit.within(closest.build, range) && closest.build.power != null){ + Building build = closest.build; + + if(build.block.consumes.hasPower() && build.block.consumes.getPower().buffered){ + float amount = closest.build.power.status * build.block.consumes.getPower().capacity; + float powerPerAmmo = totalPower / unit.type().ammoCapacity; + float ammoRequired = unit.type().ammoCapacity - unit.ammo; + float powerRequired = ammoRequired * powerPerAmmo; + float powerTaken = Math.min(amount, powerRequired); + + if(powerTaken > 1){ + closest.build.power.status -= powerTaken / build.block.consumes.getPower().capacity; + unit.ammo += powerTaken / powerPerAmmo; + + Fx.itemTransfer.at(build.x, build.y, Math.max(powerTaken / 100f, 1f), Pal.power, unit); + } + } + } + } + } + + public static class ItemAmmoType extends AmmoType{ + public @NonNull Item item; + + public ItemAmmoType(Item item){ + this.item = item; + this.color = item.color; + } + + public ItemAmmoType(){ + } + + @Override + public void load(){ + if(item != null){ + icon = item.emoji(); + } + } + } +} diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index cce31e77c1..fda8dbbbf2 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -56,7 +56,7 @@ public class StatusEffect extends MappableContent{ } if(effect != Fx.none && Mathf.chanceDelta(effectChance)){ - Tmp.v1.rnd(unit.type().hitsize/2f); + Tmp.v1.rnd(unit.type().hitSize /2f); effect.at(unit.x + Tmp.v1.x, unit.y + Tmp.v1.y); } } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 8fd2e45e82..8f89385640 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -72,7 +72,8 @@ public class UnitType extends UnlockableContent{ public Color mechLegColor = Pal.darkMetal; public int itemCapacity = -1; - public int ammoCapacity = 220; + public int ammoCapacity = -1; + public AmmoType ammoType = AmmoTypes.copper; public int mineTier = -1; public float buildSpeed = 1f, mineSpeed = 1f; @@ -80,7 +81,7 @@ public class UnitType extends UnlockableContent{ public boolean canDrown = true; public float engineOffset = 5f, engineSize = 2.5f; public float strafePenalty = 0.5f; - public float hitsize = 6f; + public float hitSize = 6f; public float itemOffsetY = 3f; public float lightRadius = 60f, lightOpacity = 0.6f; public Color lightColor = Pal.powerLight; @@ -136,41 +137,6 @@ public class UnitType extends UnlockableContent{ public void update(Unit unit){ - if(unit instanceof Mechc && !unit.isFlying()){ - updateMechEffects(unit); - } - } - - public void updateMechEffects(Unit unit){ - Mechc mech = (Mechc)unit; - - float extend = walkExtend((Mechc)unit, false); - float base = walkExtend((Mechc)unit, true); - float extendScl = base % 1f; - - float lastExtend = mech.walkExtension(); - - if(extendScl < lastExtend && base % 2f > 1f){ - int side = -Mathf.sign(extend); - float width = hitsize / 2f * side, length = mechStride * 1.35f; - - float cx = unit.x + Angles.trnsx(mech.baseRotation(), length, width), - cy = unit.y + Angles.trnsy(mech.baseRotation(), length, width); - - if(mechStepShake > 0){ - Effect.shake(mechStepShake, mechStepShake, cx, cy); - } - - if(mechStepParticles){ - Tile tile = world.tileWorld(cx, cy); - if(tile != null){ - Color color = tile.floor().mapColor; - Fx.unitLand.at(cx, cy, hitsize/8f, color); - } - } - } - - mech.walkExtension(extendScl); } public void landed(Unit unit){} @@ -184,13 +150,13 @@ public class UnitType extends UnlockableContent{ table.row(); table.table(bars -> { - bars.defaults().growX().height(18f).pad(4); + bars.defaults().growX().height(20f).pad(4); bars.add(new Bar("blocks.health", Pal.health, unit::healthf).blink(Color.white)); bars.row(); if(state.rules.unitAmmo){ - bars.add(new Bar("blocks.ammo", Pal.ammo, () -> unit.ammo / ammoCapacity)); + bars.add(new Bar(ammoType.icon + " " + Core.bundle.get("blocks.ammo"), ammoType.barColor, () -> unit.ammo / ammoCapacity)); bars.row(); } }).growX(); @@ -237,24 +203,24 @@ public class UnitType extends UnlockableContent{ singleTarget = weapons.size <= 1; if(itemCapacity < 0){ - itemCapacity = Math.max(Mathf.round(hitsize * 7, 20), 20); + itemCapacity = Math.max(Mathf.round(hitSize * 7, 20), 20); } //set up default range if(range < 0){ range = Float.MAX_VALUE; for(Weapon weapon : weapons){ - range = Math.min(range, weapon.bullet.range() + hitsize/2f); + range = Math.min(range, weapon.bullet.range() + hitSize /2f); } } if(mechStride < 0){ - mechStride = 4f + (hitsize-8f)/2.1f; + mechStride = 4f + (hitSize -8f)/2.1f; } if(mechStepShake < 0){ - mechStepShake = Mathf.round((hitsize - 11f) / 9f); - mechStepParticles = hitsize > 15f; + mechStepShake = Mathf.round((hitSize - 11f) / 9f); + mechStepParticles = hitSize > 15f; } canHeal = weapons.contains(w -> w.bullet instanceof HealBulletType); @@ -281,6 +247,15 @@ public class UnitType extends UnlockableContent{ } } this.weapons = mapped; + + //dynamically create ammo capacity based on firing rate + if(ammoCapacity < 0){ + float shotsPerSecond = weapons.sumf(w -> 60f / w.reload); + //duration of continuous fire without reload + float targetSeconds = 30; + + ammoCapacity = Math.max(1, (int)(shotsPerSecond * targetSeconds)); + } } @CallSuper @@ -342,7 +317,7 @@ public class UnitType extends UnlockableContent{ public void draw(Unit unit){ Mechc mech = unit instanceof Mechc ? (Mechc)unit : null; - float z = unit.elevation > 0.5f ? (lowAltitude ? Layer.flyingUnitLow : Layer.flyingUnit) : groundLayer + Mathf.clamp(hitsize/4000f, 0, 0.01f); + float z = unit.elevation > 0.5f ? (lowAltitude ? Layer.flyingUnitLow : Layer.flyingUnit) : groundLayer + Mathf.clamp(hitSize /4000f, 0, 0.01f); if(unit.controller().isBeingControlled(player.unit())){ drawControl(unit); @@ -359,10 +334,10 @@ public class UnitType extends UnlockableContent{ drawMech(mech); //side - legOffset.trns(mech.baseRotation(), 0f, Mathf.lerp(Mathf.sin(walkExtend(mech, true), 2f/Mathf.PI, 1) * mechSideSway, 0f, unit.elevation)); + legOffset.trns(mech.baseRotation(), 0f, Mathf.lerp(Mathf.sin(mech.walkExtend(true), 2f/Mathf.PI, 1) * mechSideSway, 0f, unit.elevation)); //front - legOffset.add(Tmp.v1.trns(mech.baseRotation() + 90, 0f, Mathf.lerp(Mathf.sin(walkExtend(mech, true), 1f/Mathf.PI, 1) * mechFrontSway, 0f, unit.elevation))); + legOffset.add(Tmp.v1.trns(mech.baseRotation() + 90, 0f, Mathf.lerp(Mathf.sin(mech.walkExtend(true), 1f/Mathf.PI, 1) * mechFrontSway, 0f, unit.elevation))); unit.trns(legOffset.x, legOffset.y); } @@ -656,8 +631,8 @@ public class UnitType extends UnlockableContent{ float e = unit.elevation; - float sin = Mathf.lerp(Mathf.sin(walkExtend(mech, true), 2f / Mathf.PI, 1f), 0f, e); - float extension = Mathf.lerp(walkExtend(mech, false), 0, e); + float sin = Mathf.lerp(Mathf.sin(mech.walkExtend(true), 2f / Mathf.PI, 1f), 0f, e); + float extension = Mathf.lerp(mech.walkExtend(false), 0, e); float boostTrns = e * 2f; Floor floor = unit.isFlying() ? Blocks.air.asFloor() : unit.floorOn(); @@ -690,20 +665,6 @@ public class UnitType extends UnlockableContent{ Draw.mixcol(); } - public float walkExtend(Mechc mech, boolean scaled){ - - //now ranges from -maxExtension to maxExtension*3 - float raw = mech.walkTime() % (mechStride * 4); - - if(scaled) return raw / mechStride; - - if(raw > mechStride*3) raw = raw - mechStride * 4; - else if(raw > mechStride*2) raw = mechStride * 2 - raw; - else if(raw > mechStride) raw = mechStride * 2 - raw; - - return raw; - } - public void applyColor(Unit unit){ Draw.color(); Draw.mixcol(Color.white, unit.hitTime); diff --git a/core/src/mindustry/ui/Bar.java b/core/src/mindustry/ui/Bar.java index cb1588650d..d58ad53c37 100644 --- a/core/src/mindustry/ui/Bar.java +++ b/core/src/mindustry/ui/Bar.java @@ -21,7 +21,7 @@ public class Bar extends Element{ public Bar(String name, Color color, Floatp fraction){ this.fraction = fraction; - this.name = Core.bundle.get(name); + this.name = Core.bundle.get(name, name); this.blinkColor.set(color); lastValue = value = fraction.get(); setColor(color); diff --git a/core/src/mindustry/ui/ContentDisplay.java b/core/src/mindustry/ui/ContentDisplay.java index a9902349bb..3e82412f0e 100644 --- a/core/src/mindustry/ui/ContentDisplay.java +++ b/core/src/mindustry/ui/ContentDisplay.java @@ -130,7 +130,7 @@ public class ContentDisplay{ public static void displayUnit(Table table, UnitType unit){ table.table(title -> { - title.image(unit.icon(Cicon.xlarge)); + title.image(unit.icon(Cicon.xlarge)).size(8 * 6).scaling(Scaling.fit); title.add("[accent]" + unit.localizedName).padLeft(5); }); diff --git a/core/src/mindustry/ui/dialogs/JoinDialog.java b/core/src/mindustry/ui/dialogs/JoinDialog.java index 648f504e9b..1c80418708 100644 --- a/core/src/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/mindustry/ui/dialogs/JoinDialog.java @@ -30,6 +30,7 @@ public class JoinDialog extends BaseDialog{ Table global = new Table(); Table hosts = new Table(); int totalHosts; + int refreshes; public JoinDialog(){ super("@joingame"); @@ -95,6 +96,8 @@ public class JoinDialog extends BaseDialog{ } void refreshAll(){ + refreshes ++; + refreshLocal(); refreshRemote(); refreshGlobal(); @@ -327,12 +330,15 @@ public class JoinDialog extends BaseDialog{ } void refreshGlobal(){ + int cur = refreshes; + global.clear(); global.background(null); for(String host : defaultServers){ String resaddress = host.contains(":") ? host.split(":")[0] : host; int resport = host.contains(":") ? Strings.parseInt(host.split(":")[1]) : port; net.pingHost(resaddress, resport, res -> { + if(refreshes != cur) return; res.port = resport; addGlobalHost(res); }, e -> {}); diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index c4cfc02132..8dd9753fda 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -93,7 +93,7 @@ public class SettingsMenuDialog extends SettingsDialog{ ObjectMap map = new ObjectMap<>(); for(String value : Core.settings.keys()){ if(value.contains("usid") || value.contains("uuid")){ - map.put(value, Core.settings.getString(value)); + map.put(value, Core.settings.get(value, null)); } } Core.settings.clear(); diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index 65038ee67f..e5b6dd9713 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -741,7 +741,7 @@ public class HudFragment extends Fragment{ t.add(new SideBar(() -> player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad); t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f); t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> { - b.color.set(player.displayAmmo() ? Pal.ammo : Pal.health); + b.color.set(player.displayAmmo() ? player.dead() ? Pal.ammo : player.unit().type().ammoType.color : Pal.health); }); t.getChildren().get(1).toFront(); diff --git a/core/src/mindustry/world/blocks/power/Battery.java b/core/src/mindustry/world/blocks/power/Battery.java index 35b9965eaa..d556f584f5 100644 --- a/core/src/mindustry/world/blocks/power/Battery.java +++ b/core/src/mindustry/world/blocks/power/Battery.java @@ -2,8 +2,10 @@ package mindustry.world.blocks.power; import arc.graphics.*; import arc.graphics.g2d.*; +import arc.struct.*; import mindustry.annotations.Annotations.*; import mindustry.gen.*; +import mindustry.world.meta.*; import static mindustry.Vars.tilesize; @@ -17,6 +19,7 @@ public class Battery extends PowerDistributor{ super(name); outputsPower = true; consumesPower = true; + flags = EnumSet.of(BlockFlag.powerResupply); } public class BatteryBuild extends Building{ diff --git a/core/src/mindustry/world/blocks/units/ResupplyPoint.java b/core/src/mindustry/world/blocks/units/ResupplyPoint.java index 5967fdd035..2af0998421 100644 --- a/core/src/mindustry/world/blocks/units/ResupplyPoint.java +++ b/core/src/mindustry/world/blocks/units/ResupplyPoint.java @@ -5,6 +5,7 @@ import mindustry.content.*; import mindustry.entities.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.type.AmmoTypes.*; import mindustry.world.*; import static mindustry.Vars.*; @@ -53,10 +54,10 @@ public class ResupplyPoint extends Block{ public static boolean resupply(Building tile, float range, int ammoAmount, Color ammoColor){ if(!state.rules.unitAmmo) return false; - Unit unit = Units.closest(tile.team, tile.x, tile.y, range, u -> u.ammo() <= u.type().ammoCapacity - ammoAmount); + Unit unit = Units.closest(tile.team, tile.x, tile.y, range, u -> u.type().ammoType instanceof ItemAmmoType && u.ammo <= u.type().ammoCapacity - ammoAmount); if(unit != null){ Fx.itemTransfer.at(tile.x, tile.y, ammoAmount / 2f, ammoColor, unit); - unit.ammo(Math.min(unit.ammo() + ammoAmount, unit.type().ammoCapacity)); + unit.ammo = Math.min(unit.ammo + ammoAmount, unit.type().ammoCapacity); return true; } diff --git a/core/src/mindustry/world/meta/BlockFlag.java b/core/src/mindustry/world/meta/BlockFlag.java index ddf9fa9ba7..c818ba642a 100644 --- a/core/src/mindustry/world/meta/BlockFlag.java +++ b/core/src/mindustry/world/meta/BlockFlag.java @@ -12,6 +12,8 @@ public enum BlockFlag{ repair, /** Rally point. */ rally, + /** Block that stored power for resupply. */ + powerResupply, /** Any block that boosts unit capacity. */ unitModifier;