Skip to content

Commit

Permalink
Update 20241228 - Cannon Turret Implementation
Browse files Browse the repository at this point in the history
Finally implemented a fully working Cannon Turret (without its projectile - Cannonball).

[CHANGELOG]
🟢 Added a base particle emitter class called "CustomEmitter" which provides a base for all emitter type particles such as the Cannon Flash.
🟢 Created a copy of the Projectile Attack Goal class but with an added flexibility of knowing when the entity is shooting or not.
🟡 Renamed CannonFlash into Sparks.
🟡 Updated Cannon Turret's renderer class to prevent the entity from using the standard death rotation animation upon death.
🟡 Updated the Cannon Turret entity class to now minimize usage of other unnecessary and redundant fields, along with its particle keyframe fix and animation fix.
🟡 Moved all RawAnimation instances into a Map for easier access and for reusability (Cannon Turret Entity).
🟡 Updated the value of the "@author" in all class and interface documentation to a link to my GitHub.
🟡 Shortened the animation length of Cannon Fuse to allow the particle's position to immediately update when the Cannon Turret swung its barrel.
🟡 Renamed the particle JSON file of Cannon Flash from "cannon_flash" to "sparks".
🔴 Removed some processes in the Sparks (formerly known as Cannon Flash) and moved it somewhere else.
🔴 Removed all unneeded and redundant data in Turret Entity base entity class.
  • Loading branch information
Virus5600 committed Dec 28, 2024
1 parent ca40641 commit fd0316c
Show file tree
Hide file tree
Showing 15 changed files with 702 additions and 312 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
import com.virus5600.defensive_measures.DefensiveMeasures;

import com.virus5600.defensive_measures.particle.custom.*;
import com.virus5600.defensive_measures.particle.custom.emitters.*;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;

