Skip to content

Commit

Permalink
Sleeping, spawn tweaks, & Seed Mix
Browse files Browse the repository at this point in the history
  • Loading branch information
crispytwig committed Oct 26, 2024
1 parent e7b881a commit c7b07c6
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 13 deletions.
79 changes: 70 additions & 9 deletions src/main/java/com/starfish_studios/hamsters/entity/HamsterNew.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.google.common.collect.Lists;
import com.starfish_studios.hamsters.entity.common.MMPathNavigatorGround;
import com.starfish_studios.hamsters.entity.common.SleepGoal;
import com.starfish_studios.hamsters.entity.common.SleepingAnimal;
import com.starfish_studios.hamsters.entity.common.SmartBodyHelper;
import com.starfish_studios.hamsters.registry.HamstersEntityType;
import com.starfish_studios.hamsters.registry.HamstersSoundEvents;
Expand Down Expand Up @@ -34,7 +36,11 @@
import net.minecraft.world.entity.ai.control.BodyRotationControl;
import net.minecraft.world.entity.ai.goal.*;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.ai.targeting.TargetingConditions;
import net.minecraft.world.entity.animal.Cat;
import net.minecraft.world.entity.animal.Fox;
import net.minecraft.world.entity.animal.ShoulderRidingEntity;
import net.minecraft.world.entity.animal.Wolf;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
Expand All @@ -43,6 +49,7 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -57,7 +64,7 @@

import java.util.*;

