From 6983959aebea7877ef5f02c66f051e41f97cb3a0 Mon Sep 17 00:00:00 2001 From: Anuke Date: Sat, 5 Mar 2022 11:06:28 -0500 Subject: [PATCH] Fog fixes / Weapon attack fixes / Avert weapon --- .../sprites/units/weapons/avert-weapon.png | Bin 0 -> 6929 bytes core/src/mindustry/ai/types/BuilderAI.java | 2 +- core/src/mindustry/content/UnitTypes.java | 32 ++++++++- .../entities/units/AIController.java | 2 +- core/src/mindustry/game/FogControl.java | 61 ++++++++++++------ core/src/mindustry/type/UnitType.java | 6 +- core/src/mindustry/type/Weapon.java | 2 + .../type/weapons/RepairBeamWeapon.java | 1 + 8 files changed, 80 insertions(+), 26 deletions(-) create mode 100644 core/assets-raw/sprites/units/weapons/avert-weapon.png diff --git a/core/assets-raw/sprites/units/weapons/avert-weapon.png b/core/assets-raw/sprites/units/weapons/avert-weapon.png new file mode 100644 index 0000000000000000000000000000000000000000..08083aef14fa64f8276273c6756463cd4a2ada21 GIT binary patch literal 6929 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 literal 0 HcmV?d00001 diff --git a/core/src/mindustry/ai/types/BuilderAI.java b/core/src/mindustry/ai/types/BuilderAI.java index 01f90942e5..d06812d267 100644 --- a/core/src/mindustry/ai/types/BuilderAI.java +++ b/core/src/mindustry/ai/types/BuilderAI.java @@ -173,6 +173,6 @@ public class BuilderAI extends AIController{ @Override public boolean shouldShoot(){ - return !unit.isBuilding(); + return !unit.isBuilding() && unit.type.canAttack; } } diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index e98b39142a..a43d5a34f5 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -3119,18 +3119,44 @@ public class UnitTypes{ lowAltitude = false; flying = true; drag = 0.08f; - speed = 2.5f; - rotateSpeed = 5f; + speed = 2f; + rotateSpeed = 4f; accel = 0.09f; - health = 600f; + health = 800f; armor = 2f; hitSize = 12f; engineSize = 0; + fogRadius = 25; setEnginesMirror( new UnitEngine(34 / 4f, 31 / 4f, 3f, 45f), new UnitEngine(35 / 4f, -38 / 4f, 3f, 315f) ); + + weapons.add(new Weapon("avert-weapon"){{ + reload = 35f; + x = 4f; + y = 6.25f; + shootY = 5.75f; + recoil = 1.5f; + top = false; + layerOffset = -0.01f; + rotate = false; + + //TODO cooler + balancing + bullet = new BasicBulletType(5f, 15){{ + width = 7f; + height = 12f; + lifetime = 25f; + shootEffect = Fx.sparkShoot; + smokeEffect = Fx.shootBigSmoke; + hitColor = backColor = trailColor = Pal.suppress; + frontColor = Color.white; + trailWidth = 1.5f; + trailLength = 5; + hitEffect = despawnEffect = Fx.hitBulletColor; + }}; + }}); }}; quell = new ErekirUnitType("quell"){{ diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index cd79041957..9d83c8b7ba 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -145,7 +145,7 @@ public class AIController implements UnitController{ float wrange = weapon.range(); //let uncontrollable weapons do their own thing - if(!weapon.controllable) continue; + if(!weapon.controllable || weapon.noAttack) continue; float mountX = unit.x + Angles.trnsx(rotation, weapon.x, weapon.y), mountY = unit.y + Angles.trnsy(rotation, weapon.x, weapon.y); diff --git a/core/src/mindustry/game/FogControl.java b/core/src/mindustry/game/FogControl.java index 6c22af4f80..83d174b0fb 100644 --- a/core/src/mindustry/game/FogControl.java +++ b/core/src/mindustry/game/FogControl.java @@ -35,6 +35,7 @@ public final class FogControl implements CustomChunk{ private @Nullable Thread dynamicFogThread; private boolean justLoaded = false; + private boolean loadedStatic = false; public FogControl(){ Events.on(ResetEvent.class, e -> { @@ -44,19 +45,18 @@ public final class FogControl implements CustomChunk{ Events.on(WorldLoadEvent.class, e -> { stop(); + loadedStatic = false; justLoaded = true; ww = world.width(); wh = world.height(); //all old buildings have static light scheduled around them if(state.rules.fog && state.rules.staticFog){ - synchronized(staticEvents){ - for(var build : Groups.build){ - if(build.block.flags.contains(BlockFlag.hasFogRadius)){ - staticEvents.add(FogEvent.get(build.tile.x, build.tile.y, Mathf.round(build.fogRadius()), build.team.id)); - } - } - } + pushStaticBlocks(); + //force draw all static stuff immediately + updateStatic(); + + loadedStatic = true; } }); @@ -133,6 +133,16 @@ public final class FogControl implements CustomChunk{ } } + void pushStaticBlocks(){ + synchronized(staticEvents){ + for(var build : Groups.build){ + if(build.block.flags.contains(BlockFlag.hasFogRadius)){ + pushEvent(FogEvent.get(build.tile.x, build.tile.y, Mathf.round(build.fogRadius()), build.team.id)); + } + } + } + } + void pushEvent(long event){ if(!state.rules.staticFog) return; @@ -159,6 +169,13 @@ public final class FogControl implements CustomChunk{ fog = new FogData[256]; } + //force update static + if(state.rules.staticFog && !loadedStatic){ + pushStaticBlocks(); + updateStatic(); + loadedStatic = true; + } + //not run clientside, the CPU side isn't needed here. if(staticFogThread == null && !net.client()){ staticFogThread = new StaticFogThread(); @@ -271,25 +288,29 @@ public final class FogControl implements CustomChunk{ } } - //I really don't like synchronizing here, but there should be *some* performance benefit at least - synchronized(staticEvents){ - int size = staticEvents.size; - for(int i = 0; i < size; i++){ - long event = staticEvents.items[i]; - int x = FogEvent.x(event), y = FogEvent.y(event), rad = FogEvent.radius(event), team = FogEvent.team(event); - var data = fog[team]; - if(data != null){ - circle(data.staticData, x, y, rad); - } - } - staticEvents.clear(); - } + updateStatic(); //ignore, don't want to crash this thread }catch(Exception e){} } } } + void updateStatic(){ + //I really don't like synchronizing here, but there should be *some* performance benefit at least + synchronized(staticEvents){ + int size = staticEvents.size; + for(int i = 0; i < size; i++){ + long event = staticEvents.items[i]; + int x = FogEvent.x(event), y = FogEvent.y(event), rad = FogEvent.radius(event), team = FogEvent.team(event); + var data = fog[team]; + if(data != null){ + circle(data.staticData, x, y, rad); + } + } + staticEvents.clear(); + } + } + class DynamicFogThread extends Thread{ final Bits cleared = new Bits(); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 468a994571..0a20701b70 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -181,6 +181,8 @@ public class UnitType extends UnlockableContent{ /** If true, all weapons will attack the same target. */ public boolean singleTarget = false; public boolean forceMultiTarget = false; + /** If false, this unit has no weapons that can attack. */ + public boolean canAttack = true; public boolean hidden = false; public boolean internal = false; /** Function used for calculating cost of moving with ControlPathfinder. Does not affect "normal" flow field pathfinding. */ @@ -464,7 +466,7 @@ public class UnitType extends UnlockableContent{ } if(fogRadius < 0){ - fogRadius = Math.max(lightRadius * 3.1f, 1f) / 8f; + fogRadius = Math.max(11f * 2.3f * 3f, hitSize * 2f) / 8f; } if(weapons.isEmpty()){ @@ -529,6 +531,8 @@ public class UnitType extends UnlockableContent{ weapons.each(Weapon::init); + canAttack = weapons.contains(w -> !w.noAttack); + //dynamically create ammo capacity based on firing rate if(ammoCapacity < 0){ float shotsPerSecond = weapons.sumf(w -> w.useAmmo ? 60f / w.reload : 0f); diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index c437e1a24c..a955ed73ef 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -89,6 +89,8 @@ public class Weapon implements Cloneable{ public float soundPitchMin = 0.8f, soundPitchMax = 1f; /** whether shooter rotation is ignored when shooting. */ public boolean ignoreRotation = false; + /** If true, this weapon cannot be used to attack targets. */ + public boolean noAttack = false; /** min velocity required for this weapon to shoot */ public float minShootVelocity = -1f; /** should the shoot effects follow the unit (effects need followParent set to true for this to work) */ diff --git a/core/src/mindustry/type/weapons/RepairBeamWeapon.java b/core/src/mindustry/type/weapons/RepairBeamWeapon.java index 4e381f5368..2de8102e53 100644 --- a/core/src/mindustry/type/weapons/RepairBeamWeapon.java +++ b/core/src/mindustry/type/weapons/RepairBeamWeapon.java @@ -58,6 +58,7 @@ public class RepairBeamWeapon extends Weapon{ useAmmo = false; mountType = HealBeamMount::new; recoil = 0f; + noAttack = true; } @Override