Skip to content

Commit

Permalink
Update 20241217 - Standard Item Regis Fix
Browse files Browse the repository at this point in the history
Fixed the item registration for standard items such as the cannon base and turret remover.

Furthermore, fixed the relative position getter from the Turret Entity base class and began updating the particle issues.

[CHANGELOG]
🟢 Added a TODO to the Cannon Flash particle.
🟢 Added the relative position of the barrel and fuse for the Cannon Turret entity.
🟡 Updated some maps and lists in the Cannon Turret entity to a simplified declaration.
🟡 Refactored the Cannon Turret entity class to adapt to the changes made after the removal of some tracked data.
🟡 Fixed the standard item registration.
🟡 Updated tooltip for the Cannon Turret item to just loop instead after changes made to the tooltip line.
🟡 Separated the tooltip line for the Cannon Turret item into three lines to prevent an unknown symbol from appearing in-game.
🟡 Updated the overloaded "registerItem" method to now required a a factory instead of just the string.
🔴 Removed some tracked data in the base Turret Entity class.
  • Loading branch information
Virus5600 committed Dec 17, 2024
1 parent 05c2911 commit ca40641
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 114 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.virus5600.defensive_measures.particle.custom;

import com.virus5600.defensive_measures.particle.ModParticles;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.*;
Expand All @@ -20,7 +21,7 @@ public class CannonFlash extends SpriteBillboardParticle {
private final Vec3d source;

/// CONSTRUCTORS ///
protected CannonFlash(ClientWorld level, double x, double y, double z, SpriteProvider spriteSet, double xd, double yd, double zd) {
public CannonFlash(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 @@ -36,8 +37,20 @@ protected CannonFlash(ClientWorld level, double x, double y, double z, SpritePro
this.source = new Vec3d(x, y, z);

this.red = 1f;
this.green= 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 @@ -68,7 +81,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 Down Expand Up @@ -116,6 +128,5 @@ 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);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ protected void initGoals() {
this.goalSelector.add(8, new LookAroundGoal(this));

// Targets
this.targetSelector.add(1, new ActiveTargetGoal<MobEntity>(this, MobEntity.class, 10, true, false, (entity, serverWorld) -> entity instanceof Monster));
this.targetSelector.add(1, new ActiveTargetGoal<>(this, MobEntity.class, 10, true, false, (entity, _) -> entity instanceof Monster));
this.targetSelector.add(3, new TargetOtherTeamGoal(this));
}

Expand All @@ -116,22 +116,14 @@ public static DefaultAttributeContainer.Builder setAttributes() {

@Override
public void shootAt(LivingEntity target, float pullProgress) {
if (target == null) {
if (this.isShooting())
this.setShooting(false);
return;
}

this.setShooting(true);

try {
double vx = (target.getX() - this.getX()) * 1.0625;
double vy = target.getBodyY((double) 2 / 3) - this.getY() + 0.25;
double vz = (target.getZ() - this.getZ()) * 1.0625;
double variance = Math.sqrt(vx * vx + vz * vz);
float divergence = this.getWorld().getDifficulty().getId() * 2;
// ProjectileEntity projectile = (ProjectileEntity) new CannonballEntity(ModEntities.CANNONBALL, this, vx, vy, vz, this.getWorld());
ProjectileEntity projectile = (ProjectileEntity) new ArrowEntity(EntityType.ARROW, this.getWorld());
// ProjectileEntity projectile = new CannonballEntity(ModEntities.CANNONBALL, this, vx, vy, vz, this.getWorld());
ProjectileEntity projectile = new ArrowEntity(EntityType.ARROW, this.getWorld());

projectile.setVelocity(vx, vy + variance * 0.1f, vz, 1.5f, divergence);
projectile.setPos(this.getX(), this.getY() + 0.5, this.getZ());
Expand Down Expand Up @@ -162,20 +154,12 @@ public void tick() {
this.setYaw(0);
this.setBodyYaw(0);

if (this.isShooting() && this.hasTarget()) {
if (this.attackGoal != null) {
if (this.attackGoal.shouldContinue()) {
if (--this.attCooldown <= 0) {
this.setShootingFXDone(false);
this.setFuseLit(false);
this.attCooldown = totalAttCooldown;
}
else {
this.setShootingFXDone(true);
this.setFuseLit(true);
this.triggerAnim("Firing Sequence", "Charge");
}
}
if (this.getTarget() != null && this.getWorld().isClient) {
if (--this.attCooldown <= 0) {
this.attCooldown = totalAttCooldown;
}
else {
this.triggerAnim("Firing Sequence", "Charge");
}
}
}
Expand All @@ -200,13 +184,6 @@ protected SoundEvent getDeathSound() {
return ModSoundEvents.TURRET_CANNON_DESTROYED;
}

protected boolean isFuseLit() {
return this.dataTracker.get(FUSE_LIT);
}
protected void setFuseLit(boolean lit) {
this.dataTracker.set(FUSE_LIT, lit);
}

@Override
public ItemStack getEntityItem() {
return new ItemStack(ModItems.CANNON_TURRET);
Expand Down Expand Up @@ -241,8 +218,8 @@ private <E extends CannonTurretEntity>PlayState idleController(final AnimationSt

// TODO: Fix particle spawning
private <E extends CannonTurretEntity>PlayState firingSequenceController(final AnimationState<E> event) {
Vec3d fusePos = this.getRelativePos(0, 1, 0),
barrelPos = this.getRelativePos(0, 0, 0);
Vec3d fusePos = this.getRelativePos(0, 1, -0.5),
barrelPos = this.getRelativePos(0, 0.25, 1);

// Shooting sequence
event.getController()
Expand All @@ -251,10 +228,7 @@ private <E extends CannonTurretEntity>PlayState firingSequenceController(final A
effectName = state.getKeyframeData().getEffect(),
currentState = "fuse";

if (this.hasTarget() && this.isShooting()) {
if (this.isFuseLit()) currentState = "fuse";
else currentState = "shoot";
}
if (locator.equals("barrel")) currentState = "shoot";

System.out.println("Locator: " + locator + " | Effect: " + effectName + " | State: " + currentState);

Expand Down Expand Up @@ -319,7 +293,7 @@ public AnimatableInstanceCache getAnimatableInstanceCache() {
static {
FUSE_LIT = DataTracker.registerData(CannonTurretEntity.class, TrackedDataHandlerRegistry.BOOLEAN);

healables = new HashMap<Item, Float>() {
healables = new HashMap<>() {
{
for (Item item : TurretEntity.PLANKS)
put(item, 1.0f);
Expand All @@ -329,9 +303,9 @@ public AnimatableInstanceCache getAnimatableInstanceCache() {
}
};

effectSource = new HashMap<Item, List<Object[]>>() {
effectSource = new HashMap<>() {
{
put(Items.IRON_BLOCK, new ArrayList<Object[]>() {
put(Items.IRON_BLOCK, new ArrayList<>() {
{
add(new Object[] {StatusEffects.ABSORPTION, 60, 2});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
* @see RangedAttackMob
*
*/
public class TurretEntity extends MobEntity implements Itemable, RangedAttackMob{
public class TurretEntity extends MobEntity implements Itemable, RangedAttackMob {
/**
* Tracks the level (stage) of this turret entity.
*/
Expand All @@ -71,18 +71,6 @@ public class TurretEntity extends MobEntity implements Itemable, RangedAttackMob
* Tracks whether this entity is spawned from an item.
*/
private static final TrackedData<Byte> FROM_ITEM;
/**
* Tracks whether this entity is shooting.
*/
private static final TrackedData<Boolean> SHOOTING;
/**
* Tracks whether the shooting effect is done.
*/
private static final TrackedData<Boolean> SHOOTING_FX_DONE;
/**
* Tracks whether this turret has a target.
*/
private static final TrackedData<Boolean> HAS_TARGET;

/**
* Tracks the direction where this turret is attached to.
Expand Down Expand Up @@ -278,9 +266,6 @@ protected void initDataTracker(DataTracker.Builder builder) {
// Entity related tracking
builder.add(LEVEL, this.level)
.add(FROM_ITEM, (byte) 1)
.add(SHOOTING, false)
.add(SHOOTING_FX_DONE, true)
.add(HAS_TARGET, false)

// Position related tracking
.add(ATTACHED_FACE, Direction.DOWN)
Expand Down Expand Up @@ -467,9 +452,7 @@ public ItemStack getPickBlockStack() {
public void tick() {
super.tick();

if (!this.getWorld().isClient()) {
this.setHasTarget(this.getTarget() != null);
} else {
if (this.getWorld().isClient()) {
// SNAPPING THE TURRET BACK IN PLACE
if (this.getVelocity().x == 0 && this.getVelocity().z == 0 && !this.hasVehicle()) {
Vec3d newPos = new Vec3d(
Expand Down Expand Up @@ -645,8 +628,11 @@ protected Direction getAttachedFace() {
* @return Vec3d the relative position of this point, assuming that the origin is at <b>[0, 0, 0]</b>
*/
public Vec3d getRelativePos(double xOffset, double yOffset, double zOffset) {
return this.getRotationVecClient().add(this.getPos())
.add(xOffset, yOffset, zOffset);
Vec3d rotated = new Vec3d(xOffset, yOffset, zOffset)
.rotateX(this.getPitch())
.rotateY(this.getYaw());

return rotated.add(this.getPos());
}

@Override
Expand Down Expand Up @@ -906,30 +892,6 @@ public List<Object[]> getMobEffect(Item item) {
return this.isEffectSource(item) ? this.effectSource.get(item) : List.<Object[]>of();
}

public boolean isShooting() {
return this.dataTracker.get(SHOOTING);
}

public void setShooting(boolean shooting) {
this.dataTracker.set(SHOOTING, shooting);
}

public boolean getShootingFXDone() {
return this.dataTracker.get(SHOOTING_FX_DONE);
}

public void setShootingFXDone(boolean status) {
this.dataTracker.set(SHOOTING_FX_DONE, status);
}

public boolean hasTarget() {
return this.dataTracker.get(HAS_TARGET);
}

public void setHasTarget(boolean hasTarget) {
this.dataTracker.set(HAS_TARGET, hasTarget);
}

public void setPos(TrackedData<Float> axis, double value) {
this.dataTracker.set(axis, (float) value);
}
Expand Down Expand Up @@ -1000,13 +962,9 @@ public SoundEvent getEntityRemoveSound() {

@Override
public void shootAt(LivingEntity target, float pullProgress) {
if (!this.isShooting())
this.setShooting(target != null);

try {
String targetName = target != null ? target.getName().getString() : "(nothing)";
System.out.println("Shooting at " + targetName + " with a pull progress of " + pullProgress);
this.setHasTarget(target != null);

if (target != null) {
ProjectileEntity projectile = (ProjectileEntity) this.projectile
Expand Down Expand Up @@ -1079,9 +1037,6 @@ protected void clampHeadYaw() {
static {
LEVEL = DataTracker.registerData(TurretEntity.class, TrackedDataHandlerRegistry.INTEGER);
FROM_ITEM = DataTracker.registerData(TurretEntity.class, TrackedDataHandlerRegistry.BYTE);
SHOOTING = DataTracker.registerData(TurretEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
SHOOTING_FX_DONE = DataTracker.registerData(TurretEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
HAS_TARGET = DataTracker.registerData(TurretEntity.class, TrackedDataHandlerRegistry.BOOLEAN);

ATTACHED_FACE = DataTracker.registerData(TurretEntity.class, TrackedDataHandlerRegistry.FACING);
X = DataTracker.registerData(TurretEntity.class, TrackedDataHandlerRegistry.FLOAT);
Expand Down
45 changes: 36 additions & 9 deletions src/main/java/com/virus5600/defensive_measures/item/ModItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

import java.util.Arrays;

/**
* A class that contains all the items in the mod.
* This class is used to register all the items in the mod, from turrets, to equipments, to traps, block items,
* ingredients, etc. This class is also used to register the items to their respective item groups to categorize
* them in the creative inventory.
*/
public class ModItems {
public final static Item[] DM_ITEMS;
public final static Item[] DM_EQUIPMENTS;
Expand All @@ -31,10 +37,10 @@ public class ModItems {

// CANNON
public final static Item CANNON_TURRET = registerItem("cannon_turret", ModEntities.CANNON_TURRET, CannonTurretItem::new);
public final static Item CANNON_BASE = registerItem("cannon_base");
public final static Item CANNON_HEAD = registerItem("cannon_head");
public final static Item CANNON_STAND = registerItem("cannon_stand");
public final static Item UNFINISHED_CANNON_HEAD = registerItem("unfinished_cannon_head");
public final static Item CANNON_BASE = registerItem("cannon_base", CannonBaseItem::new);
public final static Item CANNON_HEAD = registerItem("cannon_head", CannonHeadItem::new);
public final static Item CANNON_STAND = registerItem("cannon_stand", CannonStandItem::new);
public final static Item UNFINISHED_CANNON_HEAD = registerItem("unfinished_cannon_head", UnfinishedCannonHeadItem::new);

// BALLISTA
// public final static Item BALLISTA = new BallistaTurretItem(ModEntities.BALLISTA, SETTING_DMT);
Expand All @@ -56,22 +62,39 @@ public class ModItems {
////////////////

// TURRET REMOVER
public final static Item TURRET_REMOVER = registerItem("turret_remover");
public final static Item TURRET_REMOVER = registerItem("turret_remover", TurretRemoverItem::new);

//////////////////////////////
// REGISTRY RELATED METHODS //
//////////////////////////////

private static Item registerItem(String name, EntityType<? extends MobEntity> entityType, ItemFactory<? extends TurretItem> factory) {
/**
* Registers a turret item which spawns a turret entity.
* @param name The name of the item. (e.g. "cannon_turret")
* @param entityType The entity type of the turret. (e.g. {@code ModEntities.CANNON_TURRET})
* @param factory The factory method to create the turret item. Usually a lambda expression like {@code CannonTurretItem::new}.
* @return The registered item.
*/
private static Item registerItem(String name, EntityType<? extends MobEntity> entityType, TurretItemFactory<? extends TurretItem> factory) {
return RegistryUtil.registerItem(
name,
(settings) -> factory.create(entityType, settings),
new Settings()
);
}

private static Item registerItem(String name) {
return RegistryUtil.registerItem(name);
/**
* Registers a normal item such as ingredients, tools, etc.
* @param name The name of the item. (e.g. "cannon_base")
* @param factory The factory method to create the item. Usually a lambda expression like {@code CannonBaseItem::new}.
* @return The registered item.
*/
private static Item registerItem(String name, ItemFactory<? extends Item> factory) {
return RegistryUtil.registerItem(
name,
factory::create,
new Settings()
);
}

public static void registerModItems() {
Expand Down Expand Up @@ -108,10 +131,14 @@ public static void registerModItems() {
}));
}

private interface ItemFactory<T extends Item> {
private interface TurretItemFactory<T extends TurretItem> {
T create(EntityType<? extends MobEntity> entityType, Settings settings);
}

private interface ItemFactory<T extends Item> {
T create(Settings settings);
}

static {
DM_ITEMS = new Item[]{
CANNON_BASE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ public CannonTurretItem(EntityType<? extends MobEntity> type, Settings settings)

@Override
public void appendTooltip(ItemStack stack, Item.TooltipContext context, List<Text> tooltip, TooltipType type) {
tooltip.add(
Text.translatable("itemTooltip.dm.cannon_turret")
.formatted(Formatting.DARK_AQUA)
);
for (int i = 1; i <= 3; i++) {
tooltip.add(
Text.translatable("itemTooltip.dm.cannon_turret.line" + i)
.formatted(Formatting.DARK_AQUA)
);
}
}
}
Loading

0 comments on commit ca40641

Please sign in to comment.