diff --git a/common/src/main/java/com/faboslav/friendsandfoes/entity/RascalEntity.java b/common/src/main/java/com/faboslav/friendsandfoes/entity/RascalEntity.java index 861bf04e4..d49ef443c 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/entity/RascalEntity.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/entity/RascalEntity.java @@ -7,66 +7,66 @@ import com.faboslav.friendsandfoes.entity.ai.brain.RascalBrain; import com.faboslav.friendsandfoes.entity.animation.AnimatedEntity; import com.faboslav.friendsandfoes.init.FriendsAndFoesSoundEvents; -import com.faboslav.friendsandfoes.mixin.ChunkRegionAccessor; -import com.faboslav.friendsandfoes.mixin.ServerWorldAccessor; import com.faboslav.friendsandfoes.util.RandomGenerator; import com.mojang.serialization.Dynamic; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.ai.brain.Brain; +import net.minecraft.entity.ai.brain.MemoryModuleType; +import net.minecraft.entity.ai.pathing.PathNodeType; import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.damage.DamageSource; -import net.minecraft.entity.mob.IllusionerEntity; +import net.minecraft.entity.data.DataTracker; +import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.passive.IronGolemEntity; import net.minecraft.entity.passive.PassiveEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleTypes; +import net.minecraft.registry.tag.StructureTags; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvent; -import net.minecraft.tag.StructureTags; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.random.Random; -import net.minecraft.util.registry.Registry; import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; import net.minecraft.world.gen.StructureAccessor; -import net.minecraft.world.gen.structure.Structure; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; public final class RascalEntity extends PassiveEntity implements AnimatedEntity { private AnimationContextTracker animationContextTracker; + private static final TrackedData CAUGHT_COUNT; + public RascalEntity(EntityType entityType, World world) { super(entityType, world); + this.setPathfindingPenalty(PathNodeType.RAIL, 0.0F); + this.setPathfindingPenalty(PathNodeType.UNPASSABLE_RAIL, 0.0F); + this.setPathfindingPenalty(PathNodeType.DAMAGE_OTHER, -1.0F); } public static boolean canSpawn( - EntityType rascalEntityType, - ServerWorldAccess serverWorldAccess, - SpawnReason spawnReason, - BlockPos blockPos, - Random random + EntityType rascalEntityType, + ServerWorldAccess serverWorldAccess, + SpawnReason spawnReason, + BlockPos blockPos, + Random random ) { - if(spawnReason == SpawnReason.NATURAL) { + if (spawnReason == SpawnReason.NATURAL) { StructureAccessor structureAccessor = serverWorldAccess.toServerWorld().getStructureAccessor(); if ( - structureAccessor.getStructureContaining( - blockPos, - StructureTags.MINESHAFT - ).hasChildren() - && blockPos.getY() < 63 - && serverWorldAccess.isSkyVisible(blockPos) == false + structureAccessor.getStructureContaining( + blockPos, + StructureTags.MINESHAFT + ).hasChildren() + && blockPos.getY() < 63 + && serverWorldAccess.isSkyVisible(blockPos) == false ) { return true; } @@ -88,6 +88,12 @@ public AnimationContextTracker getAnimationContextTracker() { return this.animationContextTracker; } + @Override + protected void initDataTracker() { + super.initDataTracker(); + this.dataTracker.startTracking(CAUGHT_COUNT, 0); + } + @Nullable @Override public PassiveEntity createChild(ServerWorld world, PassiveEntity entity) { @@ -120,7 +126,7 @@ protected void mobTick() { public static DefaultAttributeContainer.Builder createAttributes() { return MobEntity.createMobAttributes() .add(EntityAttributes.GENERIC_MAX_HEALTH, 10.0D) - .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.8D) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.55D) .add(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, 1.0D); } @@ -153,12 +159,12 @@ public boolean damage( return false; } - public SoundEvent getApproveSound() { - return FriendsAndFoesSoundEvents.ENTITY_RASCAL_APPROVE.get(); + public SoundEvent getNodSound() { + return FriendsAndFoesSoundEvents.ENTITY_RASCAL_NOD.get(); } - public void playApproveSound() { - this.playSound(this.getApproveSound(), 1.0F, RandomGenerator.generateFloat(1.1F, 1.3F)); + public void playNodSound() { + this.playSound(this.getNodSound(), 1.0F, RandomGenerator.generateFloat(1.15F, 1.3F)); } public SoundEvent getRewardSound() { @@ -166,7 +172,7 @@ public SoundEvent getRewardSound() { } public void playRewardSound() { - this.playSound(this.getRewardSound(), 1.0F, RandomGenerator.generateFloat(1.1F, 1.3F)); + this.playSound(this.getRewardSound(), 1.0F, RandomGenerator.generateFloat(1.15F, 1.3F)); } public SoundEvent getBadRewardSound() { @@ -174,7 +180,7 @@ public SoundEvent getBadRewardSound() { } public void playBadRewardSound() { - this.playSound(this.getBadRewardSound(), 1.0F, RandomGenerator.generateFloat(1.1F, 1.3F)); + this.playSound(this.getBadRewardSound(), 1.0F, RandomGenerator.generateFloat(1.15F, 1.3F)); } @Override @@ -184,8 +190,12 @@ protected SoundEvent getAmbientSound() { @Override public void playAmbientSound() { + if (this.isHidden()) { + return; + } + SoundEvent soundEvent = this.getAmbientSound(); - this.playSound(soundEvent, 1.0F, RandomGenerator.generateFloat(1.1F, 1.3F)); + this.playSound(soundEvent, 1.0F, RandomGenerator.generateFloat(1.15F, 1.3F)); } @Override @@ -196,16 +206,48 @@ protected SoundEvent getHurtSound(DamageSource source) { @Override protected void playHurtSound(DamageSource source) { this.ambientSoundChance = -this.getMinAmbientSoundDelay(); - this.playSound(this.getHurtSound(source), 1.0F, RandomGenerator.generateFloat(1.1F, 1.3F)); + this.playSound(this.getHurtSound(source), 1.0F, RandomGenerator.generateFloat(1.15F, 1.3F)); + } + + @Override + protected void playStepSound( + BlockPos pos, + BlockState state + ) { + if ( + this.isHidden() + || state.isLiquid() + ) { + return; + } + + super.playStepSound(pos, state); + } + + public boolean isHidden() { + return this.getBrain().getOptionalRegisteredMemory(MemoryModuleType.AVOID_TARGET).orElse(null) instanceof PlayerEntity; + } + + public int getCaughtCount() { + return this.dataTracker.get(CAUGHT_COUNT); + } + + public void addToCaughtCount() { + this.dataTracker.set(CAUGHT_COUNT, this.getCaughtCount() + 1); + } + + public boolean shouldGiveReward() { + return this.getCaughtCount() >= 3; } public void spawnCloudParticles() { - this.spawnParticles(ParticleTypes.CLOUD, 16); + this.spawnParticles(ParticleTypes.CLOUD, 16, 0.1D); } public void spawnParticles( ParticleEffect particleEffect, - int amount + int amount, + double speed ) { World world = this.getWorld(); @@ -223,9 +265,13 @@ public void spawnParticles( this.getRandom().nextGaussian() * 0.02D, this.getRandom().nextGaussian() * 0.02D, this.getRandom().nextGaussian() * 0.02D, - 1.0D + speed ); } } + + static { + CAUGHT_COUNT = DataTracker.registerData(RascalEntity.class, TrackedDataHandlerRegistry.INTEGER); + } } diff --git a/common/src/main/java/com/faboslav/friendsandfoes/entity/WildfireShieldDebrisEntity.java b/common/src/main/java/com/faboslav/friendsandfoes/entity/WildfireShieldDebrisEntity.java index b500a3bcb..c090cfa92 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/entity/WildfireShieldDebrisEntity.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/entity/WildfireShieldDebrisEntity.java @@ -100,7 +100,7 @@ private SoundEvent getImpactSound() { private void playImpactSound() { SoundEvent soundEvent = this.getImpactSound(); - this.playSound(soundEvent, 1.0F, 0.95F + RandomGenerator.generateFloat(0.95F, 1.05F)); + this.playSound(soundEvent, 1.0F, 0.95F + RandomGenerator.generateFloat(0.95F, 1.05F)); } } diff --git a/common/src/main/java/com/faboslav/friendsandfoes/entity/ai/brain/RascalBrain.java b/common/src/main/java/com/faboslav/friendsandfoes/entity/ai/brain/RascalBrain.java index 346e96cf1..99de8f696 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/entity/ai/brain/RascalBrain.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/entity/ai/brain/RascalBrain.java @@ -1,19 +1,23 @@ package com.faboslav.friendsandfoes.entity.ai.brain; import com.faboslav.friendsandfoes.entity.RascalEntity; -import com.faboslav.friendsandfoes.entity.WildfireEntity; +import com.faboslav.friendsandfoes.entity.ai.brain.task.rascal.RascalWaitForPlayerTask; import com.faboslav.friendsandfoes.init.FriendsAndFoesActivities; import com.faboslav.friendsandfoes.init.FriendsAndFoesMemoryModuleTypes; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Dynamic; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.brain.Activity; import net.minecraft.entity.ai.brain.Brain; import net.minecraft.entity.ai.brain.MemoryModuleType; import net.minecraft.entity.ai.brain.sensor.Sensor; import net.minecraft.entity.ai.brain.sensor.SensorType; import net.minecraft.entity.ai.brain.task.*; +import net.minecraft.util.TimeHelper; +import net.minecraft.util.math.intprovider.UniformIntProvider; import java.util.List; @@ -22,6 +26,8 @@ public final class RascalBrain { public static final List> MEMORY_MODULES; public static final List>> SENSORS; + private static final UniformIntProvider NOD_COOLDOWN_PROVIDER; + private static final UniformIntProvider AVOID_MEMORY_DURATION; public RascalBrain() { } @@ -31,8 +37,9 @@ public static Brain create(Dynamic dynamic) { Brain brain = profile.deserialize(dynamic); addCoreActivities(brain); - addHomeActivities(brain); addIdleActivities(brain); + addWaitActivities(brain); + addAvoidActivities(brain); brain.setCoreActivities(ImmutableSet.of(Activity.CORE)); brain.setDefaultActivity(Activity.IDLE); @@ -45,29 +52,53 @@ private static void addCoreActivities(Brain brain) { brain.setTaskList(Activity.CORE, 0, ImmutableList.of( + new StayAboveWaterTask(0.8F), new LookAroundTask(45, 90), - new WanderAroundTask() + new WanderAroundTask(), + new TemptationCooldownTask(FriendsAndFoesMemoryModuleTypes.RASCAL_NOD_COOLDOWN.get()) ) ); } - private static void addHomeActivities(Brain brain) { - - } - private static void addIdleActivities(Brain brain) { brain.setTaskList( Activity.IDLE, ImmutableList.of( + Pair.of(0, FindInteractionTargetTask.create(EntityType.PLAYER, 8)), Pair.of(0, makeRandomWanderTask()) ) ); } + private static void addWaitActivities( + Brain brain + ) { + brain.setTaskList( + FriendsAndFoesActivities.RASCAL_WAIT.get(), + 10, + ImmutableList.of( + new RascalWaitForPlayerTask() + ), MemoryModuleType.INTERACTION_TARGET + ); + } + + private static void addAvoidActivities(Brain brain) { + brain.setTaskList( + Activity.AVOID, + 10, + ImmutableList.of( + GoToRememberedPositionTask.createEntityBased(MemoryModuleType.AVOID_TARGET, 0.9F, 32, true), + makeRandomWanderTask() + ), + MemoryModuleType.AVOID_TARGET + ); + } + public static void updateActivities(RascalEntity rascal) { rascal.getBrain().resetPossibleActivities( ImmutableList.of( - FriendsAndFoesActivities.TUFF_GOLEM_HOME.get(), + FriendsAndFoesActivities.RASCAL_WAIT.get(), + Activity.AVOID, Activity.IDLE ) ); @@ -76,13 +107,43 @@ public static void updateActivities(RascalEntity rascal) { private static RandomTask makeRandomWanderTask() { return new RandomTask( ImmutableList.of( - Pair.of(new StrollTask(0.6F), 2), - Pair.of(new GoTowardsLookTarget(1.0F, 3), 2), + Pair.of(StrollTask.create(0.6F), 2), + Pair.of(GoTowardsLookTargetTask.create(1.0F, 3), 2), Pair.of(new WaitTask(30, 60), 1) ) ); } + public static void setNodCooldown(RascalEntity rascal) { + rascal.getBrain().remember(FriendsAndFoesMemoryModuleTypes.RASCAL_NOD_COOLDOWN.get(), NOD_COOLDOWN_PROVIDER.get(rascal.getRandom())); + onCooldown(rascal); + } + + public static boolean shouldRunAway(RascalEntity rascal) { + return rascal.getBrain().getOptionalRegisteredMemory(FriendsAndFoesMemoryModuleTypes.RASCAL_NOD_COOLDOWN.get()).isPresent(); + } + + public static void onCooldown(RascalEntity rascal) { + if (shouldRunAway(rascal) == false) { + return; + } + + LivingEntity nearestTarget = rascal.getBrain().getOptionalRegisteredMemory(MemoryModuleType.INTERACTION_TARGET).orElse(null); + + if (nearestTarget == null) { + return; + } + + runAwayFrom(rascal, nearestTarget); + } + + private static void runAwayFrom(RascalEntity rascal, LivingEntity target) { + rascal.getBrain().forget(MemoryModuleType.LOOK_TARGET); + rascal.getBrain().forget(MemoryModuleType.WALK_TARGET); + rascal.getBrain().forget(MemoryModuleType.INTERACTION_TARGET); + rascal.getBrain().remember(MemoryModuleType.AVOID_TARGET, target, AVOID_MEMORY_DURATION.get(rascal.getRandom())); + } + static { SENSORS = List.of( SensorType.NEAREST_LIVING_ENTITIES, @@ -93,8 +154,14 @@ private static RandomTask makeRandomWanderTask() { MemoryModuleType.PATH, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, + MemoryModuleType.AVOID_TARGET, + MemoryModuleType.INTERACTION_TARGET, + MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, + MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, - FriendsAndFoesMemoryModuleTypes.TUFF_GOLEM_SLEEP_COOLDOWN.get() + FriendsAndFoesMemoryModuleTypes.RASCAL_NOD_COOLDOWN.get() ); + NOD_COOLDOWN_PROVIDER = TimeHelper.betweenSeconds(30, 40); + AVOID_MEMORY_DURATION = TimeHelper.betweenSeconds(20, 30); } } diff --git a/common/src/main/java/com/faboslav/friendsandfoes/entity/ai/brain/task/rascal/RascalWaitForPlayerTask.java b/common/src/main/java/com/faboslav/friendsandfoes/entity/ai/brain/task/rascal/RascalWaitForPlayerTask.java new file mode 100644 index 000000000..0b02d2ccd --- /dev/null +++ b/common/src/main/java/com/faboslav/friendsandfoes/entity/ai/brain/task/rascal/RascalWaitForPlayerTask.java @@ -0,0 +1,122 @@ +package com.faboslav.friendsandfoes.entity.ai.brain.task.rascal; + +import com.faboslav.friendsandfoes.entity.RascalEntity; +import com.faboslav.friendsandfoes.entity.ai.brain.RascalBrain; +import com.faboslav.friendsandfoes.init.FriendsAndFoesMemoryModuleTypes; +import com.google.common.collect.ImmutableMap; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.brain.MemoryModuleState; +import net.minecraft.entity.ai.brain.MemoryModuleType; +import net.minecraft.entity.ai.brain.task.LookTargetUtil; +import net.minecraft.entity.ai.brain.task.MultiTickTask; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.random.Random; + +public final class RascalWaitForPlayerTask extends MultiTickTask +{ + private final static int NOD_DURATION = 60; + public final static float NOD_RANGE = 5.0F; + + private int nodTicks; + private LivingEntity nearestTarget; + + public RascalWaitForPlayerTask() { + super(ImmutableMap.of( + MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleState.REGISTERED, + MemoryModuleType.NEAREST_PLAYERS, MemoryModuleState.REGISTERED, + FriendsAndFoesMemoryModuleTypes.RASCAL_NOD_COOLDOWN.get(), MemoryModuleState.VALUE_ABSENT + ), NOD_DURATION); + } + + @Override + protected boolean shouldRun(ServerWorld world, RascalEntity rascal) { + LivingEntity nearestTarget = rascal.getBrain().getOptionalRegisteredMemory(MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER).orElse(null); + + if (nearestTarget == null) { + nearestTarget = rascal.getBrain().getOptionalRegisteredMemory(MemoryModuleType.INTERACTION_TARGET).orElse(null); + } + + if ( + nearestTarget == null + || rascal.distanceTo(nearestTarget) > NOD_RANGE + || nearestTarget.isAlive() == false + || ( + nearestTarget instanceof PlayerEntity + && ( + nearestTarget.isSpectator() + || ((PlayerEntity) nearestTarget).isCreative() + ) + ) + ) { + + if (nearestTarget == null) { + } + return false; + } + + this.nearestTarget = nearestTarget; + + return true; + } + + @Override + protected void run(ServerWorld world, RascalEntity rascal, long time) { + rascal.getBrain().forget(MemoryModuleType.WALK_TARGET); + rascal.getNavigation().stop(); + + LookTargetUtil.lookAt(rascal, this.nearestTarget); + rascal.getLookControl().lookAt(this.nearestTarget); + + this.nodTicks = 0; + rascal.addToCaughtCount(); + } + + @Override + protected boolean shouldKeepRunning(ServerWorld world, RascalEntity rascal, long time) { + return this.nodTicks <= NOD_DURATION; + } + + @Override + protected void keepRunning(ServerWorld world, RascalEntity rascal, long time) { + rascal.getLookControl().lookAt(this.nearestTarget); + + if(nodTicks == 30) { + if (rascal.shouldGiveReward()) { + rascal.playRewardSound(); + Random random = rascal.getRandom(); + ItemStack itemStack = Items.IRON_PICKAXE.getDefaultStack(); + ItemStack enchantedItemStack = EnchantmentHelper.enchant( + random, + itemStack, + rascal.getRandom().nextBetween(15, 19), + true + ); + + LookTargetUtil.give(rascal, enchantedItemStack, nearestTarget.getPos().add(0.0, 1.0, 0.0)); + } else { + rascal.playNodSound(); + } + } + + this.nodTicks++; + } + + @Override + protected void finishRunning(ServerWorld world, RascalEntity rascal, long time) { + if (rascal.shouldGiveReward() && rascal.hasCustomName() == false) { + rascal.spawnCloudParticles(); + rascal.playAmbientSound(); + rascal.discard(); + } + + rascal.spawnCloudParticles(); + rascal.addStatusEffect(new StatusEffectInstance(StatusEffects.INVISIBILITY, 600)); + RascalBrain.setNodCooldown(rascal); + } +} diff --git a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesActivities.java b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesActivities.java index 954e0d6d8..fbeb021f1 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesActivities.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesActivities.java @@ -11,9 +11,11 @@ public final class FriendsAndFoesActivities { public final static Supplier TUFF_GOLEM_HOME; + public final static Supplier RASCAL_WAIT; static { TUFF_GOLEM_HOME = RegistryHelper.registerActivity("tuff_golem_home", () -> new Activity("tuff_golem_home")); + RASCAL_WAIT = RegistryHelper.registerActivity("rascal_wait", () -> new Activity("rascal_wait")); } public static void init() { diff --git a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesEntityTypes.java b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesEntityTypes.java index 96d65f904..fb9031318 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesEntityTypes.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesEntityTypes.java @@ -3,7 +3,6 @@ import com.faboslav.friendsandfoes.FriendsAndFoes; import com.faboslav.friendsandfoes.api.MoobloomVariants; import com.faboslav.friendsandfoes.client.render.entity.renderer.WildfireEntityRenderer; -import com.faboslav.friendsandfoes.config.annotation.Description; import com.faboslav.friendsandfoes.entity.*; import com.faboslav.friendsandfoes.mixin.SpawnRestrictionAccessor; import com.faboslav.friendsandfoes.platform.BiomeModifications; @@ -15,14 +14,7 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnGroup; import net.minecraft.entity.SpawnRestriction; -import net.minecraft.tag.BiomeTags; -import net.minecraft.tag.StructureTags; -import net.minecraft.tag.TagKey; -import net.minecraft.util.registry.BuiltinRegistries; -import net.minecraft.util.registry.Registry; import net.minecraft.world.Heightmap; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.gen.structure.Structure; import java.util.function.Supplier; @@ -107,7 +99,7 @@ public static void addSpawns() { BiomeModifications.addMobSpawn(FriendsAndFoesTags.HAS_MORE_MOOBLOOMS, MOOBLOOM.get(), SpawnGroup.CREATURE, config.moobloomMeadowSpawnWeight, config.moobloomMeadowSpawnMinGroupSize, config.moobloomMeadowSpawnMaxGroupSize); } - if(config.enableRascal && config.enableRascalSpawn) { + if (config.enableRascal && config.enableRascalSpawn) { BiomeModifications.addMobSpawn(FriendsAndFoesTags.HAS_RASCAL, RASCAL.get(), CustomSpawnGroup.getRascalsCategory(), 4, 1, 1); } } diff --git a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesItems.java b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesItems.java index 639234585..420964e4d 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesItems.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesItems.java @@ -19,6 +19,7 @@ public final class FriendsAndFoesItems public final static Supplier ILLUSIONER_SPAWN_EGG; public final static Supplier MAULER_SPAWN_EGG; public final static Supplier MOOBLOOM_SPAWN_EGG; + public final static Supplier RASCAL_SPAWN_EGG; public final static Supplier TUFF_GOLEM_SPAWN_EGG; public final static Supplier WILDFIRE_SPAWN_EGG; public static final Supplier BUTTERCUP; @@ -59,6 +60,7 @@ public final class FriendsAndFoesItems ILLUSIONER_SPAWN_EGG = RegistryHelper.registerSpawnEggItem("illusioner_spawn_egg", () -> EntityType.ILLUSIONER, 0x603E5C, 0x888E8E, new Item.Settings().maxCount(64)); MAULER_SPAWN_EGG = RegistryHelper.registerSpawnEggItem("mauler_spawn_egg", FriendsAndFoesEntityTypes.MAULER, 0x534F25, 0x817B39, new Item.Settings().maxCount(64)); MOOBLOOM_SPAWN_EGG = RegistryHelper.registerSpawnEggItem("moobloom_spawn_egg", FriendsAndFoesEntityTypes.MOOBLOOM, 0xF7EDC1, 0xFACA00, new Item.Settings().maxCount(64)); + RASCAL_SPAWN_EGG = RegistryHelper.registerSpawnEggItem("rascal_spawn_egg", FriendsAndFoesEntityTypes.RASCAL, 0x05736A, 0x8A521C, new Item.Settings().maxCount(64)); TUFF_GOLEM_SPAWN_EGG = RegistryHelper.registerSpawnEggItem("tuff_golem_spawn_egg", FriendsAndFoesEntityTypes.TUFF_GOLEM, 0xA0A297, 0x5D5D52, new Item.Settings().maxCount(64)); WILDFIRE_SPAWN_EGG = RegistryHelper.registerSpawnEggItem("wildfire_spawn_egg", FriendsAndFoesEntityTypes.WILDFIRE, 0x6C3100, 0xFFD528, new Item.Settings().maxCount(64)); BUTTERCUP = RegistryHelper.registerItem("buttercup", () -> new BlockItem(FriendsAndFoesBlocks.BUTTERCUP.get(), new Item.Settings().maxCount(64))); @@ -107,8 +109,9 @@ private static void addToItemGroups() { RegistryHelper.addToItemGroupAfter(ItemGroups.SPAWN_EGGS, ILLUSIONER_SPAWN_EGG.get(), ICEOLOGER_SPAWN_EGG.get()); RegistryHelper.addToItemGroupAfter(ItemGroups.SPAWN_EGGS, MAULER_SPAWN_EGG.get(), Items.MAGMA_CUBE_SPAWN_EGG); RegistryHelper.addToItemGroupBefore(ItemGroups.SPAWN_EGGS, MOOBLOOM_SPAWN_EGG.get(), Items.MOOSHROOM_SPAWN_EGG); - RegistryHelper.addToItemGroupBefore(ItemGroups.SPAWN_EGGS, TUFF_GOLEM_SPAWN_EGG.get(), TUFF_GOLEM_SPAWN_EGG.get()); - RegistryHelper.addToItemGroupBefore(ItemGroups.SPAWN_EGGS, WILDFIRE_SPAWN_EGG.get(), WILDFIRE_SPAWN_EGG.get()); + RegistryHelper.addToItemGroupBefore(ItemGroups.SPAWN_EGGS, TUFF_GOLEM_SPAWN_EGG.get(), Items.TURTLE_SPAWN_EGG); + RegistryHelper.addToItemGroupBefore(ItemGroups.SPAWN_EGGS, RASCAL_SPAWN_EGG.get(), Items.RAVAGER_SPAWN_EGG); + RegistryHelper.addToItemGroupBefore(ItemGroups.SPAWN_EGGS, WILDFIRE_SPAWN_EGG.get(), Items.WITCH_SPAWN_EGG); RegistryHelper.addToItemGroupAfter(ItemGroups.NATURAL, BUTTERCUP.get(), Items.DANDELION); RegistryHelper.addToItemGroupAfter(ItemGroups.FUNCTIONAL, SPRUCE_BEEHIVE.get(), Items.BEEHIVE); diff --git a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesMemoryModuleTypes.java b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesMemoryModuleTypes.java index 75e3f6490..433ef2263 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesMemoryModuleTypes.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesMemoryModuleTypes.java @@ -16,12 +16,14 @@ public final class FriendsAndFoesMemoryModuleTypes public final static Supplier> WILDFIRE_SHOCKWAVE_ATTACK_COOLDOWN; public final static Supplier> WILDFIRE_SUMMON_BLAZE_COOLDOWN; public final static Supplier> TUFF_GOLEM_SLEEP_COOLDOWN; + public final static Supplier> RASCAL_NOD_COOLDOWN; static { WILDFIRE_BARRAGE_ATTACK_COOLDOWN = RegistryHelper.registerMemoryModuleType("wildfire_barrage_attack_cooldown", () -> new MemoryModuleType<>(Optional.of(Codec.INT))); WILDFIRE_SHOCKWAVE_ATTACK_COOLDOWN = RegistryHelper.registerMemoryModuleType("wildfire_shockwave_attack_cooldown", () -> new MemoryModuleType<>(Optional.of(Codec.INT))); WILDFIRE_SUMMON_BLAZE_COOLDOWN = RegistryHelper.registerMemoryModuleType("wildfire_summon_blazes_cooldown", () -> new MemoryModuleType<>(Optional.of(Codec.INT))); TUFF_GOLEM_SLEEP_COOLDOWN = RegistryHelper.registerMemoryModuleType("tuff_golem_sleep_cooldown", () -> new MemoryModuleType<>(Optional.of(Codec.INT))); + RASCAL_NOD_COOLDOWN = RegistryHelper.registerMemoryModuleType("rascal_nod_cooldown", () -> new MemoryModuleType<>(Optional.of(Codec.INT))); } public static void init() { diff --git a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesSoundEvents.java b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesSoundEvents.java index 8a74b3b44..24289d798 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesSoundEvents.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/init/FriendsAndFoesSoundEvents.java @@ -40,7 +40,7 @@ public final class FriendsAndFoesSoundEvents public static final Supplier ENTITY_MOOBLOOM_CONVERT; public static final Supplier ENTITY_PLAYER_MIRROR_MOVE; public static final Supplier ENTITY_RASCAL_AMBIENT; - public static final Supplier ENTITY_RASCAL_APPROVE; + public static final Supplier ENTITY_RASCAL_NOD; public static final Supplier ENTITY_RASCAL_HURT; public static final Supplier ENTITY_RASCAL_REWARD; public static final Supplier ENTITY_RASCAL_REWARD_BAD; @@ -91,7 +91,7 @@ public final class FriendsAndFoesSoundEvents ENTITY_MOOBLOOM_CONVERT = register("entity", "moobloom.convert"); ENTITY_PLAYER_MIRROR_MOVE = register("entity", "player.mirror_move"); ENTITY_RASCAL_AMBIENT = register("entity", "rascal.ambient"); - ENTITY_RASCAL_APPROVE = register("entity", "rascal.approve"); + ENTITY_RASCAL_NOD = register("entity", "rascal.nod"); ENTITY_RASCAL_HURT = register("entity", "rascal.hurt"); ENTITY_RASCAL_REWARD = register("entity", "rascal.reward"); ENTITY_RASCAL_REWARD_BAD = register("entity", "rascal.reward_bad"); diff --git a/common/src/main/java/com/faboslav/friendsandfoes/mixin/StrongholdGeneratorMixin.java b/common/src/main/java/com/faboslav/friendsandfoes/mixin/StrongholdGeneratorMixin.java index cc05171e0..42e90000f 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/mixin/StrongholdGeneratorMixin.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/mixin/StrongholdGeneratorMixin.java @@ -95,7 +95,7 @@ private void friendsandfoes_generate( ItemStack enchantedItemStack = EnchantmentHelper.enchant( random, itemStack, - random.nextBetween(1, 3), + random.nextBetween(1, 30), true ); diff --git a/common/src/main/java/com/faboslav/friendsandfoes/platform/CustomSpawnGroup.java b/common/src/main/java/com/faboslav/friendsandfoes/platform/CustomSpawnGroup.java index dcfb8826e..2ddabcb0a 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/platform/CustomSpawnGroup.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/platform/CustomSpawnGroup.java @@ -14,7 +14,7 @@ public final class CustomSpawnGroup public static final String RASCALS_INTERNAL_NAME = "RASCALS"; public static final String RASCALS_NAME = "rascals"; - public static final int RASCALS_SPAWN_CAP = 15; + public static final int RASCALS_SPAWN_CAP = 3; public static final boolean RASCALS_PEACEFUL = true; public static final boolean RASCALS_RARE = false; public static final int RASCALS_IMMEDIATE_DESPAWN_RANGE = 128; diff --git a/common/src/main/java/com/faboslav/friendsandfoes/world/spawner/IceologerSpawner.java b/common/src/main/java/com/faboslav/friendsandfoes/world/spawner/IceologerSpawner.java index 87826b8fa..371146750 100644 --- a/common/src/main/java/com/faboslav/friendsandfoes/world/spawner/IceologerSpawner.java +++ b/common/src/main/java/com/faboslav/friendsandfoes/world/spawner/IceologerSpawner.java @@ -43,7 +43,7 @@ public int spawn(ServerWorld world, boolean spawnMonsters, boolean spawnAnimals) if ( l < 5L || world.isDay() == false - || random.nextBetween(0, 1) != 0 + || random.nextBetween(0, 1) != 0 ) { return 0; } diff --git a/common/src/main/resources/assets/friendsandfoes/lang/en_us.json b/common/src/main/resources/assets/friendsandfoes/lang/en_us.json index 54dc056d8..56e5d9110 100644 --- a/common/src/main/resources/assets/friendsandfoes/lang/en_us.json +++ b/common/src/main/resources/assets/friendsandfoes/lang/en_us.json @@ -67,6 +67,7 @@ "item.friendsandfoes.illusioner_spawn_egg": "Illusioner Spawn Egg", "item.friendsandfoes.mauler_spawn_egg": "Mauler Spawn Egg", "item.friendsandfoes.moobloom_spawn_egg": "Moobloom Spawn Egg", + "item.friendsandfoes.rascal_spawn_egg": "Rascal Spawn Egg", "item.friendsandfoes.tuff_golem_spawn_egg": "Tuff Golem Spawn Egg", "item.friendsandfoes.wildfire_spawn_egg": "Wildfire Spawn Egg", "item.friendsandfoes.totem_of_freezing": "Totem of Freezing", @@ -101,7 +102,7 @@ "subtitle.entity.friendsandfoes.moobloom.convert": "Moobloom transforms", "subtitle.entity.friendsandfoes.player.mirror_move": "Player displaces", "subtitle.entity.friendsandfoes.rascal.ambient": "Rascal taunts", - "subtitle.entity.friendsandfoes.rascal.approve": "Rascal approves", + "subtitle.entity.friendsandfoes.rascal.nod": "Rascal nods", "subtitle.entity.friendsandfoes.rascal.hurt": "Rascal hurts", "subtitle.entity.friendsandfoes.rascal.reward": "Rascal gives reward", "subtitle.entity.friendsandfoes.rascal.reward_bad": "Rascal gives bad reward", diff --git a/common/src/main/resources/assets/friendsandfoes/models/item/rascal_spawn_egg.json b/common/src/main/resources/assets/friendsandfoes/models/item/rascal_spawn_egg.json new file mode 100644 index 000000000..9af90217d --- /dev/null +++ b/common/src/main/resources/assets/friendsandfoes/models/item/rascal_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "item/template_spawn_egg" +} \ No newline at end of file diff --git a/common/src/main/resources/assets/friendsandfoes/sounds.json b/common/src/main/resources/assets/friendsandfoes/sounds.json index e43d2619e..47493b4e6 100644 --- a/common/src/main/resources/assets/friendsandfoes/sounds.json +++ b/common/src/main/resources/assets/friendsandfoes/sounds.json @@ -193,14 +193,14 @@ ], "subtitle": "subtitle.entity.friendsandfoes.rascal.ambient" }, - "entity.rascal.approve": { + "entity.rascal.nod": { "sounds": [ - "friendsandfoes:entity/rascal/approve1", - "friendsandfoes:entity/rascal/approve2", - "friendsandfoes:entity/rascal/approve3", - "friendsandfoes:entity/rascal/approve4" + "friendsandfoes:entity/rascal/nod1", + "friendsandfoes:entity/rascal/nod2", + "friendsandfoes:entity/rascal/nod3", + "friendsandfoes:entity/rascal/nod4" ], - "subtitle": "subtitle.entity.friendsandfoes.rascal.approve" + "subtitle": "subtitle.entity.friendsandfoes.rascal.nod" }, "entity.rascal.hurt": { "sounds": [ diff --git a/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve1.ogg b/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod1.ogg similarity index 100% rename from common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve1.ogg rename to common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod1.ogg diff --git a/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve2.ogg b/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod2.ogg similarity index 100% rename from common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve2.ogg rename to common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod2.ogg diff --git a/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve3.ogg b/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod3.ogg similarity index 100% rename from common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve3.ogg rename to common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod3.ogg diff --git a/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve4.ogg b/common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod4.ogg similarity index 100% rename from common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/approve4.ogg rename to common/src/main/resources/assets/friendsandfoes/sounds/entity/rascal/nod4.ogg diff --git a/common/src/main/resources/data/friendsandfoes/loot_tables/entities/rascal.json b/common/src/main/resources/data/friendsandfoes/loot_tables/entities/rascal.json new file mode 100644 index 000000000..605616d6d --- /dev/null +++ b/common/src/main/resources/data/friendsandfoes/loot_tables/entities/rascal.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:entity", + "pools": [] +} \ No newline at end of file diff --git a/common/src/main/resources/data/minecraft/advancements/husbandry/wax_off.json b/common/src/main/resources/data/minecraft/advancements/husbandry/wax_off.json index 91e6bd33b..d28d536f0 100644 --- a/common/src/main/resources/data/minecraft/advancements/husbandry/wax_off.json +++ b/common/src/main/resources/data/minecraft/advancements/husbandry/wax_off.json @@ -17,50 +17,50 @@ "announce_to_chat": true, "hidden": false }, - "criteria": { - "wax_off": { - "conditions": { - "location": [ - { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": [ - "minecraft:waxed_copper_block", - "minecraft:waxed_exposed_copper", - "minecraft:waxed_weathered_copper", - "minecraft:waxed_oxidized_copper", - "minecraft:waxed_cut_copper", - "minecraft:waxed_exposed_cut_copper", - "minecraft:waxed_weathered_cut_copper", - "minecraft:waxed_oxidized_cut_copper", - "minecraft:waxed_cut_copper_slab", - "minecraft:waxed_exposed_cut_copper_slab", - "minecraft:waxed_weathered_cut_copper_slab", - "minecraft:waxed_oxidized_cut_copper_slab", - "minecraft:waxed_cut_copper_stairs", - "minecraft:waxed_exposed_cut_copper_stairs", - "minecraft:waxed_weathered_cut_copper_stairs", - "minecraft:waxed_oxidized_cut_copper_stairs", - "friendsandfoes:waxed_copper_button", - "friendsandfoes:waxed_exposed_copper_button", - "friendsandfoes:waxed_oxidized_copper_button", - "friendsandfoes:waxed_weathered_copper_button" - ] - } - } - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "tag": "minecraft:axes" - } - } - ] - }, - "trigger": "minecraft:item_used_on_block" - } - }, + "criteria": { + "wax_off": { + "conditions": { + "location": [ + { + "condition": "minecraft:location_check", + "predicate": { + "block": { + "blocks": [ + "minecraft:waxed_copper_block", + "minecraft:waxed_exposed_copper", + "minecraft:waxed_weathered_copper", + "minecraft:waxed_oxidized_copper", + "minecraft:waxed_cut_copper", + "minecraft:waxed_exposed_cut_copper", + "minecraft:waxed_weathered_cut_copper", + "minecraft:waxed_oxidized_cut_copper", + "minecraft:waxed_cut_copper_slab", + "minecraft:waxed_exposed_cut_copper_slab", + "minecraft:waxed_weathered_cut_copper_slab", + "minecraft:waxed_oxidized_cut_copper_slab", + "minecraft:waxed_cut_copper_stairs", + "minecraft:waxed_exposed_cut_copper_stairs", + "minecraft:waxed_weathered_cut_copper_stairs", + "minecraft:waxed_oxidized_cut_copper_stairs", + "friendsandfoes:waxed_copper_button", + "friendsandfoes:waxed_exposed_copper_button", + "friendsandfoes:waxed_oxidized_copper_button", + "friendsandfoes:waxed_weathered_copper_button" + ] + } + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "tag": "minecraft:axes" + } + } + ] + }, + "trigger": "minecraft:item_used_on_block" + } + }, "requirements": [ [ "wax_off" diff --git a/common/src/main/resources/data/minecraft/advancements/husbandry/wax_on.json b/common/src/main/resources/data/minecraft/advancements/husbandry/wax_on.json index 32b962979..a0ea0390e 100644 --- a/common/src/main/resources/data/minecraft/advancements/husbandry/wax_on.json +++ b/common/src/main/resources/data/minecraft/advancements/husbandry/wax_on.json @@ -16,52 +16,52 @@ "announce_to_chat": true, "hidden": false }, - "criteria": { - "wax_on": { - "conditions": { - "location": [ - { - "condition": "minecraft:location_check", - "predicate": { - "block": { - "blocks": [ - "minecraft:copper_block", - "minecraft:exposed_copper", - "minecraft:weathered_copper", - "minecraft:oxidized_copper", - "minecraft:cut_copper", - "minecraft:exposed_cut_copper", - "minecraft:weathered_cut_copper", - "minecraft:oxidized_cut_copper", - "minecraft:cut_copper_slab", - "minecraft:exposed_cut_copper_slab", - "minecraft:weathered_cut_copper_slab", - "minecraft:oxidized_cut_copper_slab", - "minecraft:cut_copper_stairs", - "minecraft:exposed_cut_copper_stairs", - "minecraft:weathered_cut_copper_stairs", - "minecraft:oxidized_cut_copper_stairs", - "friendsandfoes:copper_button", - "friendsandfoes:exposed_copper_button", - "friendsandfoes:oxidized_copper_button", - "friendsandfoes:weathered_copper_button" - ] - } - } - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "items": [ - "minecraft:honeycomb" - ] - } - } - ] - }, - "trigger": "minecraft:item_used_on_block" - } - }, + "criteria": { + "wax_on": { + "conditions": { + "location": [ + { + "condition": "minecraft:location_check", + "predicate": { + "block": { + "blocks": [ + "minecraft:copper_block", + "minecraft:exposed_copper", + "minecraft:weathered_copper", + "minecraft:oxidized_copper", + "minecraft:cut_copper", + "minecraft:exposed_cut_copper", + "minecraft:weathered_cut_copper", + "minecraft:oxidized_cut_copper", + "minecraft:cut_copper_slab", + "minecraft:exposed_cut_copper_slab", + "minecraft:weathered_cut_copper_slab", + "minecraft:oxidized_cut_copper_slab", + "minecraft:cut_copper_stairs", + "minecraft:exposed_cut_copper_stairs", + "minecraft:weathered_cut_copper_stairs", + "minecraft:oxidized_cut_copper_stairs", + "friendsandfoes:copper_button", + "friendsandfoes:exposed_copper_button", + "friendsandfoes:oxidized_copper_button", + "friendsandfoes:weathered_copper_button" + ] + } + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "items": [ + "minecraft:honeycomb" + ] + } + } + ] + }, + "trigger": "minecraft:item_used_on_block" + } + }, "requirements": [ [ "wax_on"