Skip to content

Commit 27b0686

Browse files
committed
Scale particles for singleplayer
1 parent 5a2bb8a commit 27b0686

File tree

13 files changed

+198
-34
lines changed

13 files changed

+198
-34
lines changed

src/main/java/net/superkat/explosiveenhancement/ExplosiveEnhancement.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
import net.minecraft.particle.SimpleParticleType;
2323
//?}
2424

25+
//? if(>=1.21.2) {
26+
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
27+
import net.superkat.explosiveenhancement.network.S2CExplosiveEnhancementParticles;
28+
//?}
29+
2530
public class ExplosiveEnhancement implements ModInitializer {
2631
public static final String MOD_ID = "explosiveenhancement";
2732
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
@@ -50,6 +55,12 @@ public class ExplosiveEnhancement implements ModInitializer {
5055
public static final SimpleParticleType UNDERWATERSPARKS = FabricParticleTypes.simple();
5156
//?}
5257

58+
//? if(>=1.21.2)
59+
public static final SimpleParticleType NO_RENDER_PARTICLE = FabricParticleTypes.simple();
60+
//?}
61+
62+
//TODO - change flash particle to custom "noexplosion" particle
63+
5364
@Override
5465
public void onInitialize() {
5566
registerParticle(id("blastwave"), BLASTWAVE);
@@ -62,6 +73,12 @@ public void onInitialize() {
6273
registerParticle(id("underwaterblastwave"), UNDERWATERBLASTWAVE);
6374
registerParticle(id("sparks"), SPARKS);
6475
registerParticle(id("underwatersparks"), UNDERWATERSPARKS);
76+
77+
//? if(>=1.21.2) {
78+
//Used for the single player dynamic explosions
79+
registerParticle(id("norenderparticle"), NO_RENDER_PARTICLE);
80+
PayloadTypeRegistry.playS2C().register(S2CExplosiveEnhancementParticles.ID, S2CExplosiveEnhancementParticles.CODEC);
81+
//?}
6582
}
6683

6784
public void registerParticle(Identifier id, ParticleType<?> particle) {

src/main/java/net/superkat/explosiveenhancement/ExplosiveEnhancementClient.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,27 @@
33
import net.fabricmc.api.ClientModInitializer;
44
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
55
import net.fabricmc.loader.api.FabricLoader;
6+
import net.minecraft.client.particle.NoRenderParticle;
67
import net.superkat.explosiveenhancement.config.ExplosiveConfig;
78
import net.superkat.explosiveenhancement.particles.normal.BlastWaveParticle;
89
import net.superkat.explosiveenhancement.particles.normal.FireballParticle;
10+
import net.superkat.explosiveenhancement.particles.normal.NoRender;
911
import net.superkat.explosiveenhancement.particles.normal.SmokeParticle;
1012
import net.superkat.explosiveenhancement.particles.normal.SparkParticle;
1113
import net.superkat.explosiveenhancement.particles.underwater.BubbleParticle;
1214
import net.superkat.explosiveenhancement.particles.underwater.ShockwaveParticle;
1315
import net.superkat.explosiveenhancement.particles.underwater.UnderwaterBlastWaveParticle;
1416
import net.superkat.explosiveenhancement.particles.underwater.UnderwaterSparkParticle;
1517

18+
//? if(>=1.21.2) {
19+
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
20+
import net.superkat.explosiveenhancement.network.S2CExplosiveEnhancementParticles;
21+
import net.superkat.explosiveenhancement.api.ExplosionParticleType;
22+
import net.superkat.explosiveenhancement.api.ExplosiveApi;
23+
import net.minecraft.util.math.Vec3d;
24+
import net.minecraft.world.World;
25+
//?}
26+
1627
public class ExplosiveEnhancementClient implements ClientModInitializer {
1728

1829
public static ExplosiveConfig CONFIG = ExplosiveConfig.INSTANCE;
@@ -35,6 +46,28 @@ public void onInitializeClient() {
3546
ParticleFactoryRegistry.getInstance().register(ExplosiveEnhancement.BLANK_SHOCKWAVE, ShockwaveParticle.Factory::new);
3647
ParticleFactoryRegistry.getInstance().register(ExplosiveEnhancement.UNDERWATERBLASTWAVE, UnderwaterBlastWaveParticle.Factory::new);
3748
ParticleFactoryRegistry.getInstance().register(ExplosiveEnhancement.UNDERWATERSPARKS, UnderwaterSparkParticle.Factory::new);
49+
50+
//? if(>=1.21.2) {
51+
ParticleFactoryRegistry.getInstance().register(ExplosiveEnhancement.NO_RENDER_PARTICLE, NoRender.Factory::new);
52+
53+
ClientPlayNetworking.registerGlobalReceiver(S2CExplosiveEnhancementParticles.ID, (payload, context) -> {
54+
if(CONFIG.bypassPowerForSingleplayer) {
55+
World world = context.client().world;
56+
double x = payload.x();
57+
double y = payload.y();
58+
double z = payload.z();
59+
ExplosionParticleType explosionParticleType = ExplosiveApi.determineParticleType(world, new Vec3d(x, y, z), payload.initParticle());
60+
ExplosiveApi.spawnParticles(world, x, y, z, payload.power(), explosionParticleType);
61+
62+
boolean showVanillaParticles =
63+
(CONFIG.showDefaultExplosion && explosionParticleType == ExplosionParticleType.NORMAL)
64+
|| (CONFIG.showDefaultExplosionUnderwater && explosionParticleType == ExplosionParticleType.WATER);
65+
if(showVanillaParticles) {
66+
world.addParticle(payload.initParticle(), x, y, z, 0f, 0f, 0f);
67+
}
68+
}
69+
});
70+
//?}
3871
}
3972

4073
public static boolean YaclLoaded() {

src/main/java/net/superkat/explosiveenhancement/ExplosiveHandler.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,6 @@ public static void spawnExplosionParticles(World world, double x, double y, doub
200200
if(CONFIG.showMushroomCloud) {
201201
spawnMushroomCloud(world, x, y, z, power, smokePower, isImportant);
202202
}
203-
204-
if(CONFIG.showDefaultExplosion) {
205-
spawnVanillaParticles(world, x, y, z, power, didDestroyBlocks, isImportant, false);
206-
}
207203
}
208204

209205
public static void spawnUnderwaterExplosionParticles(World world, double x, double y, double z, float power, boolean didDestroyBlocks, boolean isImportant) {
@@ -225,10 +221,6 @@ public static void spawnUnderwaterExplosionParticles(World world, double x, doub
225221
}
226222

227223
spawnBubble(world, x, y, z, isImportant);
228-
229-
if(CONFIG.showDefaultExplosionUnderwater) {
230-
spawnVanillaParticles(world, x, y, z, power, didDestroyBlocks, isImportant, false);
231-
}
232224
}
233225

234226
private static void spawnMushroomCloud(World world, double x, double y, double z, float power, double smokePower, boolean isImportant) {

src/main/java/net/superkat/explosiveenhancement/config/YaclIntegration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,11 @@ public static Screen makeScreen(Screen parent) {
417417
dynamicExplosionGroup.option(smallExtraPower);
418418
dynamicExplosionGroup.option(attemptBetterSmallExplosions);
419419
dynamicExplosionGroup.option(smallExplosionYOffset);
420+
//? if(>=1.21.2)
420421
dynamicExplosionGroup.option(sad121_2notice);
421422
dynamicExplosionGroup.option(bypassPowerForSingleplayer);
422423
dynamicExplosionGroup.option(attemptPowerKnockbackCalc);
424+
//?}
423425
dynamicCategoryBuilder.group(dynamicExplosionGroup.build());
424426

425427

src/main/java/net/superkat/explosiveenhancement/mixin/ClientPlayNetworkHandlerMixin.java

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
package net.superkat.explosiveenhancement.mixin;
22

3-
import net.minecraft.client.MinecraftClient;
43
import net.minecraft.client.network.ClientPlayNetworkHandler;
54
import net.minecraft.client.world.ClientWorld;
65
import net.minecraft.network.packet.s2c.play.ExplosionS2CPacket;
6+
import net.minecraft.particle.ParticleEffect;
77
import net.minecraft.particle.ParticleTypes;
88
import net.minecraft.util.math.Vec3d;
99
import net.minecraft.world.World;
10-
import net.superkat.explosiveenhancement.ExplosiveEnhancementClient;
10+
import net.superkat.explosiveenhancement.ExplosiveEnhancement;
1111
import net.superkat.explosiveenhancement.api.ExplosionParticleType;
1212
import net.superkat.explosiveenhancement.api.ExplosiveApi;
1313
import org.spongepowered.asm.mixin.Mixin;
1414
import org.spongepowered.asm.mixin.Shadow;
1515
import org.spongepowered.asm.mixin.injection.At;
1616
import org.spongepowered.asm.mixin.injection.Inject;
1717
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
18-
19-
import static net.superkat.explosiveenhancement.ExplosiveEnhancementClient.CONFIG;
2018
import static net.superkat.explosiveenhancement.ExplosiveEnhancement.LOGGER;
19+
import static net.superkat.explosiveenhancement.ExplosiveEnhancementClient.CONFIG;
2120

2221
@Mixin(ClientPlayNetworkHandler.class)
2322
public abstract class ClientPlayNetworkHandlerMixin {
24-
//? if(>=1.21.3) {
23+
//? if (>=1.21.3) {
2524

2625
@Shadow public abstract ClientWorld getWorld();
2726

@@ -33,23 +32,22 @@ public abstract class ClientPlayNetworkHandlerMixin {
3332
World world = this.getWorld();
3433
Vec3d pos = packet.center();
3534

36-
ExplosionParticleType explosionParticleType = ExplosiveApi.determineParticleType(world, pos, packet.explosionParticle());
35+
ParticleEffect particle = packet.explosionParticle();
36+
if(particle == ExplosiveEnhancement.NO_RENDER_PARTICLE && CONFIG.bypassPowerForSingleplayer) {
37+
return;
38+
}
39+
40+
ExplosionParticleType explosionParticleType = ExplosiveApi.determineParticleType(world, pos, particle);
3741
if(explosionParticleType != ExplosionParticleType.WIND) { //allows normal wind particles to be shown
3842
float power = ExplosiveApi.getPowerFromExplosionPacket(world, packet);
39-
// float power = 0;
40-
// boolean powerFromKb = false;
41-
// if(packet.playerKnockback().isPresent()) {
42-
// power = ExplosiveApi.getPowerFromKnockback(world, pos, MinecraftClient.getInstance().player, packet.playerKnockback().get());
43-
// powerFromKb = true;
44-
// if(CONFIG.debugLogs) { LOGGER.info("[Explosive Enhancement]: power from knockback: {}", power); }
45-
// }
46-
//
47-
// if(!powerFromKb || Float.isNaN(power)) {
48-
// //change to api method
49-
// power = packet.explosionParticle() == ParticleTypes.EXPLOSION_EMITTER ? 4f : 2f;
50-
// }
51-
ExplosiveApi.spawnParticles(world, pos.getX(), pos.getY(), pos.getZ(), power, explosionParticleType, true);
52-
ci.cancel();
43+
ExplosiveApi.spawnParticles(world, pos.getX(), pos.getY(), pos.getZ(), power, explosionParticleType);
44+
boolean showVanillaParticles =
45+
(CONFIG.showDefaultExplosion && explosionParticleType == ExplosionParticleType.NORMAL)
46+
|| (CONFIG.showDefaultExplosionUnderwater && explosionParticleType == ExplosionParticleType.WATER);
47+
48+
if(!showVanillaParticles) {
49+
ci.cancel();
50+
}
5351
}
5452
}
5553
}

src/main/java/net/superkat/explosiveenhancement/mixin/ExplosionMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
public abstract class ExplosionMixin {
2020
//The client-side explosion handling changed in 1.21.2/3, requiring a new mixin
2121

22-
//?if(<=1.21.1) {
22+
//? if (<=1.21.1) {
2323
// @Shadow @Final private World world;
2424
// @Shadow @Final private double x;
2525
// @Shadow @Final private double y;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package net.superkat.explosiveenhancement.mixin;
2+
3+
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
4+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
5+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
6+
import com.llamalad7.mixinextras.sugar.Local;
7+
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
8+
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
9+
import net.minecraft.entity.Entity;
10+
import net.minecraft.entity.damage.DamageSource;
11+
import net.minecraft.particle.ParticleEffect;
12+
import net.minecraft.particle.ParticleTypes;
13+
import net.minecraft.registry.entry.RegistryEntry;
14+
import net.minecraft.server.network.ServerPlayerEntity;
15+
import net.minecraft.server.world.ServerWorld;
16+
import net.minecraft.sound.SoundEvent;
17+
import net.minecraft.util.math.Vec3d;
18+
import net.minecraft.world.World;
19+
import net.minecraft.world.explosion.ExplosionBehavior;
20+
import net.minecraft.world.explosion.ExplosionImpl;
21+
import net.superkat.explosiveenhancement.ExplosiveEnhancement;
22+
import net.superkat.explosiveenhancement.ExplosiveEnhancementClient;
23+
import net.superkat.explosiveenhancement.network.S2CExplosiveEnhancementParticles;
24+
import org.jetbrains.annotations.Nullable;
25+
import org.spongepowered.asm.mixin.Final;
26+
import org.spongepowered.asm.mixin.Mixin;
27+
import org.spongepowered.asm.mixin.Shadow;
28+
import org.spongepowered.asm.mixin.injection.At;
29+
import org.spongepowered.asm.mixin.injection.Inject;
30+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
31+
32+
import java.util.List;
33+
34+
@Mixin(ServerWorld.class)
35+
public class ServerWorldMixin {
36+
37+
@Shadow @Final private List<ServerPlayerEntity> players;
38+
39+
@Inject(method = "createExplosion", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/explosion/ExplosionImpl;getKnockbackByPlayer()Ljava/util/Map;"))
40+
public void explosiveenhancement$scaleParticlesForSingleplayer(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionBehavior behavior, double x, double y, double z, float power, boolean createFire, World.ExplosionSourceType explosionSourceType, ParticleEffect smallParticle, ParticleEffect largeParticle, RegistryEntry<SoundEvent> soundEvent, CallbackInfo ci, @Local(ordinal = 2) LocalRef<ParticleEffect> effect) {
41+
ServerWorld world = (ServerWorld)(Object)this;
42+
if (world.getServer().isSingleplayer() && this.players.size() == 1) {
43+
if(ExplosiveEnhancementClient.CONFIG.bypassPowerForSingleplayer) {
44+
ServerPlayNetworking.send(this.players.getFirst(), new S2CExplosiveEnhancementParticles(x, y, z, power, effect.get()));
45+
effect.set(ExplosiveEnhancement.NO_RENDER_PARTICLE);
46+
}
47+
}
48+
}
49+
50+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package net.superkat.explosiveenhancement.network;
2+
3+
import net.minecraft.network.RegistryByteBuf;
4+
import net.minecraft.network.codec.PacketCodec;
5+
import net.minecraft.network.packet.CustomPayload;
6+
import net.minecraft.particle.ParticleEffect;
7+
import net.minecraft.particle.ParticleTypes;
8+
import net.minecraft.util.Identifier;
9+
import net.superkat.explosiveenhancement.ExplosiveEnhancement;
10+
11+
/**
12+
* Despite this being a Server-To-Client packet, IT DOES NOT LOAD ON THE SERVER AS OF 1.3.0!!
13+
* <br><br>Explosive Enhancement is set to a "client" mod in the fabric.mod.json, meaning it is not loaded on a server environment.
14+
* <br><br>This packet is used to dynamically scale explosions in single player. I may use it for a server environment in the future.
15+
*/
16+
public record S2CExplosiveEnhancementParticles(double x, double y, double z, float power, ParticleEffect initParticle) implements CustomPayload {
17+
18+
public static final CustomPayload.Id<S2CExplosiveEnhancementParticles> ID = new Id<>(Identifier.of(ExplosiveEnhancement.MOD_ID));
19+
public static final PacketCodec<RegistryByteBuf, S2CExplosiveEnhancementParticles> CODEC = CustomPayload.codecOf(S2CExplosiveEnhancementParticles::write, S2CExplosiveEnhancementParticles::new);
20+
21+
public S2CExplosiveEnhancementParticles(RegistryByteBuf buf) {
22+
this(
23+
buf.readDouble(),
24+
buf.readDouble(),
25+
buf.readDouble(),
26+
buf.readFloat(),
27+
ParticleTypes.PACKET_CODEC.decode(buf)
28+
);
29+
}
30+
31+
public void write(RegistryByteBuf buf) {
32+
buf.writeDouble(this.x);
33+
buf.writeDouble(this.y);
34+
buf.writeDouble(this.z);
35+
buf.writeFloat(this.power);
36+
ParticleTypes.PACKET_CODEC.encode(buf, this.initParticle);
37+
}
38+
39+
@Override
40+
public Id<? extends CustomPayload> getId() {
41+
return ID;
42+
}
43+
}

src/main/java/net/superkat/explosiveenhancement/particles/normal/BlastWaveParticle.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ public void buildGeometry(VertexConsumer buffer, Camera camera, float ticks) {
7474
Vector3f vector3f = vector3fs[i];
7575
vector3f.rotate(QUATERNION);
7676
vector3f.mul(f4);
77-
vector3f.add(x, y, z);
77+
vector3f.add(x, y + 0.01f, z); //slightly higher to avoid z-fighting with bottom particle and hopefully ground-level blocks as well
7878

7979
// Create additional vertices for underside faces
8080
Vector3f vector3fBottom = vector3fsBottom[i];
8181
vector3fBottom.rotate(QUATERNION);
8282
vector3fBottom.mul(f4);
83-
vector3fBottom.add(x, y - 0.1F, z); // Slightly lower to avoid z-fighting
83+
vector3fBottom.add(x, y, z);
8484
//?}
8585
}
8686

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.superkat.explosiveenhancement.particles.normal;
2+
3+
import net.fabricmc.api.EnvType;
4+
import net.fabricmc.api.Environment;
5+
import net.minecraft.client.particle.NoRenderParticle;
6+
import net.minecraft.client.particle.Particle;
7+
import net.minecraft.client.particle.ParticleFactory;
8+
import net.minecraft.client.particle.SpriteProvider;
9+
import net.minecraft.client.world.ClientWorld;
10+
import net.minecraft.particle.ParticleEffect;
11+
12+
public class NoRender extends NoRenderParticle {
13+
protected NoRender(ClientWorld clientWorld, double d, double e, double f) {
14+
super(clientWorld, d, e, f);
15+
}
16+
17+
@Environment(EnvType.CLIENT)
18+
public record Factory<T extends ParticleEffect>(SpriteProvider sprites) implements ParticleFactory<T> {
19+
public Particle createParticle(T type, ClientWorld world, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {
20+
return new NoRender(world, x, y, z);
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)