Skip to content

Commit

Permalink
Add new feature (#4)
Browse files Browse the repository at this point in the history
Rideable Capybara (like a pig)
  • Loading branch information
ChokoJoestar committed Jun 29, 2023
1 parent a365ba4 commit 8749657
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 774 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ yarn_mappings=1.20+build.1
loader_version=0.14.21

# Mod Properties
mod_version=1.1
mod_version=1.2
maven_group=fr.chokojoestar.capymod
mod_id=capymod

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package fr.chokojoestar.capymod.entity.custom.Capybara;

import java.util.Set;

import org.jetbrains.annotations.Nullable;

import com.google.common.collect.Sets;

import fr.chokojoestar.capymod.entity.CapyEntities;
import fr.chokojoestar.capymod.item.CapyItems;
import java.util.Set;
import net.minecraft.entity.Dismounting;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.EntityStatuses;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.Saddleable;
import net.minecraft.entity.SaddledComponent;
import net.minecraft.entity.ai.goal.AnimalMateGoal;
import net.minecraft.entity.ai.goal.EscapeDangerGoal;
import net.minecraft.entity.ai.goal.FollowParentGoal;
Expand All @@ -17,19 +27,28 @@
import net.minecraft.entity.ai.goal.WanderAroundFarGoal;
import net.minecraft.entity.attribute.DefaultAttributeContainer;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.passive.PassiveEntity;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.recipe.Ingredient;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.EntityView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.core.animation.AnimatableManager.ControllerRegistrar;
Expand All @@ -40,14 +59,21 @@
import software.bernie.geckolib.core.object.PlayState;
import software.bernie.geckolib.util.GeckoLibUtil;

public class CapybaraEntity extends TameableEntity implements GeoEntity {
public class CapybaraEntity extends TameableEntity implements GeoEntity, Saddleable {

private static final TrackedData<Boolean> SADDLED = DataTracker.registerData(CapybaraEntity.class,
TrackedDataHandlerRegistry.BOOLEAN);
private static final TrackedData<Integer> BOOST_TIME = DataTracker.registerData(CapybaraEntity.class,
TrackedDataHandlerRegistry.INTEGER);
private static final Ingredient BREEDING_INGREDIENT = Ingredient.ofItems(Items.MELON_SLICE, Items.CARROT);
private static final Set<Item> SITS = Sets.newHashSet(Items.STICK, Items.BAMBOO, CapyItems.STAFF);
private AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private final SaddledComponent saddledComponent;

public CapybaraEntity(EntityType<? extends CapybaraEntity> entityType, World world) {
super((EntityType<? extends TameableEntity>) entityType, world);
this.saddledComponent = new SaddledComponent(this.dataTracker, BOOST_TIME, SADDLED);

public CapybaraEntity(EntityType<? extends TameableEntity> entityType, World world) {
super(entityType, world);
}

public static DefaultAttributeContainer.Builder createCapybaraAttributes() {
Expand Down Expand Up @@ -95,8 +121,17 @@ public ActionResult interactMob(PlayerEntity player, Hand hand) {
return ActionResult.SUCCESS;
}

/* SADDLE SYSTEM */
if (super.interactMob(player, hand).isAccepted() && this.isTamed()) {
if (itemStack.isOf(Items.SADDLE)) {
return itemStack.useOnEntity(player, this, hand);
}
return ActionResult.PASS;
}

/* RIDING SYSTEM */
if (!SITS.contains(item) && !isBreedingItem(itemStack)) {
if (!SITS.contains(item) && !isBreedingItem(itemStack) && !this.isSitting() && this.isSaddled()
&& !this.hasPassengers() && !player.shouldCancelInteraction()) {
if (!this.getWorld().isClient())
player.startRiding(this);
return ActionResult.SUCCESS;
Expand Down Expand Up @@ -164,4 +199,121 @@ public PassiveEntity createChild(ServerWorld world, PassiveEntity entity) {
public AnimatableInstanceCache getAnimatableInstanceCache() {
return cache;
}

@Override
public boolean canBeSaddled() {
return this.isAlive() && !this.isBaby();
}

@Override
public void saddle(SoundCategory sound) {
this.saddledComponent.setSaddled(true);
if (sound != null) {
this.getWorld().playSoundFromEntity(null, this, SoundEvents.ENTITY_PIG_SADDLE, sound, 0.5f, 1.0f);
}
}

@Override
public boolean isSaddled() {
return this.saddledComponent.isSaddled();
}

@Override
protected void dropInventory() {
super.dropInventory();
if (this.isSaddled()) {
this.dropItem(Items.SADDLE);
}
}

@Override
public Vec3d updatePassengerForDismount(LivingEntity passenger) {
Direction direction = this.getMovementDirection();
if (direction.getAxis() == Direction.Axis.Y) {
return super.updatePassengerForDismount(passenger);
}
int[][] is = Dismounting.getDismountOffsets(direction);
BlockPos blockPos = this.getBlockPos();
BlockPos.Mutable mutable = new BlockPos.Mutable();
for (EntityPose entityPose : passenger.getPoses()) {
Box box = passenger.getBoundingBox(entityPose);
for (int[] js : is) {
mutable.set(blockPos.getX() + js[0], blockPos.getY(), blockPos.getZ() + js[1]);
double d = this.getWorld().getDismountHeight(mutable);
if (!Dismounting.canDismountInBlock(d))
continue;
Vec3d vec3d = Vec3d.ofCenter(mutable, d);
if (!Dismounting.canPlaceEntityAt(this.getWorld(), passenger, box.offset(vec3d)))
continue;
passenger.setPose(entityPose);
return vec3d;
}
}
return super.updatePassengerForDismount(passenger);
}

protected void tickControlled(PlayerEntity controllingPlayer, Vec3d movementInput) {
super.tickControlled(controllingPlayer, movementInput);
this.setRotation(controllingPlayer.getYaw(), controllingPlayer.getPitch() * 0.5f);
this.bodyYaw = this.headYaw = this.getYaw();
this.prevYaw = this.headYaw;
this.saddledComponent.tickBoost();
}

@Override
protected Vec3d getControlledMovementInput(PlayerEntity controllingPlayer, Vec3d movementInput) {
return new Vec3d(0.0, 0.0, 1.0);
}

@Override
protected float getSaddledSpeed(PlayerEntity controllingPlayer) {
return (float) (this.getAttributeValue(EntityAttributes.GENERIC_MOVEMENT_SPEED) * 0.5
* (double) this.saddledComponent.getMovementSpeedMultiplier());
}

@Override
public Vec3d getLeashOffset() {
return new Vec3d(0.0, 0.6f * this.getStandingEyeHeight(), this.getWidth() * 0.4f);
}

@Override
public void writeCustomDataToNbt(NbtCompound nbt) {
super.writeCustomDataToNbt(nbt);
this.saddledComponent.writeNbt(nbt);
}

@Override
public void readCustomDataFromNbt(NbtCompound nbt) {
super.readCustomDataFromNbt(nbt);
this.saddledComponent.readNbt(nbt);
}

@Override
@Nullable
public LivingEntity getControllingPassenger() {
PlayerEntity playerEntity;
Entity entity;
if (this.isSaddled() && (entity = this.getFirstPassenger()) instanceof PlayerEntity
&& ((playerEntity = (PlayerEntity) entity).getMainHandStack().isOf(CapyItems.STAFF)
|| playerEntity.getOffHandStack().isOf(CapyItems.STAFF))) {
return playerEntity;
}
return null;
}

@Override
public void onTrackedDataSet(TrackedData<?> data) {
if (BOOST_TIME.equals(data) && this.getWorld().isClient) {
this.saddledComponent.boost();
}
super.onTrackedDataSet(data);
}

@Override
protected void initDataTracker() {
super.initDataTracker();
this.dataTracker.startTracking(SADDLED, false);
this.dataTracker.startTracking(BOOST_TIME, 0);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import fr.chokojoestar.capymod.Register;
import net.minecraft.util.Identifier;
import software.bernie.geckolib.core.animatable.model.CoreGeoBone;
import software.bernie.geckolib.core.animation.AnimationState;
import software.bernie.geckolib.model.GeoModel;

public class CapybaraModel extends GeoModel<CapybaraEntity> {
Expand All @@ -20,4 +22,11 @@ public Identifier getTextureResource(CapybaraEntity animatable) {
public Identifier getAnimationResource(CapybaraEntity animatable) {
return Register.registerLocation("animations", "capybara.animation.json");
}

@Override
public void setCustomAnimations(CapybaraEntity entity, long instanceId,
AnimationState<CapybaraEntity> animationState) {
CoreGeoBone saddle = this.getAnimationProcessor().getBone("saddle");
saddle.setHidden(!entity.isSaddled());
}
}
Loading

0 comments on commit 8749657

Please sign in to comment.