public class HamsterNew extends ShoulderRidingEntity implements GeoEntity {
public class HamsterNew extends ShoulderRidingEntity implements GeoEntity, SleepingAnimal {

// region Variables

Expand All @@ -78,13 +85,23 @@ public class HamsterNew extends ShoulderRidingEntity implements GeoEntity {
private static final EntityDataAccessor<Integer> CHEEK_LEVEL = SynchedEntityData.defineId(HamsterNew.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Integer> SQUISHED_TICKS = SynchedEntityData.defineId(HamsterNew.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Integer> BIRTH_COUNTDOWN = SynchedEntityData.defineId(HamsterNew.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> SLEEPING = SynchedEntityData.defineId(HamsterNew.class, EntityDataSerializers.BOOLEAN);

private static final Ingredient FOOD_ITEMS = Ingredient.of(HamstersTags.HAMSTER_FOOD);


// endregion

public HamsterNew(EntityType<? extends ShoulderRidingEntity> entityType, Level level) {
super(entityType, level);
this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F);
this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 1.0F);
this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, 1.0F);
this.setPathfindingMalus(BlockPathTypes.DAMAGE_CAUTIOUS, 1.0F);
this.setPathfindingMalus((BlockPathTypes.DANGER_POWDER_SNOW), 1.0F);
this.setPathfindingMalus((BlockPathTypes.DANGER_OTHER), 1.0F);
this.setPathfindingMalus((BlockPathTypes.DAMAGE_OTHER), 1.0F);
this.setPathfindingMalus((BlockPathTypes.WATER_BORDER), 1.0F);
}

public static boolean checkHamsterNewSpawnRules(EntityType<? extends TamableAnimal> entityType, LevelAccessor levelAccessor, MobSpawnType mobSpawnType, BlockPos blockPos, RandomSource randomSource) {
Expand Down Expand Up @@ -122,26 +139,30 @@ protected void registerGoals() {
this.goalSelector.addGoal(1, new PanicGoal(this, 1.3));
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
this.goalSelector.addGoal(3, new BreedGoal(this, 1.0));
this.goalSelector.addGoal(4, new HamsterSleepGoal(this));

this.goalSelector.addGoal(4, new HamsterTemptGoal(this, 1.0, FOOD_ITEMS, true));
this.goalSelector.addGoal(4, new HamsterAvoidPlayersGoal(this, 6.0f, 1.6D, 1.6D));
this.goalSelector.addGoal(5, new HamsterTemptGoal(this, 1.0, FOOD_ITEMS, true));
this.goalSelector.addGoal(5, new HamsterAvoidPlayersGoal(this, 6.0f, 1.6D, 1.6D));
// this.goalSelector.addGoal(5, new AvoidEntityGoal<>(this, Animal.class, 10.0F, 1.5D, 2.0D, livingEntity -> livingEntity.getType().is(HamstersTags.HAMSTER_PREDATORS)));
this.goalSelector.addGoal(5, new AvoidEntityGoal<>(this, Player.class, 10.0F, 1.5D, 2.0D) {
this.goalSelector.addGoal(6, new AvoidEntityGoal<>(this, Fox.class, 10.0F, 1.5D, 2.0D));
this.goalSelector.addGoal(6, new AvoidEntityGoal<>(this, Cat.class, 10.0F, 1.5D, 2.0D));
this.goalSelector.addGoal(6, new AvoidEntityGoal<>(this, Wolf.class, 10.0F, 1.5D, 2.0D));
this.goalSelector.addGoal(6, new AvoidEntityGoal<>(this, Player.class, 5.0F, 1.5D, 2.0D) {
@Override
public boolean canUse() {
return !HamsterNew.this.isTame() && super.canUse();
}
});
this.goalSelector.addGoal(6, new FollowParentGoal(this, 1.0));
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0));
this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 6.0F) {
this.goalSelector.addGoal(7, new FollowParentGoal(this, 1.0));
this.goalSelector.addGoal(8, new WaterAvoidingRandomStrollGoal(this, 1.0));
this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 6.0F) {
@Override
public void tick() {
if (this.mob instanceof HamsterNew hamsterNew && hamsterNew.getSquishedTicks() > 0) return;
super.tick();
}
});
this.goalSelector.addGoal(9, new HamsterLookAroundGoal(this));
this.goalSelector.addGoal(10, new HamsterLookAroundGoal(this));
// this.goalSelector.addGoal(10, new GetOnOwnersShoulderGoal(this));
}

Expand Down Expand Up @@ -439,6 +460,7 @@ protected void defineSynchedData() {
this.getEntityData().define(CHEEK_LEVEL, 0);
this.getEntityData().define(SQUISHED_TICKS, 0);
this.getEntityData().define(BIRTH_COUNTDOWN, 0);
this.getEntityData().define(SLEEPING, false);
}

@Override
Expand All @@ -450,6 +472,7 @@ public void readAdditionalSaveData(@NotNull CompoundTag compoundTag) {
this.setCheekLevel(compoundTag.getInt("CheekLevel"));
this.setSquishedTicks(compoundTag.getInt("SquishedTicks"));
this.setBirthCountdown(compoundTag.getInt("BirthCountdown"));
this.setSleeping(compoundTag.getBoolean("Sleeping"));
}

@Override
Expand All @@ -461,6 +484,7 @@ public void addAdditionalSaveData(@NotNull CompoundTag compoundTag) {
compoundTag.putInt("CheekLevel", this.getCheekLevel());
compoundTag.putInt("SquishedTicks", this.getSquishedTicks());
compoundTag.putInt("BirthCountdown", this.getBirthCountdown());
compoundTag.putBoolean("Sleeping", this.isSleeping());
}

public int getSquishedTicks() {
Expand Down Expand Up @@ -521,6 +545,37 @@ public void setCheekLevel(int cheekLevel) {
this.entityData.set(CHEEK_LEVEL, cheekLevel);
}


@Override
public boolean isSleeping() {
return this.entityData.get(SLEEPING);
}

@Override
public boolean canSleep() {
long dayTime = this.level().getDayTime();
List<Player> players = this.level().getNearbyPlayers(TargetingConditions.forNonCombat().range(4.0D), this, this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D));

if (dayTime > 12000 && dayTime < 23000) {
return false;
}

if (!players.isEmpty() && !players.get(0).isCreative() && !players.get(0).isCrouching()) {
return false;
}

else return !this.isInWater() // If the Hamster is not swimming
&& !this.isInLava() // If the Hamster is not in Lava
&& this.getSquishedTicks() <= 0 // If the Hamster is not squished
&& !level().isThundering(); // If there's not a thunderstorm

}

@Override
public void setSleeping(boolean sleeping) {
this.entityData.set(SLEEPING, sleeping);
}

public enum Marking {
BLANK (0, "blank"),
BANDED (1, "banded"),
Expand Down Expand Up @@ -620,7 +675,7 @@ protected <E extends HamsterNew> PlayState animController(final AnimationState<E
event.setControllerSpeed(1.1F);
event.setAnimation(PINKIE_WALK);
} else {
event.setControllerSpeed(1.1F);
event.setControllerSpeed(1.1F * event.getLimbSwingAmount());
event.setAnimation(WALK);
}
}
Expand Down Expand Up @@ -722,5 +777,11 @@ public void tick() {
}
}

public static class HamsterSleepGoal extends SleepGoal<HamsterNew> {
public HamsterSleepGoal(HamsterNew mob) {
super(mob);
}
}

// endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.starfish_studios.hamsters.entity.common;

import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.goal.Goal;

import java.util.EnumSet;

public class SleepGoal<E extends PathfinderMob & SleepingAnimal> extends Goal {
public final E mob;

public SleepGoal(E mob) {
this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK, Flag.JUMP));
this.mob = mob;
}

@Override
public void start() {
// After the goal is activated, makes the mob stop jumping, start sleeping, and stop moving.
mob.setJumping(false);
mob.setSleeping(true);
mob.getNavigation().stop();
mob.getMoveControl().setWantedPosition(mob.getX(), mob.getY(), mob.getZ(), 0.0D);
}

