Skip to content

Commit

Permalink
Update 20240719 - Implemented Basic CT Animations
Browse files Browse the repository at this point in the history
Implemented the Look-at-Target animation for the Cannon Turret.

[CHANGELOG]
🟢 Added setCustomAnimation method to Cannon Turret's model class.
🟢 Added custom eye height for Cannon Turret.
🟢 Added a trigger animation for when the Cannon Turret shoots (WIP).
🟢 Added a default or base tick method for Turret Entities.
🟢 Added isCollidable and isPushable methods for base Turret Entity class.
🟡 Updated getEntityItem return value.
🟡 Updated heal sound for Cannon Turret.
🟡 Moved the Projectile entity instance from outside the target conditional statement to inside to prevent it from running when not needed in Turret Entity class.
🔴 Removed the custom debug message when using the Turret Item.
  • Loading branch information
Virus5600 committed Jul 19, 2024
1 parent 063e77e commit fdf8b31
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.util.Identifier;
import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.constant.DataTickets;
import software.bernie.geckolib.model.GeoModel;
import software.bernie.geckolib.model.data.EntityModelData;

import java.util.Optional;

@Environment(EnvType.CLIENT)
public class CannonTurretModel extends GeoModel<CannonTurretEntity> {
Expand All @@ -28,5 +34,35 @@ public Identifier getAnimationResource(CannonTurretEntity animatable) {
return Identifier.of(DefensiveMeasures.MOD_ID, "animations/cannon_turret.animation.json");
}

// TODO: Fix the animation not working.
@Override
public void setCustomAnimations(CannonTurretEntity animatable, long instanceId, AnimationState<CannonTurretEntity> animationState) {
super.setCustomAnimations(animatable, instanceId, animationState);

Optional<GeoBone> base = this.getBone("base");
Optional<GeoBone> neck = this.getBone("stand");
Optional<GeoBone> head = this.getBone("head");

EntityModelData extraData = (EntityModelData) animationState.getExtraData().get(DataTickets.ENTITY_MODEL_DATA);

if (neck.isPresent()) {
float targetYRot = (extraData.netHeadYaw() * ((float) Math.PI / 180F));
neck.get().setRotY(targetYRot);

if (head.isPresent()) {
float targetXRot = (extraData.headPitch() * ((float) Math.PI / 180F));
head.get().setRotX(targetXRot);
}
}

if (base.isPresent()) {
base.get().setRotX(0);
base.get().setRotY(0);
base.get().setRotZ(0);
}
}

/*
* TODO: Consult Discord Servers for potential issue why this is thrown specifically when placed on Lightning Rods:
* [09:11:45] [Netty Server IO #1/ERROR] (Minecraft) Error sending packet clientbound/minecraft:set_entity_data
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ModEntities {
Builder
.create(CannonTurretEntity::new, SpawnGroup.MISC)
.dimensions(1F, 1F)
.eyeHeight(0.51F)
.build()
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.MathHelper;
Expand All @@ -44,7 +43,6 @@
import com.virus5600.defensive_measures.entity.TurretMaterial;
import com.virus5600.defensive_measures.entity.ai.goal.TargetOtherTeamGoal;

import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager.ControllerRegistrar;
Expand Down Expand Up @@ -85,7 +83,7 @@ public class CannonTurretEntity extends TurretEntity implements GeoEntity, Range
public CannonTurretEntity(EntityType<? extends MobEntity> entityType, World world) {
super(entityType, world, TurretMaterial.METAL, ArrowEntity.class);
this.setShootSound(ModSoundEvents.TURRET_CANNON_SHOOT);
this.setHealSound(ModSoundEvents.TURRET_REMOVED_METAL);
this.setHealSound(ModSoundEvents.TURRET_REPAIR_METAL);
this.addHealables(healables);
this.addEffectSource(effectSource);
}
Expand Down Expand Up @@ -150,6 +148,7 @@ public void shootAt(LivingEntity target, float pullProgress) {

this.playSound(this.getShootSound(), 1.0f, 1.0f / (this.getRandom().nextFloat() * 0.4f + 0.8f));
this.getWorld().spawnEntity(projectile);
this.triggerAnim("Firing Sequence", "Shoot");
} catch (IllegalArgumentException | SecurityException e) {
e.printStackTrace();

Expand Down Expand Up @@ -210,7 +209,7 @@ protected void setFuseLit(boolean lit) {

@Override
public ItemStack getEntityItem() {
return new ItemStack(Items.IRON_BLOCK);
return new ItemStack(ModItems.CANNON_TURRET);
}

///////////////////////////
Expand Down Expand Up @@ -240,6 +239,7 @@ private <E extends CannonTurretEntity>PlayState idleController(final AnimationSt
);
}

// TODO: Fix particle key-framing
private <E extends CannonTurretEntity>PlayState firingSequenceController(final AnimationState<E> event) {
Vec3d fusePos = this.getRelativePos(0, 0, 0),
barrelPos = this.getRelativePos(0, 0, 0);
Expand Down Expand Up @@ -292,6 +292,7 @@ public void registerControllers(final ControllerRegistrar controllers) {
new AnimationController<>(this, "Death", this::deathController),
new AnimationController<>(this, "Idle", this::idleController),
new AnimationController<>(this, "Firing Sequence", this::firingSequenceController)
.triggerableAnim("Shoot", RawAnimation.begin().thenPlay("animation.cannon_turret.shoot"))
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.virus5600.defensive_measures.item.ModItems;
import com.virus5600.defensive_measures.item.turrets.TurretItem;

import net.minecraft.world.event.GameEvent;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -410,6 +411,8 @@ public boolean startRiding(Entity entity, boolean force) {
if (this.getWorld().isClient()) {
this.prevAttachedBlock = null;
}

this.setAttachedFace(Direction.DOWN);
return super.startRiding(entity, force);
}

Expand All @@ -420,6 +423,7 @@ public void stopRiding() {
if (this.getWorld().isClient) {
this.prevAttachedBlock = this.getBlockPos();
}

this.prevBodyYaw = 0.0f;
this.bodyYaw = 0.0f;
}
Expand All @@ -435,6 +439,45 @@ public ItemStack getPickBlockStack() {
return new ItemStack(turretItem);
}

@Override
public void tick() {
super.tick();

if (!this.getWorld().isClient()) {
this.setHasTarget(this.getTarget() != null);
} else {
// SNAPPING THE TURRET BACK IN PLACE
if (this.getVelocity().x == 0 && this.getVelocity().z == 0 && !this.hasVehicle()) {
Vec3d newPos = new Vec3d(
(double) MathHelper.floor(this.getX()) + 0.5,
this.getY(),
(double) MathHelper.floor(this.getZ()) + 0.5
);

this.tryAttachOrFall();
super.setPosition(newPos);
this.getWorld().emitGameEvent(this, GameEvent.TELEPORT, newPos);

if (this.getVelocity() == Vec3d.ZERO && this.getWorld().isClient() && !this.hasVehicle()) {
this.lastRenderX = this.getX();
this.lastRenderY = this.getY();
this.lastRenderZ = this.getZ();
}
}
}
}

@Override
public void tickMovement() {
super.tickMovement();

if (!(this.getWorld().isClient()
|| this.hasVehicle()
|| this.canStay(this.getBlockPos(), this.getAttachedFace()))) {
this.tryAttachOrFall();
}
}

//////////////////////////////////////
// QUESTION METHODS (True or False) //
//////////////////////////////////////
Expand Down Expand Up @@ -518,6 +561,16 @@ public boolean canBeLeashed() {
return false;
}

@Override
public boolean isCollidable() {
return this.isAlive();
}

@Override
public boolean isPushable() {
return false;
}

/////////////////////////
// GETTERS AND SETTERS //
/////////////////////////
Expand Down Expand Up @@ -934,11 +987,11 @@ public void shootAt(LivingEntity target, float pullProgress) {
try {
this.setHasTarget(target != null);

ProjectileEntity projectile = (ProjectileEntity) this.projectile
.getConstructor(World.class, LivingEntity.class)
.newInstance(this.getWorld(), this);

if (target != null) {
ProjectileEntity projectile = (ProjectileEntity) this.projectile
.getConstructor(World.class, LivingEntity.class)
.newInstance(this.getWorld(), this);

double[] velocity = new double[] {
target.getX() - this.getX(),
target.getBodyY((double) 1 / 2) - projectile.getX(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ public ActionResult useOnBlock(ItemUsageContext context) {
NbtComponent nbtComponent = itemStack.get(DataComponentTypes.CUSTOM_DATA);
NbtCompound nbt = nbtComponent != null ? nbtComponent.copyNbt() : NbtComponent.DEFAULT.copyNbt();
EntityType<?> entityType2 = this.getEntityType(nbt);
context.getPlayer().sendMessage(Text.of("Spawning " + entityType2.getName().getString()), true);
Entity entity = entityType2.spawnFromItemStack(
(ServerWorld) world,
itemStack,
Expand Down

0 comments on commit fdf8b31

Please sign in to comment.