diff --git a/src/generated/resources/.cache/0fe122e549a2e3aeeca535edbc3649f31121d28e b/src/generated/resources/.cache/0fe122e549a2e3aeeca535edbc3649f31121d28e index e2631f7c2e..97253aa9a8 100644 --- a/src/generated/resources/.cache/0fe122e549a2e3aeeca535edbc3649f31121d28e +++ b/src/generated/resources/.cache/0fe122e549a2e3aeeca535edbc3649f31121d28e @@ -1,4 +1,4 @@ -// 1.20.1 2024-01-23T12:37:16.0299097 Tags for minecraft:entity_type mod id aether +// 1.20.1 2024-04-01T21:48:51.7997534 Tags for minecraft:entity_type mod id aether b3a379df5d7bd0f9d26800bb985a7acba83143fe data/aether/tags/entity_types/deflectable_projectiles.json 1b6a9ff2a0c19d921d6b0012941d44eeb7c028f6 data/aether/tags/entity_types/dungeon_entities.json 0830aa859642688f0ce9dbf68ec5710f92d7f5d6 data/aether/tags/entity_types/fire_mob.json @@ -7,6 +7,7 @@ b3a379df5d7bd0f9d26800bb985a7acba83143fe data/aether/tags/entity_types/deflectab 6ded3ea2e35a47445f95b3e2a263d918575d48cf data/aether/tags/entity_types/no_candy_cane_drops.json f7203aae71175bb0e7c7c2df595579e99489b9ab data/aether/tags/entity_types/no_skyroot_double_drops.json 2bd7356d8661b5745b019dfe60733e365ba7de97 data/aether/tags/entity_types/pigs.json +0749942c552cc826aaefd3edd65eaa376647ee1c data/aether/tags/entity_types/slider_damaging_projectiles.json 4fd137c2bce66e14ebca74226b1d16dd47f5b553 data/aether/tags/entity_types/swets.json 35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/aether/tags/entity_types/treated_as_aether_entity.json 35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/aether/tags/entity_types/treated_as_vanilla_entity.json diff --git a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e index 2fdc0ce3a4..f6163d3bef 100644 --- a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e +++ b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e @@ -1,4 +1,4 @@ -// 1.20.1 2024-03-17T20:14:22.2015111 Recipes +// 1.20.1 2024-04-01T21:48:51.8197528 Recipes ce9ab2e043b1d5d8747a22324584f0bcf4c2b3b1 data/aether/advancements/recipes/building_blocks/aerogel_slab.json 90208eb708709fa9badd0fc606e5daf5ad91b03b data/aether/advancements/recipes/building_blocks/aerogel_slab_from_aerogel_stonecutting.json 6845688223f47a89fd0d51f6e6d1de155f983710 data/aether/advancements/recipes/building_blocks/aerogel_stairs.json @@ -323,7 +323,7 @@ c978ad29d62a992f1a45c13793d45564e8718de1 data/aether/recipes/aether_gold_nugget_ d6ea60e365df69ac31671107d7c4b87d96adcb24 data/aether/recipes/aether_iron_nugget_from_smelting.json 22c5f28f42aeeec0a4f9bb3f4d3b4d1a7f94d22d data/aether/recipes/aether_saddle.json 0c21d2b654c566de841cac9311066f39f31e85bc data/aether/recipes/aether_tune_enchanting.json -07f4b638eb1ebe38f6a2a736eb6ef7325f5c6fce data/aether/recipes/altar.json +52afabb7a247db3632c65c5e2efcee8f0fee15d3 data/aether/recipes/altar.json f16e7f5f90f310f7be36030d1070e44e76e7cbdb data/aether/recipes/ambrosium_block.json 453451e26bd4a68814efc558a9eae20afcbc8c3d data/aether/recipes/ambrosium_enchant_aether_grass_to_enchanted_aether_grass.json 311c797765eefdecd2e980cbbfb50217d7ad66ee data/aether/recipes/ambrosium_shard_from_ambrosium_block.json diff --git a/src/generated/resources/data/aether/recipes/altar.json b/src/generated/resources/data/aether/recipes/altar.json index 8613438361..b0898ea5f9 100644 --- a/src/generated/resources/data/aether/recipes/altar.json +++ b/src/generated/resources/data/aether/recipes/altar.json @@ -6,7 +6,7 @@ "item": "aether:holystone" }, "Z": { - "item": "aether:zanite_gemstone" + "tag": "aether:gems/zanite" } }, "pattern": [ diff --git a/src/generated/resources/data/aether/tags/entity_types/slider_damaging_projectiles.json b/src/generated/resources/data/aether/tags/entity_types/slider_damaging_projectiles.json new file mode 100644 index 0000000000..f86b443154 --- /dev/null +++ b/src/generated/resources/data/aether/tags/entity_types/slider_damaging_projectiles.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "quark:pickarang", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/main/java/com/aetherteam/aether/AetherTags.java b/src/main/java/com/aetherteam/aether/AetherTags.java index 7b38feef88..787ea9fa42 100644 --- a/src/main/java/com/aetherteam/aether/AetherTags.java +++ b/src/main/java/com/aetherteam/aether/AetherTags.java @@ -178,6 +178,7 @@ public static class Entities { public static final TagKey> TREATED_AS_AETHER_ENTITY = tag("treated_as_aether_entity"); public static final TagKey> TREATED_AS_VANILLA_ENTITY = tag("treated_as_vanilla_entity"); public static final TagKey> DUNGEON_ENTITIES = tag("dungeon_entities"); + public static final TagKey> SLIDER_DAMAGING_PROJECTILES = tag("slider_damaging_projectiles"); private static TagKey> tag(String name) { return TagKey.create(Registries.ENTITY_TYPE, new ResourceLocation(Aether.MODID, name)); diff --git a/src/main/java/com/aetherteam/aether/data/generators/tags/AetherEntityTagData.java b/src/main/java/com/aetherteam/aether/data/generators/tags/AetherEntityTagData.java index 897a0a147a..a7f4ef6f2e 100644 --- a/src/main/java/com/aetherteam/aether/data/generators/tags/AetherEntityTagData.java +++ b/src/main/java/com/aetherteam/aether/data/generators/tags/AetherEntityTagData.java @@ -6,6 +6,7 @@ import net.minecraft.core.HolderLookup; import net.minecraft.data.PackOutput; import net.minecraft.data.tags.EntityTypeTagsProvider; +import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.EntityTypeTags; import net.minecraft.world.entity.EntityType; import net.minecraftforge.common.Tags; @@ -81,6 +82,8 @@ public void addTags(HolderLookup.Provider provider) { AetherEntityTypes.FIRE_MINION.get(), AetherEntityTypes.FIRE_CRYSTAL.get(), AetherEntityTypes.ICE_CRYSTAL.get()); + this.tag(AetherTags.Entities.SLIDER_DAMAGING_PROJECTILES) + .addOptional(new ResourceLocation("quark", "pickarang")); // Forge this.tag(Tags.EntityTypes.BOSSES).add( diff --git a/src/main/java/com/aetherteam/aether/entity/monster/dungeon/boss/Slider.java b/src/main/java/com/aetherteam/aether/entity/monster/dungeon/boss/Slider.java index db0b0f833b..9dedcbd29c 100644 --- a/src/main/java/com/aetherteam/aether/entity/monster/dungeon/boss/Slider.java +++ b/src/main/java/com/aetherteam/aether/entity/monster/dungeon/boss/Slider.java @@ -42,6 +42,7 @@ import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.monster.Enemy; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.block.Blocks; @@ -55,6 +56,7 @@ import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nullable; +import java.util.Optional; import java.util.function.Predicate; public class Slider extends PathfinderMob implements AetherBossMob, Enemy, IEntityAdditionalSpawnData { @@ -183,72 +185,123 @@ public void customServerAiStep() { } /** - * Handles damaging the Slider or playing a chat message if the player attempts to damage with the wrong tool. + * Handles damaging the Slider. * @param source The {@link DamageSource}. * @param amount The {@link Float} amount of damage. * @return Whether the entity was hurt, as a {@link Boolean}. */ @Override public boolean hurt(DamageSource source, float amount) { + Optional damageResult = this.canDamageSlider(source); if (source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) { super.hurt(source, amount); if (!this.level().isClientSide() && source.getEntity() instanceof LivingEntity living) { this.mostDamageTargetGoal.addAggro(living, amount); // AI goal for being hurt. } - } else if (source.getDirectEntity() instanceof LivingEntity attacker && this.level().getDifficulty() != Difficulty.PEACEFUL) { - if (this.getDungeon() == null || this.getDungeon().isPlayerWithinRoomInterior(attacker)) { // Only allow damage within the boss room. - if (attacker.getMainHandItem().canPerformAction(ToolActions.PICKAXE_DIG) || attacker.getMainHandItem().is(AetherTags.Items.SLIDER_DAMAGING_ITEMS)) { // Check for correct tool. - if (super.hurt(source, amount) && this.getHealth() > 0) { - if (!this.isBossFight()) { - this.start(); - } - this.setDeltaMovement(this.getDeltaMovement().scale(0.75F)); - - // Handle the Slider's model tilt when damaged. - double a = Math.abs(this.position().x() - attacker.position().x()); - double c = Math.abs(this.position().z() - attacker.position().z()); - if (a > c) { - this.setHurtAngleZ(1); - this.setHurtAngleX(0); - if (this.position().x() > attacker.position().x()) { - this.setHurtAngleZ(-1); - } - } else { - this.setHurtAngleX(1); - this.setHurtAngleZ(0); - if (this.position().z() > attacker.position().z()) { - this.setHurtAngleX(-1); - } - } - this.setHurtAngle(0.7F - (this.getHealth() / 875.0F)); - - if (!this.level().isClientSide() && source.getEntity() instanceof LivingEntity living) { - this.mostDamageTargetGoal.addAggro(living, amount); // AI goal for being hurt. - } - return true; + } else if (damageResult.isPresent()) { + LivingEntity attacker = damageResult.get(); + if (super.hurt(source, amount) && this.getHealth() > 0) { + if (!this.isBossFight()) { + this.start(); + } + this.setDeltaMovement(this.getDeltaMovement().scale(0.75F)); + + // Handle the Slider's model tilt when damaged. + double a = Math.abs(this.position().x() - attacker.position().x()); + double c = Math.abs(this.position().z() - attacker.position().z()); + if (a > c) { + this.setHurtAngleZ(1); + this.setHurtAngleX(0); + if (this.position().x() > attacker.position().x()) { + this.setHurtAngleZ(-1); } } else { - if (!this.level().isClientSide() && attacker instanceof Player player) { - if (this.getChatCooldown() <= 0) { - player.sendSystemMessage(Component.translatable("gui.aether.slider.message.attack.invalid")); // Invalid tool. - this.setChatCooldown(15); - return false; - } + this.setHurtAngleX(1); + this.setHurtAngleZ(0); + if (this.position().z() > attacker.position().z()) { + this.setHurtAngleX(-1); } } - } else { - if (!this.level().isClientSide() && attacker instanceof Player player) { - if (this.getChatCooldown() <= 0) { - this.displayTooFarMessage(player); // Too far from Slider - this.setChatCooldown(15); - return false; - } + this.setHurtAngle(0.7F - (this.getHealth() / 875.0F)); + + if (!this.level().isClientSide() && source.getEntity() instanceof LivingEntity living) { + this.mostDamageTargetGoal.addAggro(living, amount); // AI goal for being hurt. } + return true; } } return false; } + /** + * Checks whether the Slider can be damaged, playing a chat message if the player attempts to damage with the wrong tool or is too far away. + * + * @param source The {@link DamageSource}. + * @return An {@link Optional} that contains the attacking {@link LivingEntity} if the damage checks are successful. + */ + private Optional canDamageSlider(DamageSource source) { + if (this.level().getDifficulty() != Difficulty.PEACEFUL) { + if (source.getDirectEntity() instanceof LivingEntity attacker) { + if (this.getDungeon() == null || this.getDungeon().isPlayerWithinRoomInterior(attacker)) { // Only allow damage within the boss room. + if (attacker.getMainHandItem().canPerformAction(ToolActions.PICKAXE_DIG) + || attacker.getMainHandItem().is(AetherTags.Items.SLIDER_DAMAGING_ITEMS) + || attacker.getMainHandItem().isCorrectToolForDrops(AetherBlocks.CARVED_STONE.get().defaultBlockState())) { // Check for correct tool. + return Optional.of(attacker); + } else { + return this.sendInvalidToolMessage(attacker); + } + } else { + this.sendTooFarMessage(attacker); + } + } else if (source.getDirectEntity() instanceof Projectile projectile) { + if (projectile.getOwner() instanceof LivingEntity attacker) { + if (this.getDungeon() == null || this.getDungeon().isPlayerWithinRoomInterior(attacker)) { // Only allow damage within the boss room. + if (projectile.getType().is(AetherTags.Entities.SLIDER_DAMAGING_PROJECTILES)) { + return Optional.of(attacker); + } else { + return this.sendInvalidToolMessage(attacker); + } + } else { + return this.sendTooFarMessage(attacker); + } + } + } + } + return Optional.empty(); + } + + /** + * Tells the player that they are using an invalid tool to attack the Slider. + * + * @param attacker The attacking {@link LivingEntity}. + * @return An empty {@link Optional}. + */ + private Optional sendInvalidToolMessage(LivingEntity attacker) { + if (!this.level().isClientSide() && attacker instanceof Player player) { + if (this.getChatCooldown() <= 0) { + player.sendSystemMessage(Component.translatable("gui.aether.slider.message.attack.invalid")); // Invalid tool. + this.setChatCooldown(15); + } + } + return Optional.empty(); + } + + /** + * Tells the player that they are too far away to attack the Slider. + * + * @param attacker The attacking {@link LivingEntity}. + * @return An empty {@link Optional}. + */ + private Optional sendTooFarMessage(LivingEntity attacker) { + if (!this.level().isClientSide() && attacker instanceof Player player) { + if (this.getChatCooldown() <= 0) { + this.displayTooFarMessage(player); // Too far from Slider + this.setChatCooldown(15); + } + } + return Optional.empty(); + } + /** * Awakens the boss, starts the boss fight, and closes the boss room. */