@Override
public boolean canUse() {
// If the mob is not moving and can sleep or is already sleeping, return true
if (mob.xxa == 0.0F && mob.yya == 0.0F && mob.zza == 0.0F) {
return mob.canSleep() || mob.isSleeping();
} else {
return false;
}
}

@Override
public boolean canContinueToUse() {
return mob.canSleep();
} // Allows the mob to continue sleeping if it can sleep (i.e., if it is not interrupted)

@Override
public void stop() {
mob.setSleeping(false);
} // Wakes up the mob when the goal ends
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.starfish_studios.hamsters.entity.common;

public interface SleepingAnimal {
boolean canSleep();
void setSleeping(boolean sleeping);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public HamsterItem(Properties properties) {
if (itemStack.hasTag() && itemStack.getTag() != null) hamster.load(itemStack.getTag());

hamster.moveTo(blockPos.getX() + 0.5, blockPos.getY(), blockPos.getZ() + 0.5, Objects.requireNonNull(useOnContext.getPlayer()).getYRot(), 0.0F);
hamster.setOwnerUUID(useOnContext.getPlayer().getUUID());

hamster.playSound(SoundEvents.CHICKEN_EGG);
useOnContext.getLevel().addFreshEntity(hamster);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class HamstersCreativeModeTab {
public static final CreativeModeTab ITEM_GROUP = register("item_group", FabricItemGroup.builder().icon(HAMSTER_SPAWN_EGG::getDefaultInstance).title(Component.translatable("itemGroup.hamsters.tab")).displayItems((featureFlagSet, output) -> {

// output.accept(TUNNEL);
output.accept(SEED_MIX);
output.accept(HAMSTER_WHEEL);

// RED, ORANGE, YELLOW, LIME, GREEN, CYAN, BLUE, LIGHT BLUE, PINK, MAGENTA, PURPLE, WHITE, LIGHT GRAY, GRAY, BLACK, BROWN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class HamstersEntityType {
public static final Supplier<EntityType<SeatEntity>> SEAT = registerEntityType("seat", (type, world) -> new SeatEntity(world), MobCategory.MISC, 0.0F, 0.0F);

static {
BiomeModifications.addSpawn(BiomeSelectors.tag(HamstersTags.HAS_HAMSTER), MobCategory.CREATURE, HamstersEntityType.HAMSTER_NEW, 30, 1, 1);
BiomeModifications.addSpawn(BiomeSelectors.tag(HamstersTags.HAS_HAMSTER), MobCategory.CREATURE, HamstersEntityType.HAMSTER_NEW, 10, 1, 2);
}

public static <T extends Entity> Supplier<EntityType<T>> registerEntityType(String id, EntityType.EntityFactory<T> factory, MobCategory category, float width, float height) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static Item hamsterBallItem() {
// public static final Item TUNNEL = register("tunnel", new BlockItem(HamstersBlocks.TUNNEL, new FabricItemSettings()));

public static final Item HAMSTER = register("hamster", new HamsterItem(new FabricItemSettings().stacksTo(1)));
public static final Item SEED_MIX = register("seed_mix", new Item(new FabricItemSettings()));

// RED, ORANGE, YELLOW, LIME, GREEN, CYAN, BLUE, LIGHT BLUE, PINK, MAGENTA, PURPLE, WHITE, LIGHT GRAY, GRAY, BLACK, BROWN

Expand Down Expand Up @@ -57,6 +58,7 @@ public static Item hamsterBallItem() {
// return registerItem(name, () -> new HamsterItem(entitySupplier, fluidSupplier.get(), soundSupplier, variantAmount, new Item.Properties().stacksTo(1)));
// }


@SuppressWarnings("unused")
public static <T extends Item> Supplier<T> registerItem(String id, Supplier<T> item) {
T registry = Registry.register(BuiltInRegistries.ITEM, Hamsters.id(id), item.get());
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/assets/hamsters/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

"item.hamsters.hamster_spawn_egg": "Hamster Spawn Egg",
"item.hamsters.hamster_new_spawn_egg": "Hamster Spawn Egg",
"item.hamsters.seed_mix": "Seed Mix",
"block.hamsters.tunnel": "Tunnel",
"block.hamsters.hamster_wheel": "Hamster Wheel",

Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/assets/hamsters/models/item/seed_mix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "hamsters:item/seed_mix"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"values": [
"minecraft:wheat_seeds",
"minecraft:beetroot_seeds",
"minecraft:pumpkin_seeds"
"hamsters:seed_mix"
]
}

0 comments on commit c7b07c6

Please sign in to comment.