@Environment(EnvType.CLIENT)
public class ModClientParticles {
Expand All @@ -19,7 +16,11 @@ public static void registerParticles() {

ParticleFactoryRegistry registry = ParticleFactoryRegistry.getInstance();

// PARTICLES
registry.register(ModParticles.CANNON_FUSE, CannonFuse.Factory::new);
registry.register(ModParticles.CANNON_FLASH, CannonFlash.Factory::new);
registry.register(ModParticles.SPARKS, Sparks.Factory::new);

// EMITTERS
registry.register(ModParticles.CANNON_FLASH, new CannonFlash.Factory());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;

import com.virus5600.defensive_measures.particle.ModParticles;

/**
* Defines the particles emitted by the {@link com.virus5600.defensive_measures.entity.turrets.CannonTurretEntity Cannon Turret}
* when charging up to fire.
Expand All @@ -22,6 +24,7 @@
@Environment(EnvType.CLIENT)
public class CannonFuse extends SpriteBillboardParticle {
private final Vec3d source;
private final float maxParticleAge = 25;

/// CONSTRUCTORS ///
protected CannonFuse(ClientWorld level, double x, double y, double z, SpriteProvider spriteSet, double xd, double yd, double zd) {
Expand All @@ -32,7 +35,7 @@ protected CannonFuse(ClientWorld level, double x, double y, double z, SpriteProv
this.y = y;
this.z = z;
this.scale *= 0.5f;
this.maxAge = 25;
this.maxAge = 2;
this.gravityStrength = 1f;
this.collidesWithWorld = true;
this.setSpriteForAge(spriteSet);
Expand Down Expand Up @@ -68,7 +71,6 @@ public ParticleTextureSheet getType() {
@Override
public int getBrightness(float tint) {
int i = super.getBrightness(tint);
@SuppressWarnings("unused") int j = 240;
int k = i >> 16 & 0xFF;

return 0xF0 | k << 16;
Expand All @@ -86,10 +88,30 @@ public void tick() {
super.tick();
this.fadeOut();

if (this.age < 10) {
if (this.age < this.maxAge) {
if (MathHelper.nextInt(this.random, 0, 100) > 90) {
this.world.addParticle(ParticleTypes.SMOKE, this.source.x, this.source.y, this.source.z, MathHelper.nextDouble(this.random, -0.01, 0.01), MathHelper.clamp(Math.abs(this.velocityY), 0.0625, 0.125), MathHelper.nextDouble(this.random, -0.01, 0.01));
this.world.addParticle(
ParticleTypes.SMOKE,
this.source.x,
this.source.y,
this.source.z,
MathHelper.nextDouble(this.random, -0.01, 0.01),
MathHelper.clamp(Math.abs(this.velocityY), 0.0625, 0.125),
MathHelper.nextDouble(this.random, -0.01, 0.01)
);
}

if (MathHelper.nextInt(this.random, 0, 100) > 25) {
this.world.addParticle(
ModParticles.SPARKS,
this.source.x,
this.source.y,
this.source.z,
MathHelper.nextDouble(this.random, -0.01, 0.01),
MathHelper.clamp(Math.abs(this.velocityY), 0.0625, 0.125),
MathHelper.nextDouble(this.random, -0.01, 0.01)
);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
package com.virus5600.defensive_measures.particle.custom;

import com.virus5600.defensive_measures.particle.ModParticles;
import com.virus5600.defensive_measures.particle.custom.emitters.CannonFlash;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.*;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;

/**
* Defines the particles emitted by the {@link com.virus5600.defensive_measures.entity.turrets.CannonTurretEntity Cannon Turret}
* when it fires.
* The particle shots out in a cone shape and fades out over time. The direction is
* determined by the direction the turret is facing.
* Defines the particles emitted by certain turrets that creates sparks when they
* shoot. This particle is the base particle for some spark-based particles such
* as the {@link CannonFlash Cannon Flash Emitter}.
*/
@Environment(EnvType.CLIENT)
public class CannonFlash extends SpriteBillboardParticle {
private final Vec3d source;
public class Sparks extends SpriteBillboardParticle {

/// CONSTRUCTORS ///
public CannonFlash(ClientWorld level, double x, double y, double z, SpriteProvider spriteSet, double xd, double yd, double zd) {
public Sparks(ClientWorld level, double x, double y, double z, SpriteProvider spriteSet, double xd, double yd, double zd) {
super(level, x, y, z, xd, yd, zd);

this.velocityMultiplier = 1f;
Expand All @@ -34,23 +29,10 @@ public CannonFlash(ClientWorld level, double x, double y, double z, SpriteProvid
this.collidesWithWorld = true;
this.setSpriteForAge(spriteSet);
this.setVelocity(xd, yd, zd);
this.source = new Vec3d(x, y, z);

this.red = 1f;
this.green = 1f;
this.blue = 1f;

// TODO: Create a separete emitter for the cannon flash, distinguishing the actual flash from the sparks.
final int maxParticles = MathHelper.nextInt(this.random, 15, 25);
for (int i = 10; i <= maxParticles; i++) {
level.addParticle(
ModParticles.CANNON_FLASH,
x, y, z,
MathHelper.nextDouble(this.random, -0.1, 0.1) + xd,
MathHelper.nextDouble(this.random, -0.1, 0.1) + yd,
MathHelper.nextDouble(this.random, -0.1, 0.1) + zd
);
}
}

/// METHODS ///
Expand Down Expand Up @@ -101,20 +83,6 @@ public void setVelocity(double vx, double vy, double vz) {
public void tick() {
super.tick();
this.fadeOut();

if (this.dead) {
for (int i = 0; i < MathHelper.nextInt(this.random, 1, 3); i++) {
this.world.addParticle(
ParticleTypes.CAMPFIRE_COSY_SMOKE,
this.source.x,
this.source.y,
this.source.z,
MathHelper.nextDouble(this.random, -0.01, 0.01),
MathHelper.nextDouble(this.random, 0.01, 0.025),
MathHelper.nextDouble(this.random, -0.01, 0.01)
);
}
}
}

@Environment(EnvType.CLIENT)
Expand All @@ -126,7 +94,7 @@ public Factory(SpriteProvider sprites) {
}

public Particle createParticle(SimpleParticleType type, ClientWorld level, double x, double y, double z, double xd, double yd, double zd) {
return new CannonFlash(level, x, y, z, this.sprites, xd, yd, zd);
return new Sparks(level, x, y, z, this.sprites, xd, yd, zd);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.virus5600.defensive_measures.particle.custom.emitters;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.util.math.MathHelper;

import com.virus5600.defensive_measures.particle.ModParticles;

/**
* Defines the particles emitted by the {@link com.virus5600.defensive_measures.entity.turrets.CannonTurretEntity Cannon Turret}
* when it fires.
* The particle shots out in a cone shape and fades out over time. The direction is
* determined by the direction the turret is facing.
*/
@Environment(EnvType.CLIENT)
public class CannonFlash extends CustomEmitter {
/// CONSTRUCTORS ///
public CannonFlash(ClientWorld world, double x, double y, double z, double vx, double vy, double vz) {
super(world, ModParticles.SPARKS, x, y, z, 9);
this.velocityX = vx;
this.velocityY = vy;
this.velocityZ = vz;
this.setCustomEmitterCode();
}

public CannonFlash(ClientWorld world, Entity entity, double vx, double vy, double vz) {
super(world, entity, ModParticles.SPARKS, 9);
this.velocityX = vx;
this.velocityY = vy;
this.velocityZ = vz;
this.setCustomEmitterCode();
}

// CUSTOM EMITTER CODE //
private void setCustomEmitterCode() {
this.customEmitterCode = (particle) -> {
// Flash
if (this.age < 3) {
double variance = 0.75;
double minX = this.velocityX - variance,
maxX = this.velocityX + variance,
minY = this.velocityY - variance,
maxY = this.velocityY + variance,
minZ = this.velocityZ - variance,
maxZ = this.velocityZ + variance;

for (int i = 0; i < MathHelper.nextInt(this.random, 10, 25); i++) {
this.world.addParticle(
particle,
this.getPosSource().x,
this.getPosSource().y,
this.getPosSource().z,
MathHelper.nextDouble(this.random, minX, maxX),
MathHelper.nextDouble(this.random, minY, maxY),
MathHelper.nextDouble(this.random, minZ, maxZ)
);
}
}

// Smoke
if (this.age >= this.maxAge) {
for (int i = 0; i < MathHelper.nextInt(this.random, 1, 3); i++) {
this.world.addParticle(
ParticleTypes.CAMPFIRE_COSY_SMOKE,
this.getPosSource().x,
this.getPosSource().y,
this.getPosSource().z,
MathHelper.nextDouble(this.random, -0.01, 0.01),
MathHelper.nextDouble(this.random, 0.01, 0.025),
MathHelper.nextDouble(this.random, -0.01, 0.01)
);
}
}

return null;
};
}

/// FACTORY ///
@Environment(EnvType.CLIENT)
public static class Factory implements ParticleFactory<SimpleParticleType> {
public Particle createParticle(SimpleParticleType simpleParticleType, ClientWorld world, double x, double y, double z, double vx, double vy, double vz) {
return new CannonFlash(world, x, y, z, vx, vy, vz);
}
}
}
Loading

0 comments on commit fd0316c

Please sign in to comment.