diff --git a/common/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/common/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d index 8d3df76f..427ff002 100644 --- a/common/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d +++ b/common/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -1,4 +1,4 @@ -// 1.21.1 2025-02-11T12:24:12.7349676 Loot Tables +// 1.21.1 2025-02-13T21:32:58.9330421 Loot Tables 2b18f4ee4964de853f965809175e41672c73f2a3 data/eternal_starlight/loot_table/blocks/abyssal_fire.json 188b8614ef4815c81bb45c3a918877795892cf25 data/eternal_starlight/loot_table/blocks/abyssal_geyser.json 77967e1af1e01fc2bbf8f97dd52c510df8648a4c data/eternal_starlight/loot_table/blocks/abyssal_kelp.json @@ -636,6 +636,7 @@ e7a4432f13c78aadaee5cb60b6c6ec9a2131bbf5 data/eternal_starlight/loot_table/bosse 817f9a82cca0cb3344de3bb32e8bde62c3aae487 data/eternal_starlight/loot_table/chests/cursed_garden.json a17c39e100a98bcc3ecff5dd8c27bed6ec49668c data/eternal_starlight/loot_table/chests/golem_forge.json 505d9a4868fc7eb145a066fcc20989938728b822 data/eternal_starlight/loot_table/chests/music_discs.json +6b6f0e7d5564829e079406c182b5c4b1c98e8743 data/eternal_starlight/loot_table/entities/aethersent_golem.json a461217c956af4bd0fb8803afa168aeb4b966da2 data/eternal_starlight/loot_table/entities/astral_golem.json 7f94abc7aae330ee290d6e0d4ee4b67e4bab1f18 data/eternal_starlight/loot_table/entities/aurora_deer.json fa0d1dceaeb0277bfa61ee74b03cfbe13644ee9c data/eternal_starlight/loot_table/entities/boarwarf.json @@ -658,7 +659,7 @@ d11b744e9604cb530323d11c95d7f6301f6acef4 data/eternal_starlight/loot_table/entit cdfda6f90f96ac9dd5c8997e86411f844ff69411 data/eternal_starlight/loot_table/entities/tangled_hatred.json babe6abda538bda4948feaa3bb8d8965deff0d8b data/eternal_starlight/loot_table/entities/tangled_skull.json b01bfc5a45f772ef5c880ced1d46e07c8a9613f6 data/eternal_starlight/loot_table/entities/the_gatekeeper.json -5d9a6a5389e54faca2c0597fa733a5a68ac14490 data/eternal_starlight/loot_table/entities/thirst_walker.json +394cea953eb6f0917e73c3821ea2b7e33c36cd79 data/eternal_starlight/loot_table/entities/thirst_walker.json ed91cb96fb35e52e950d7a03bb62f4f8db3070f1 data/eternal_starlight/loot_table/entities/tiny_creteor.json ea366c80eba1228ca61060c8975d24a771d86c82 data/eternal_starlight/loot_table/entities/tower_squid.json 9742c2717dc30701fa79d4ab3d735a2201afc8b9 data/eternal_starlight/loot_table/entities/twilight_gaze.json diff --git a/common/src/generated/resources/.cache/894d7d52e72304edfd08d72006a0a8d7ab469d4d b/common/src/generated/resources/.cache/894d7d52e72304edfd08d72006a0a8d7ab469d4d index d5bc18b7..bb855ce7 100644 --- a/common/src/generated/resources/.cache/894d7d52e72304edfd08d72006a0a8d7ab469d4d +++ b/common/src/generated/resources/.cache/894d7d52e72304edfd08d72006a0a8d7ab469d4d @@ -1,4 +1,4 @@ -// 1.21.1 2025-01-21T22:40:03.9807247 Tags for minecraft:entity_type mod id eternal_starlight +// 1.21.1 2025-02-13T17:53:49.4616158 Tags for minecraft:entity_type mod id eternal_starlight 5466319e12aea1f42139ac09c8ffdd0620c716d0 data/c/tags/entity_type/boats.json d44f14633b66cf9ee5f04c1bb297ee340a53e288 data/c/tags/entity_type/bosses.json 7c4a83216410b5cc42cab8c49f3ef1afb4bb9ebc data/eternal_starlight/tags/entity_type/abyssal_fire_immune.json @@ -10,7 +10,7 @@ be4ff0376ac9ff8a51eab4ae581131fd7b545de1 data/eternal_starlight/tags/entity_type 9579375f7c0346ef4ec7823ef881994b11c55b8d data/minecraft/tags/entity_type/arrows.json 3f853abb02779d1f23df9823ebb9d8707f24ddc9 data/minecraft/tags/entity_type/arthropod.json 0119460c4a1c254622e0f5a1b11847ceb1464491 data/minecraft/tags/entity_type/can_breathe_under_water.json -d8ee7cf341d31cccb0314d84c97e3e6567b95b60 data/minecraft/tags/entity_type/fall_damage_immune.json +c1b449952fdf84542a45629dcec3b9b589fcfa5b data/minecraft/tags/entity_type/fall_damage_immune.json f6eb1b878dcda83e8e0f0c5388c37999f2e0ec47 data/minecraft/tags/entity_type/freeze_immune_entity_types.json f627b828af90e448f9c5322878730dddd94748ff data/minecraft/tags/entity_type/immune_to_infested.json 81a6c1860d98805184066dd01894829e9b9830ec data/minecraft/tags/entity_type/skeletons.json diff --git a/common/src/generated/resources/.cache/9539076883c29777f26a3c22ea17f026ade8d9e9 b/common/src/generated/resources/.cache/9539076883c29777f26a3c22ea17f026ade8d9e9 index 2869e5c1..d820c79a 100644 --- a/common/src/generated/resources/.cache/9539076883c29777f26a3c22ea17f026ade8d9e9 +++ b/common/src/generated/resources/.cache/9539076883c29777f26a3c22ea17f026ade8d9e9 @@ -1,4 +1,4 @@ -// 1.21.1 2025-02-12T17:52:32.3457228 Item Models: eternal_starlight +// 1.21.1 2025-02-13T17:53:49.4616158 Item Models: eternal_starlight f36b77087c8c68017703cd72753faa9ec0bb05c9 assets/eternal_starlight/models/item/abyssal_fruit.json 566abbb0b7c88c3e62953e9a59a3c7a789481e57 assets/eternal_starlight/models/item/abyssal_geyser.json 22602a3404b600eeca3221ff2689c59995af1cfc assets/eternal_starlight/models/item/abyssal_magma_block.json @@ -7,6 +7,7 @@ aefbf234c6d365b47ec376cd21dc1466745acf08 assets/eternal_starlight/models/item/ab fe7306c93bf1160b307aadac41e110b8646db1cd assets/eternal_starlight/models/item/aethersent_boots.json 381a125bf62079c212d3d4fb061f87489fb0bfd1 assets/eternal_starlight/models/item/aethersent_bottoms.json c6bfef1ed529d339e0a66bad564b57071160d9a7 assets/eternal_starlight/models/item/aethersent_cape.json +63ec6c618a3a23eab4cab9c52d7d3250de9b516e assets/eternal_starlight/models/item/aethersent_golem_spawn_egg.json 487a980156ba5a388b63c97a459bb9b5337182ff assets/eternal_starlight/models/item/aethersent_hood.json 42c29417680db9a21399143fe130336922d42358 assets/eternal_starlight/models/item/aethersent_hood_amethyst_trim.json 0c74227eba977335bf574bd30cb71e9af8195cb7 assets/eternal_starlight/models/item/aethersent_hood_copper_trim.json diff --git a/common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 b/common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 index dd640782..5966e662 100644 --- a/common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 +++ b/common/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 @@ -1,4 +1,4 @@ -// 1.21.1 2025-01-26T23:30:11.7542554 Advancements +// 1.21.1 2025-02-13T21:32:58.9513671 Advancements bc79d3aedb5c3d78bbdf8ea64070159bb3371cb4 data/eternal_starlight/advancement/all_starlight_biomes.json f669cf32323b8189231a1ea04f94718c156a21b5 data/eternal_starlight/advancement/chain_tangled_skull_explosion.json bbc7597d700cf173452d0d1ae7c5a94322ce9ddc data/eternal_starlight/advancement/challenge_gatekeeper.json @@ -33,6 +33,7 @@ ea92e71eb7ad11f8c88fa1a238bc4b2b0fc5082f data/eternal_starlight/advancement/obta 02791f85a73f95f74c1dd667154917459d2d61e4 data/eternal_starlight/advancement/obtain_tooth_of_hunger_blocks.json a0dc8d246f5d8e11fca25090bc5d41b3d933c502 data/eternal_starlight/advancement/root.json 7b7c39c8a41e3d55dbca94b6189e20d9123cab2a data/eternal_starlight/advancement/saturate_dagger_of_hunger.json +52900675d4a6553e79995b6ffa6c5dc1d3c8e8de data/eternal_starlight/advancement/summon_aethersent_golem.json 40d15157c75157bc1ffdebdde016029473a01955 data/eternal_starlight/advancement/summon_grimstone_golem.json d1b5287e3a3c43c00a7aef0db4a5168532d8b679 data/eternal_starlight/advancement/tame_crystallized_moth.json 370c4174af4a372ecac94bdd34f6ee9dfb392021 data/eternal_starlight/advancement/throw_gleech_egg.json diff --git a/common/src/generated/resources/assets/eternal_starlight/models/item/aethersent_golem_spawn_egg.json b/common/src/generated/resources/assets/eternal_starlight/models/item/aethersent_golem_spawn_egg.json new file mode 100644 index 00000000..d1aaa9d6 --- /dev/null +++ b/common/src/generated/resources/assets/eternal_starlight/models/item/aethersent_golem_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} \ No newline at end of file diff --git a/common/src/generated/resources/data/eternal_starlight/advancement/summon_aethersent_golem.json b/common/src/generated/resources/data/eternal_starlight/advancement/summon_aethersent_golem.json new file mode 100644 index 00000000..fa1e65c5 --- /dev/null +++ b/common/src/generated/resources/data/eternal_starlight/advancement/summon_aethersent_golem.json @@ -0,0 +1,37 @@ +{ + "parent": "eternal_starlight:obtain_aethersent_ingot", + "criteria": { + "summon": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "eternal_starlight:aethersent_golem" + } + } + ] + }, + "trigger": "minecraft:summoned_entity" + } + }, + "display": { + "description": { + "translate": "advancements.eternal_starlight.summon_aethersent_golem.description" + }, + "icon": { + "count": 1, + "id": "eternal_starlight:starfall_longbow" + }, + "title": { + "translate": "advancements.eternal_starlight.summon_aethersent_golem.title" + } + }, + "requirements": [ + [ + "summon" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/common/src/generated/resources/data/eternal_starlight/loot_table/entities/aethersent_golem.json b/common/src/generated/resources/data/eternal_starlight/loot_table/entities/aethersent_golem.json new file mode 100644 index 00000000..24fc9a91 --- /dev/null +++ b/common/src/generated/resources/data/eternal_starlight/loot_table/entities/aethersent_golem.json @@ -0,0 +1,66 @@ +{ + "type": "minecraft:entity", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 4.0, + "min": 2.0 + }, + "function": "minecraft:set_count" + }, + { + "count": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + }, + "enchantment": "minecraft:looting", + "function": "minecraft:enchanted_count_increase" + } + ], + "name": "eternal_starlight:aethersent_ingot" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 4.0, + "min": 2.0 + }, + "function": "minecraft:set_count" + }, + { + "count": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + }, + "enchantment": "minecraft:looting", + "function": "minecraft:enchanted_count_increase" + } + ], + "name": "eternal_starlight:raw_aethersent" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "eternal_starlight:entities/aethersent_golem" +} \ No newline at end of file diff --git a/common/src/generated/resources/data/eternal_starlight/loot_table/entities/thirst_walker.json b/common/src/generated/resources/data/eternal_starlight/loot_table/entities/thirst_walker.json index 4c3f54ba..3d817a70 100644 --- a/common/src/generated/resources/data/eternal_starlight/loot_table/entities/thirst_walker.json +++ b/common/src/generated/resources/data/eternal_starlight/loot_table/entities/thirst_walker.json @@ -5,7 +5,7 @@ "bonus_rolls": 0.0, "conditions": [ { - "chance": 0.4, + "chance": 0.6, "condition": "minecraft:random_chance" } ], @@ -36,6 +36,42 @@ } ], "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "chance": 0.2, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 2.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + }, + { + "count": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + }, + "enchantment": "minecraft:looting", + "function": "minecraft:enchanted_count_increase" + } + ], + "name": "eternal_starlight:seeking_eye" + } + ], + "rolls": 1.0 } ], "random_sequence": "eternal_starlight:entities/thirst_walker" diff --git a/common/src/generated/resources/data/minecraft/tags/entity_type/fall_damage_immune.json b/common/src/generated/resources/data/minecraft/tags/entity_type/fall_damage_immune.json index ba2349a2..3e79f9a3 100644 --- a/common/src/generated/resources/data/minecraft/tags/entity_type/fall_damage_immune.json +++ b/common/src/generated/resources/data/minecraft/tags/entity_type/fall_damage_immune.json @@ -5,6 +5,7 @@ "eternal_starlight:tiny_creteor", "eternal_starlight:crystallized_moth", "eternal_starlight:shimmer_lacewing", - "eternal_starlight:grimstone_golem" + "eternal_starlight:grimstone_golem", + "eternal_starlight:aethersent_golem" ] } \ No newline at end of file diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/block/CarvedLunarisCactusFruitBlock.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/block/CarvedLunarisCactusFruitBlock.java index e8b5a988..749f4915 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/block/CarvedLunarisCactusFruitBlock.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/block/CarvedLunarisCactusFruitBlock.java @@ -1,5 +1,6 @@ package cn.leolezury.eternalstarlight.common.block; +import cn.leolezury.eternalstarlight.common.entity.living.AethersentGolem; import cn.leolezury.eternalstarlight.common.entity.living.GrimstoneGolem; import cn.leolezury.eternalstarlight.common.registry.ESBlocks; import cn.leolezury.eternalstarlight.common.registry.ESEntities; @@ -44,6 +45,10 @@ public class CarvedLunarisCactusFruitBlock extends HorizontalDirectionalBlock { private BlockPattern grimstoneGolemBase; @Nullable private BlockPattern grimstoneGolemFull; + @Nullable + private BlockPattern aethersentGolemBase; + @Nullable + private BlockPattern aethersentGolemFull; private static final Predicate LUNARIS_CACTUS_FRUIT_PREDICATE = (state) -> state != null && (state.is(ESBlocks.CARVED_LUNARIS_CACTUS_FRUIT.get()) || state.is(ESBlocks.LUNARIS_CACTUS_FRUIT_LANTERN.get())); public CarvedLunarisCactusFruitBlock(Properties properties) { @@ -65,13 +70,14 @@ protected void onPlace(BlockState blockState, Level level, BlockPos blockPos, Bl } public boolean canSpawnGolem(LevelReader levelReader, BlockPos blockPos) { - return this.getOrCreateSnowGolemBase().find(levelReader, blockPos) != null || this.getOrCreateIronGolemBase().find(levelReader, blockPos) != null || this.getOrCreateGrimstoneGolemBase().find(levelReader, blockPos) != null; + return this.getOrCreateSnowGolemBase().find(levelReader, blockPos) != null || this.getOrCreateIronGolemBase().find(levelReader, blockPos) != null || this.getOrCreateGrimstoneGolemBase().find(levelReader, blockPos) != null || this.getOrCreateAethersentGolemBase().find(levelReader, blockPos) != null; } private void trySpawnGolem(Level level, BlockPos blockPos) { BlockPattern.BlockPatternMatch snowGolemMatch = this.getOrCreateSnowGolemFull().find(level, blockPos); BlockPattern.BlockPatternMatch ironGolemMatch = this.getOrCreateIronGolemFull().find(level, blockPos); BlockPattern.BlockPatternMatch grimstoneGolemMatch = this.getOrCreateGrimstoneGolemFull().find(level, blockPos); + BlockPattern.BlockPatternMatch aethersentGolemMatch = this.getOrCreateAethersentGolemFull().find(level, blockPos); if (snowGolemMatch != null) { SnowGolem snowGolem = EntityType.SNOW_GOLEM.create(level); if (snowGolem != null) { @@ -88,6 +94,11 @@ private void trySpawnGolem(Level level, BlockPos blockPos) { if (grimstoneGolem != null) { spawnGolemInWorld(level, grimstoneGolemMatch, grimstoneGolem, grimstoneGolemMatch.getBlock(0, 1, 0).getPos()); } + } else if (aethersentGolemMatch != null) { + AethersentGolem aethersentGolem = ESEntities.AETHERSENT_GOLEM.get().create(level); + if (aethersentGolem != null) { + spawnGolemInWorld(level, aethersentGolemMatch, aethersentGolem, aethersentGolemMatch.getBlock(0, 1, 0).getPos()); + } } } @@ -168,7 +179,7 @@ private BlockPattern getOrCreateIronGolemFull() { private BlockPattern getOrCreateGrimstoneGolemBase() { if (this.grimstoneGolemBase == null) { - this.grimstoneGolemBase = BlockPatternBuilder.start().aisle(" ", "#").where('#', BlockInWorld.hasState(BlockStatePredicate.forBlock(ESBlocks.GRIMSTONE_BRICKS.get()))).where('~', (blockInWorld) -> blockInWorld.getState().isAir()).build(); + this.grimstoneGolemBase = BlockPatternBuilder.start().aisle(" ", "#").where('#', BlockInWorld.hasState(BlockStatePredicate.forBlock(ESBlocks.GRIMSTONE_BRICKS.get()))).build(); } return this.grimstoneGolemBase; @@ -181,4 +192,20 @@ private BlockPattern getOrCreateGrimstoneGolemFull() { return this.grimstoneGolemFull; } + + private BlockPattern getOrCreateAethersentGolemBase() { + if (this.aethersentGolemBase == null) { + this.aethersentGolemBase = BlockPatternBuilder.start().aisle(" ", "#").where('#', BlockInWorld.hasState(BlockStatePredicate.forBlock(ESBlocks.AETHERSENT_BLOCK.get()))).build(); + } + + return this.aethersentGolemBase; + } + + private BlockPattern getOrCreateAethersentGolemFull() { + if (this.aethersentGolemFull == null) { + this.aethersentGolemFull = BlockPatternBuilder.start().aisle("^", "#").where('^', BlockInWorld.hasState(LUNARIS_CACTUS_FRUIT_PREDICATE)).where('#', BlockInWorld.hasState(BlockStatePredicate.forBlock(ESBlocks.AETHERSENT_BLOCK.get()))).build(); + } + + return this.aethersentGolemFull; + } } diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/client/handler/ClientSetupHandlers.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/handler/ClientSetupHandlers.java index 7713f965..82693ae1 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/client/handler/ClientSetupHandlers.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/handler/ClientSetupHandlers.java @@ -685,6 +685,7 @@ public static void registerEntityRenderers(EntityRendererRegisterStrategy strate strategy.register(ESEntities.CRYSTALLIZED_MOTH.get(), CrystallizedMothRenderer::new); strategy.register(ESEntities.SHIMMER_LACEWING.get(), ShimmerLacewingRenderer::new); strategy.register(ESEntities.GRIMSTONE_GOLEM.get(), GrimstoneGolemRenderer::new); + strategy.register(ESEntities.AETHERSENT_GOLEM.get(), AethersentGolemRenderer::new); strategy.register(ESEntities.TOWER_SQUID.get(), TowerSquidRenderer::new); strategy.register(ESEntities.LUMINOFISH.get(), LuminoFishRenderer::new); strategy.register(ESEntities.LUMINARIS.get(), LuminarisRenderer::new); @@ -766,6 +767,7 @@ public static void registerLayers(RendererLayerRegisterStrategy strategy) { strategy.register(CrystallizedMothModel.LAYER_LOCATION, CrystallizedMothModel::createBodyLayer); strategy.register(ShimmerLacewingModel.LAYER_LOCATION, ShimmerLacewingModel::createBodyLayer); strategy.register(GrimstoneGolemModel.LAYER_LOCATION, GrimstoneGolemModel::createBodyLayer); + strategy.register(AethersentGolemModel.LAYER_LOCATION, AethersentGolemModel::createBodyLayer); strategy.register(TowerSquidModel.LAYER_LOCATION, TowerSquidModel::createBodyLayer); strategy.register(LuminoFishModel.LAYER_LOCATION, LuminoFishModel::createBodyLayer); strategy.register(LuminarisModel.LAYER_LOCATION, LuminarisModel::createBodyLayer); diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/client/model/animation/definition/AethersentGolemAnimation.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/model/animation/definition/AethersentGolemAnimation.java new file mode 100644 index 00000000..5f507f8a --- /dev/null +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/model/animation/definition/AethersentGolemAnimation.java @@ -0,0 +1,60 @@ +package cn.leolezury.eternalstarlight.common.client.model.animation.definition; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.animation.AnimationChannel; +import net.minecraft.client.animation.AnimationDefinition; +import net.minecraft.client.animation.Keyframe; +import net.minecraft.client.animation.KeyframeAnimations; + +@Environment(EnvType.CLIENT) +public class AethersentGolemAnimation { + public static final AnimationDefinition SHOOT = AnimationDefinition.Builder.withLength(0.5F).looping() + .addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 90.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(-2.0F, -2.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.5F, 45.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("arms", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(-20.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("eye", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.0417F, KeyframeAnimations.posVec(-0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.0833F, KeyframeAnimations.posVec(0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.125F, KeyframeAnimations.posVec(-0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.1667F, KeyframeAnimations.posVec(0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.2083F, KeyframeAnimations.posVec(-0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.25F, KeyframeAnimations.posVec(0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.2917F, KeyframeAnimations.posVec(-0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.3333F, KeyframeAnimations.posVec(0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.375F, KeyframeAnimations.posVec(-0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.4167F, KeyframeAnimations.posVec(0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.4583F, KeyframeAnimations.posVec(-0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.5F, KeyframeAnimations.posVec(0.25F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .build(); + + public static final AnimationDefinition SHOOT_END = AnimationDefinition.Builder.withLength(1.0F) + .addAnimation("left_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.5F, 45.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(-90.0F, 0.0F, 90.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("right_arm", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(-2.0F, -2.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(1.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("arms", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(-20.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(1.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .build(); +} diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/client/model/entity/AethersentGolemModel.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/model/entity/AethersentGolemModel.java new file mode 100644 index 00000000..9742af7c --- /dev/null +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/model/entity/AethersentGolemModel.java @@ -0,0 +1,102 @@ +package cn.leolezury.eternalstarlight.common.client.model.entity; + +import cn.leolezury.eternalstarlight.common.EternalStarlight; +import cn.leolezury.eternalstarlight.common.client.model.animation.AnimatedEntityModel; +import cn.leolezury.eternalstarlight.common.client.model.animation.definition.AethersentGolemAnimation; +import cn.leolezury.eternalstarlight.common.entity.living.AethersentGolem; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; + +@Environment(EnvType.CLIENT) +public class AethersentGolemModel extends AnimatedEntityModel { + public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(EternalStarlight.id("aethersent_golem"), "main"); + private final ModelPart root; + private final ModelPart eye; + + public AethersentGolemModel(ModelPart root) { + this.root = root; + this.eye = root.getChild("head").getChild("eye"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition partdefinition = meshdefinition.getRoot(); + + PartDefinition head = partdefinition.addOrReplaceChild("head", CubeListBuilder.create().texOffs(0, 0).addBox(-7.0F, -8.0F, -1.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F)), PartPose.offset(3.0F, 12.0F, -3.0F)); + + head.addOrReplaceChild("eye", CubeListBuilder.create().texOffs(0, 0).addBox(-0.5F, -1.0F, 0.0F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(-3.0F, -3.25F, -1.05F)); + + PartDefinition leftAntenna = head.addOrReplaceChild("left_antenna", CubeListBuilder.create().texOffs(0, 16).mirror().addBox(0.0F, -1.5F, -1.5F, 2.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offset(1.0F, -3.5F, 2.5F)); + + leftAntenna.addOrReplaceChild("left_antenna_upper", CubeListBuilder.create().texOffs(0, 22).mirror().addBox(-0.5F, -4.0F, -1.0F, 1.0F, 4.0F, 2.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offset(0.5F, -1.5F, -0.5F)); + + PartDefinition rightAntenna = head.addOrReplaceChild("right_antenna", CubeListBuilder.create().texOffs(0, 16).addBox(-2.0F, -1.5F, -1.5F, 2.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(-7.0F, -3.5F, 2.5F)); + + rightAntenna.addOrReplaceChild("right_antenna_upper", CubeListBuilder.create().texOffs(0, 22).addBox(-0.5F, -4.0F, -1.0F, 1.0F, 4.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offset(-0.5F, -1.5F, -0.5F)); + + partdefinition.addOrReplaceChild("body", CubeListBuilder.create().texOffs(10, 16).addBox(-5.0F, -12.0F, -1.0F, 6.0F, 12.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offset(2.0F, 24.0F, -2.0F)); + + PartDefinition arms = partdefinition.addOrReplaceChild("arms", CubeListBuilder.create(), PartPose.offset(0.0F, 14.0F, 0.0F)); + + arms.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(34, 18).mirror().addBox(0.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offset(3.0F, 0.0F, 0.0F)); + + PartDefinition rightArm = arms.addOrReplaceChild("right_arm", CubeListBuilder.create().texOffs(34, 18).addBox(-4.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offset(-3.0F, 0.0F, 0.0F)); + + PartDefinition bow = rightArm.addOrReplaceChild("bow", CubeListBuilder.create(), PartPose.offsetAndRotation(-1.5F, 12.0F, 0.0F, 0.0F, 1.5708F, 0.0F)); + + PartDefinition lowerBow = bow.addOrReplaceChild("lower_bow", CubeListBuilder.create().texOffs(24, 34).addBox(-1.5F, -1.5F, -1.5F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-2.5F, -2.5F, -0.5F, 0.0F, 0.0F, 0.2138F)); + + lowerBow.addOrReplaceChild("lower_bow_body", CubeListBuilder.create().texOffs(8, 36).addBox(-6.0F, -2.0F, -1.0F, 6.0F, 2.0F, 2.0F, new CubeDeformation(0.0F)) + .texOffs(0, 34).addBox(-8.0F, -4.0F, -1.0F, 2.0F, 4.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-1.5F, 1.0F, 0.0F, 0.0F, 0.0F, 0.2138F)); + + lowerBow.addOrReplaceChild("lower_bow_tip", CubeListBuilder.create().texOffs(36, 36).addBox(0.0F, 0.0F, -0.5F, 2.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-1.0F, 1.5F, 0.0F, 0.0F, 0.0F, -0.2138F)); + + PartDefinition upperBow = bow.addOrReplaceChild("upper_bow", CubeListBuilder.create().texOffs(24, 34).mirror().addBox(-1.5F, -1.5F, -1.5F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(2.5F, -2.5F, -0.5F, 0.0F, 0.0F, -0.2138F)); + + upperBow.addOrReplaceChild("upper_bow_body", CubeListBuilder.create().texOffs(8, 36).mirror().addBox(0.0F, -2.0F, -1.0F, 6.0F, 2.0F, 2.0F, new CubeDeformation(0.0F)).mirror(false) + .texOffs(0, 34).mirror().addBox(6.0F, -4.0F, -1.0F, 2.0F, 4.0F, 2.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(1.5F, 1.0F, 0.0F, 0.0F, 0.0F, -0.2138F)); + + upperBow.addOrReplaceChild("upper_bow_tip", CubeListBuilder.create().texOffs(36, 36).mirror().addBox(-2.0F, 0.0F, -0.5F, 2.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)).mirror(false), PartPose.offsetAndRotation(1.0F, 1.5F, 0.0F, 0.0F, 0.0F, 0.2138F)); + + return LayerDefinition.create(meshdefinition, 64, 64); + } + + @Override + public void setupAnim(T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + this.root().getAllParts().forEach(ModelPart::resetPose); + animate(entity.shootAnimationState, AethersentGolemAnimation.SHOOT, ageInTicks); + animate(entity.shootEndAnimationState, AethersentGolemAnimation.SHOOT_END, ageInTicks); + // from GuardianModel + if (!entity.shootAnimationState.isStarted()) { + Entity camera = Minecraft.getInstance().getCameraEntity(); + if (camera != null) { + Vec3 targetEyePos = camera.getEyePosition(0.0F); + Vec3 yetiEyePos = entity.getEyePosition(0.0F); + if (targetEyePos.y > yetiEyePos.y) { + this.eye.y += -1.0F; + } else { + this.eye.y += 0.0F; + } + + Vec3 vec33 = entity.getViewVector(0.0F); + vec33 = new Vec3(vec33.x, 0.0, vec33.z); + Vec3 vec34 = (new Vec3(yetiEyePos.x - targetEyePos.x, 0.0, yetiEyePos.z - targetEyePos.z)).normalize().yRot(1.5707964F); + double e = vec33.dot(vec34); + this.eye.x += Mth.sqrt((float) Math.abs(e)) * 2.0F * (float) Math.signum(e); + } + } + } + + @Override + public ModelPart root() { + return root; + } +} diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/client/renderer/entity/AethersentGolemRenderer.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/renderer/entity/AethersentGolemRenderer.java new file mode 100644 index 00000000..e18c4ee2 --- /dev/null +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/client/renderer/entity/AethersentGolemRenderer.java @@ -0,0 +1,24 @@ +package cn.leolezury.eternalstarlight.common.client.renderer.entity; + +import cn.leolezury.eternalstarlight.common.EternalStarlight; +import cn.leolezury.eternalstarlight.common.client.model.entity.AethersentGolemModel; +import cn.leolezury.eternalstarlight.common.entity.living.AethersentGolem; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; + +@Environment(EnvType.CLIENT) +public class AethersentGolemRenderer extends MobRenderer> { + private static final ResourceLocation ENTITY_TEXTURE = EternalStarlight.id("textures/entity/aethersent_golem.png"); + + public AethersentGolemRenderer(EntityRendererProvider.Context context) { + super(context, new AethersentGolemModel<>(context.bakeLayer(AethersentGolemModel.LAYER_LOCATION)), 0.3f); + } + + @Override + public ResourceLocation getTextureLocation(T entity) { + return ENTITY_TEXTURE; + } +} diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/config/ESConfig.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/config/ESConfig.java index 2693eb4d..7efb316f 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/config/ESConfig.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/config/ESConfig.java @@ -39,6 +39,7 @@ public static class MobsConfig { public final AttackingMobConfig crystallizedMoth = new AttackingMobConfig(20, 0, 1.5, 64, true); public final MobConfig shimmerLacewing = new MobConfig(20, 0, true); public final MobConfig grimstoneGolem = new MobConfig(20, 0, true); + public final MobConfig aethersentGolem = new MobConfig(50, 10, true); public final AttackingMobConfig luminoFish = new AttackingMobConfig(3, 0, 3, 16, true); public final AttackingMobConfig luminaris = new AttackingMobConfig(3, 0, 3, 64, true); public final AttackingMobConfig twilightGaze = new AttackingMobConfig(10, 0, 3, 16, true); diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/living/AethersentGolem.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/living/AethersentGolem.java new file mode 100644 index 00000000..e576d101 --- /dev/null +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/living/AethersentGolem.java @@ -0,0 +1,78 @@ +package cn.leolezury.eternalstarlight.common.entity.living; + +import cn.leolezury.eternalstarlight.common.config.ESConfig; +import cn.leolezury.eternalstarlight.common.entity.projectile.AethersentMeteor; +import cn.leolezury.eternalstarlight.common.network.ParticlePacket; +import cn.leolezury.eternalstarlight.common.particle.ExplosionShockParticleOptions; +import cn.leolezury.eternalstarlight.common.platform.ESPlatform; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.*; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; + +import java.util.List; + +public class AethersentGolem extends Mob { + public final AnimationState shootAnimationState = new AnimationState(); + public final AnimationState shootEndAnimationState = new AnimationState(); + + public AethersentGolem(EntityType type, Level level) { + super(type, level); + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes() + .add(Attributes.MAX_HEALTH, ESConfig.INSTANCE.mobsConfig.aethersentGolem.maxHealth()) + .add(Attributes.ARMOR, ESConfig.INSTANCE.mobsConfig.aethersentGolem.armor()) + .add(Attributes.KNOCKBACK_RESISTANCE, 1) + .add(Attributes.MOVEMENT_SPEED, 0); + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new FloatGoal(this)); + } + + public void stopAllAnimStates() { + shootAnimationState.stop(); + shootEndAnimationState.stop(); + } + + @Override + public void handleEntityEvent(byte b) { + if (b == 100) { + stopAllAnimStates(); + shootAnimationState.start(tickCount); + } else { + super.handleEntityEvent(b); + } + } + + @Override + public void tick() { + super.tick(); + if (!level().isClientSide) { + if (tickCount % 5 == 0) { + List meteors = level().getEntitiesOfClass(AethersentMeteor.class, getBoundingBox().inflate(40)).stream().filter(AethersentMeteor::isNatural).toList(); + if (!meteors.isEmpty()) { + level().broadcastEntityEvent(this, (byte) 100); + meteors.forEach(meteor -> meteor.dropAndDiscard(true)); + if (level() instanceof ServerLevel serverLevel) { + for (int i = 0; i < 25; i++) { + Vec3 speed = new Vec3((this.random.nextFloat() - this.random.nextFloat()) * 0.1F, this.random.nextFloat() * 0.05F, (this.random.nextFloat() - this.random.nextFloat()) * 0.1F).normalize(); + ESPlatform.INSTANCE.sendToAllClients(serverLevel, new ParticlePacket(ExplosionShockParticleOptions.AETHERSENT, position().x + speed.x * 1.2, position().y + speed.y * 1.2, position().z + speed.z * 1.2, speed.x, speed.y, speed.z)); + } + } + } + } + } else { + if (shootAnimationState.isStarted() && (shootAnimationState.getAccumulatedTime() / 1000f) * 20f > 40) { + shootAnimationState.stop(); + shootEndAnimationState.start(tickCount); + } + } + } +} diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/living/GrimstoneGolem.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/living/GrimstoneGolem.java index 6d44810a..50838766 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/living/GrimstoneGolem.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/living/GrimstoneGolem.java @@ -25,8 +25,8 @@ public class GrimstoneGolem extends PathfinderMob { public final AnimationState displayAnimationState = new AnimationState(); public final AnimationState lowerArmsAnimationState = new AnimationState(); - public GrimstoneGolem(EntityType entityType, Level level) { - super(entityType, level); + public GrimstoneGolem(EntityType type, Level level) { + super(type, level); } public static AttributeSupplier.Builder createAttributes() { @@ -133,8 +133,4 @@ public void tick() { } } } - - public static boolean checkGolemSpawnRules(EntityType type, LevelAccessor level, MobSpawnType spawnType, BlockPos pos, RandomSource random) { - return !level.canSeeSky(pos) && pos.getY() < level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, pos.getX(), pos.getZ()) - 20 && level.getBlockState(pos.below()).is(ESTags.Blocks.BASE_STONE_STARLIGHT) && ESConfig.INSTANCE.mobsConfig.grimstoneGolem.canSpawn(); - } } diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/projectile/AethersentMeteor.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/projectile/AethersentMeteor.java index c4189d5e..d2d1880f 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/projectile/AethersentMeteor.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/entity/projectile/AethersentMeteor.java @@ -6,6 +6,9 @@ import cn.leolezury.eternalstarlight.common.data.ESDamageTypes; import cn.leolezury.eternalstarlight.common.entity.interfaces.TrailOwner; import cn.leolezury.eternalstarlight.common.entity.living.monster.Creteor; +import cn.leolezury.eternalstarlight.common.network.ParticlePacket; +import cn.leolezury.eternalstarlight.common.particle.ExplosionShockParticleOptions; +import cn.leolezury.eternalstarlight.common.platform.ESPlatform; import cn.leolezury.eternalstarlight.common.registry.ESBlocks; import cn.leolezury.eternalstarlight.common.registry.ESEntities; import cn.leolezury.eternalstarlight.common.registry.ESItems; @@ -97,6 +100,10 @@ public void setOnlyHurtEnemy(boolean onlyHurtEnemy) { private boolean natural = true; + public boolean isNatural() { + return natural; + } + public AethersentMeteor(EntityType type, Level level) { super(type, level); } @@ -171,33 +178,40 @@ public void addAdditionalSaveData(CompoundTag compoundTag) { compoundTag.putBoolean(TAG_NATURAL, natural); } - private void dropAndDiscard() { + public void dropAndDiscard(boolean clean) { if (!isRemoved()) { if (!level().isClientSide) { if (natural && getSize() >= 10) { ItemEntity entity = spawnAtLocation(new ItemStack(ESItems.RAW_AETHERSENT.get(), random.nextInt(5, 9))); - for (int x = -3; x <= 3; x++) { - for (int y = -3; y <= 3; y++) { - for (int z = -3; z <= 3; z++) { - BlockPos pos = blockPosition().offset(x, y, z); - if (pos.distToCenterSqr(blockPosition().getCenter()) <= 3.5 && level().getBlockState(pos).is(ESTags.Blocks.AETHERSENT_METEOR_REPLACEABLES)) { - level().setBlockAndUpdate(pos, random.nextBoolean() ? ESBlocks.RAW_AETHERSENT_BLOCK.get().defaultBlockState() : ESBlocks.NEBULAITE.get().defaultBlockState()); - } - } - } - } if (entity != null) { entity.setGlowingTag(true); } - if (ESConfig.INSTANCE.mobsConfig.creteor.canSpawn() && random.nextFloat() < 0.7 && level().getEntitiesOfClass(Creteor.class, getBoundingBox().inflate(32)).isEmpty()) { - Creteor creteor = new Creteor(ESEntities.CRETEOR.get(), level()); - creteor.setPos(position()); - creteor.setPersistenceRequired(); - level().addFreshEntity(creteor); - } - for (int m = 0; m < ((ServerLevel) level()).players().size(); ++m) { - ServerPlayer serverPlayer = ((ServerLevel) level()).players().get(m); - ((ServerLevel) level()).sendParticles(serverPlayer, ESParticles.AETHERSENT_EXPLOSION.get(), true, getX(), getY(), getZ(), 1, 0, 0, 0, 0); + if (!clean) { + for (int x = -3; x <= 3; x++) { + for (int y = -3; y <= 3; y++) { + for (int z = -3; z <= 3; z++) { + BlockPos pos = blockPosition().offset(x, y, z); + if (pos.distToCenterSqr(blockPosition().getCenter()) <= 3.5 && level().getBlockState(pos).is(ESTags.Blocks.AETHERSENT_METEOR_REPLACEABLES)) { + level().setBlockAndUpdate(pos, random.nextBoolean() ? ESBlocks.RAW_AETHERSENT_BLOCK.get().defaultBlockState() : ESBlocks.NEBULAITE.get().defaultBlockState()); + } + } + } + } + if (ESConfig.INSTANCE.mobsConfig.creteor.canSpawn() && random.nextFloat() < 0.7 && level().getEntitiesOfClass(Creteor.class, getBoundingBox().inflate(32)).isEmpty()) { + Creteor creteor = new Creteor(ESEntities.CRETEOR.get(), level()); + creteor.setPos(position()); + creteor.setPersistenceRequired(); + level().addFreshEntity(creteor); + } + for (int m = 0; m < ((ServerLevel) level()).players().size(); ++m) { + ServerPlayer serverPlayer = ((ServerLevel) level()).players().get(m); + ((ServerLevel) level()).sendParticles(serverPlayer, ESParticles.AETHERSENT_EXPLOSION.get(), true, getX(), getY(), getZ(), 1, 0, 0, 0, 0); + } + } else if (level() instanceof ServerLevel serverLevel) { + for (int i = 0; i < 25; i++) { + Vec3 speed = new Vec3((this.random.nextFloat() - this.random.nextFloat()) * 0.1F, this.random.nextFloat() * 0.05F, (this.random.nextFloat() - this.random.nextFloat()) * 0.1F).normalize(); + ESPlatform.INSTANCE.sendToAllClients(serverLevel, new ParticlePacket(ExplosionShockParticleOptions.AETHERSENT, position().x + speed.x * 1.2, position().y + speed.y * 1.2, position().z + speed.z * 1.2, speed.x, speed.y, speed.z)); + } } } discard(); @@ -225,7 +239,7 @@ protected void onHit(HitResult hitResult) { discard(); } if (natural) { - dropAndDiscard(); + dropAndDiscard(false); } } diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/handler/CommonSetupHandlers.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/handler/CommonSetupHandlers.java index 2571c7e9..9d34aa60 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/handler/CommonSetupHandlers.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/handler/CommonSetupHandlers.java @@ -3,6 +3,7 @@ import cn.leolezury.eternalstarlight.common.EternalStarlight; import cn.leolezury.eternalstarlight.common.block.CarvedLunarisCactusFruitBlock; import cn.leolezury.eternalstarlight.common.command.ESCommand; +import cn.leolezury.eternalstarlight.common.entity.living.AethersentGolem; import cn.leolezury.eternalstarlight.common.entity.living.GrimstoneGolem; import cn.leolezury.eternalstarlight.common.entity.living.animal.*; import cn.leolezury.eternalstarlight.common.entity.living.boss.gatekeeper.TheGatekeeper; @@ -251,6 +252,7 @@ public static void createAttributes(EntityAttributeRegisterStrategy strategy) { strategy.register(ESEntities.CRYSTALLIZED_MOTH.get(), CrystallizedMoth.createAttributes().build()); strategy.register(ESEntities.SHIMMER_LACEWING.get(), ShimmerLacewing.createAttributes().build()); strategy.register(ESEntities.GRIMSTONE_GOLEM.get(), GrimstoneGolem.createAttributes().build()); + strategy.register(ESEntities.AETHERSENT_GOLEM.get(), AethersentGolem.createAttributes().build()); strategy.register(ESEntities.TOWER_SQUID.get(), Squid.createAttributes().build()); strategy.register(ESEntities.LUMINOFISH.get(), LuminoFish.createAttributes().build()); strategy.register(ESEntities.LUMINARIS.get(), Luminaris.createAttributes().build()); @@ -283,7 +285,8 @@ public static void registerSpawnPlacements(SpawnPlacementRegisterStrategy strate strategy.register(ESEntities.AURORA_DEER.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, AuroraDeer::checkAuroraDeerSpawnRules); strategy.register(ESEntities.CRYSTALLIZED_MOTH.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, CrystallizedMoth::checkMothSpawnRules); strategy.register(ESEntities.SHIMMER_LACEWING.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, ShimmerLacewing::checkLacewingSpawnRules); - strategy.register(ESEntities.GRIMSTONE_GOLEM.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, GrimstoneGolem::checkGolemSpawnRules); + strategy.register(ESEntities.GRIMSTONE_GOLEM.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, Mob::checkMobSpawnRules); + strategy.register(ESEntities.AETHERSENT_GOLEM.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, Mob::checkMobSpawnRules); strategy.register(ESEntities.TOWER_SQUID.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, TowerSquid::checkTowerSquidSpawnRules); strategy.register(ESEntities.LUMINOFISH.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, LuminoFish::checkLuminoFishSpawnRules); strategy.register(ESEntities.LUMINARIS.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, Luminaris::checkLuminarisSpawnRules); diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESEntities.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESEntities.java index 9f56aea7..2a69ffd0 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESEntities.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESEntities.java @@ -5,6 +5,7 @@ import cn.leolezury.eternalstarlight.common.entity.attack.LunarThorn; import cn.leolezury.eternalstarlight.common.entity.attack.ray.GolemLaserBeam; import cn.leolezury.eternalstarlight.common.entity.attack.ray.LunarMonstrosityBreath; +import cn.leolezury.eternalstarlight.common.entity.living.AethersentGolem; import cn.leolezury.eternalstarlight.common.entity.living.GrimstoneGolem; import cn.leolezury.eternalstarlight.common.entity.living.animal.*; import cn.leolezury.eternalstarlight.common.entity.living.boss.gatekeeper.TheGatekeeper; @@ -204,6 +205,13 @@ public class ESEntities { .clientTrackingRange(8) .build(EternalStarlight.id("grimstone_golem").toString()) ); + public static final RegistryObject, EntityType> AETHERSENT_GOLEM = ENTITIES.register( + "aethersent_golem", + () -> EntityType.Builder.of(AethersentGolem::new, MobCategory.CREATURE) + .sized(0.5F, 1.25F) + .clientTrackingRange(8) + .build(EternalStarlight.id("aethersent_golem").toString()) + ); public static final RegistryObject, EntityType> TOWER_SQUID = ENTITIES.register( "tower_squid", () -> EntityType.Builder.of(TowerSquid::new, MobCategory.WATER_CREATURE) diff --git a/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESItems.java b/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESItems.java index 45f99e90..3505de04 100644 --- a/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESItems.java +++ b/common/src/main/java/cn/leolezury/eternalstarlight/common/registry/ESItems.java @@ -58,6 +58,7 @@ private static RegistryObject registerItem(String name, Supplier CRYSTALLIZED_MOTH_SPAWN_EGG = registerItem("crystallized_moth_spawn_egg", () -> ESPlatform.INSTANCE.createSpawnEgg(ESEntities.CRYSTALLIZED_MOTH::get, 0x361d20, 0xff5cbb, new Item.Properties())); public static final RegistryObject SHIMMER_LACEWING_SPAWN_EGG = registerItem("shimmer_lacewing_spawn_egg", () -> ESPlatform.INSTANCE.createSpawnEgg(ESEntities.SHIMMER_LACEWING::get, 0x061d85, 0x15c3cd, new Item.Properties())); public static final RegistryObject GRIMSTONE_GOLEM_SPAWN_EGG = registerItem("grimstone_golem_spawn_egg", () -> ESPlatform.INSTANCE.createSpawnEgg(ESEntities.GRIMSTONE_GOLEM::get, 0x51525c, 0xf7a2ff, new Item.Properties())); + public static final RegistryObject AETHERSENT_GOLEM_SPAWN_EGG = registerItem("aethersent_golem_spawn_egg", () -> ESPlatform.INSTANCE.createSpawnEgg(ESEntities.AETHERSENT_GOLEM::get, 0x53235b, 0xffffff, new Item.Properties())); public static final RegistryObject TOWER_SQUID_SPAWN_EGG = registerItem("tower_squid_spawn_egg", () -> ESPlatform.INSTANCE.createSpawnEgg(ESEntities.TOWER_SQUID::get, 0x1d2223, 0x55605a, new Item.Properties())); public static final RegistryObject LUMINOFISH_SPAWN_EGG = registerItem("luminofish_spawn_egg", () -> ESPlatform.INSTANCE.createSpawnEgg(ESEntities.LUMINOFISH::get, 0x35293a, 0xf1ffc8, new Item.Properties())); public static final RegistryObject LUMINARIS_SPAWN_EGG = registerItem("luminaris_spawn_egg", () -> ESPlatform.INSTANCE.createSpawnEgg(ESEntities.LUMINARIS::get, 0x3e3a46, 0x91807c, new Item.Properties())); diff --git a/common/src/main/resources/assets/eternal_starlight/lang/en_us.json b/common/src/main/resources/assets/eternal_starlight/lang/en_us.json index 8f353782..34e64e56 100644 --- a/common/src/main/resources/assets/eternal_starlight/lang/en_us.json +++ b/common/src/main/resources/assets/eternal_starlight/lang/en_us.json @@ -645,6 +645,7 @@ "item.eternal_starlight.crystallized_moth_spawn_egg": "Crystallized Moth Spawn Egg", "item.eternal_starlight.shimmer_lacewing_spawn_egg": "Shimmer Lacewing Spawn Egg", "item.eternal_starlight.grimstone_golem_spawn_egg": "Grimstone Golem Spawn Egg", + "item.eternal_starlight.aethersent_golem_spawn_egg": "Aethersent Golem Spawn Egg", "item.eternal_starlight.tower_squid_spawn_egg": "Tower Squid Spawn Egg", "item.eternal_starlight.luminofish_spawn_egg": "Luminofish Spawn Egg", "item.eternal_starlight.luminaris_spawn_egg": "Luminaris Spawn Egg", @@ -907,6 +908,7 @@ "entity.eternal_starlight.crystallized_moth": "Crystallized Moth", "entity.eternal_starlight.shimmer_lacewing": "Shimmer Lacewing", "entity.eternal_starlight.grimstone_golem": "Grimstone Golem", + "entity.eternal_starlight.aethersent_golem": "Aethersent Golem", "entity.eternal_starlight.tower_squid": "Tower Squid", "entity.eternal_starlight.luminofish": "Luminofish", "entity.eternal_starlight.luminaris": "Luminaris", @@ -1059,6 +1061,8 @@ "advancements.eternal_starlight.witness_meteor_shower.description": "Witness a meteor shower", "advancements.eternal_starlight.obtain_aethersent_ingot.title": "Gift from the Sky", "advancements.eternal_starlight.obtain_aethersent_ingot.description": "Obtain an Aethersent Ingot", + "advancements.eternal_starlight.summon_aethersent_golem.title": "Planetary Protection Policy", + "advancements.eternal_starlight.summon_aethersent_golem.description": "Summon an Aethersent Golem by putting a Carved Lunaris Cactus Fruit on a Aethersent Block", "advancements.eternal_starlight.kill_creteor.title": "C'mon TARS!", "advancements.eternal_starlight.kill_creteor.description": "Defeat a Creteor, which falls from the sky during the meteor shower", "advancements.eternal_starlight.obtain_aetherstrike_rocket.title": "Cosmic Rainmaker", diff --git a/common/src/main/resources/assets/eternal_starlight/lang/ja_jp.json b/common/src/main/resources/assets/eternal_starlight/lang/ja_jp.json index 05623fe9..67e28f1d 100644 --- a/common/src/main/resources/assets/eternal_starlight/lang/ja_jp.json +++ b/common/src/main/resources/assets/eternal_starlight/lang/ja_jp.json @@ -645,6 +645,7 @@ "item.eternal_starlight.crystallized_moth_spawn_egg": "ケッショウガのスポーンエッグ", "item.eternal_starlight.shimmer_lacewing_spawn_egg": "ヒカリカゲロウのスポーンエッグ", "item.eternal_starlight.grimstone_golem_spawn_egg": "グリムストーンゴーレムのスポーンエッグ", + "item.eternal_starlight.aethersent_golem_spawn_egg": "Aethersent Golem Spawn Egg", "item.eternal_starlight.tower_squid_spawn_egg": "トウイカのスポーンエッグ", "item.eternal_starlight.luminofish_spawn_egg": "ルミノフィッシュのスポーンエッグ", "item.eternal_starlight.luminaris_spawn_egg": "ルミナリスのスポーンエッグ", @@ -907,6 +908,7 @@ "entity.eternal_starlight.crystallized_moth": "ケッショウガ", "entity.eternal_starlight.shimmer_lacewing": "ヒカリカゲロウ", "entity.eternal_starlight.grimstone_golem": "グリムストーンゴーレム", + "entity.eternal_starlight.aethersent_golem": "Aethersent Golem", "entity.eternal_starlight.tower_squid": "トウイカ", "entity.eternal_starlight.luminofish": "ルミノフィッシュ", "entity.eternal_starlight.luminaris": "ルミナリス", @@ -1059,6 +1061,8 @@ "advancements.eternal_starlight.witness_meteor_shower.description": "流星雨を目撃する", "advancements.eternal_starlight.obtain_aethersent_ingot.title": "空からの贈り物", "advancements.eternal_starlight.obtain_aethersent_ingot.description": "エーテルセントインゴットを手に入れる", + "advancements.eternal_starlight.summon_aethersent_golem.title": "Planetary Protection Policy", + "advancements.eternal_starlight.summon_aethersent_golem.description": "Summon an Aethersent Golem by putting a Carved Lunaris Cactus Fruit on a Aethersent Block", "advancements.eternal_starlight.kill_creteor.title": "どうだ、TARS!", "advancements.eternal_starlight.kill_creteor.description": "流星と共に落ちてくるクリーテオを倒す", "advancements.eternal_starlight.obtain_aetherstrike_rocket.title": "流星雨乞い", diff --git a/common/src/main/resources/assets/eternal_starlight/lang/ru_ru.json b/common/src/main/resources/assets/eternal_starlight/lang/ru_ru.json index bd7d86de..318b45b3 100644 --- a/common/src/main/resources/assets/eternal_starlight/lang/ru_ru.json +++ b/common/src/main/resources/assets/eternal_starlight/lang/ru_ru.json @@ -645,6 +645,7 @@ "item.eternal_starlight.crystallized_moth_spawn_egg": "Яйцо призыва кристаллизованного мотылька", "item.eternal_starlight.shimmer_lacewing_spawn_egg": "Яйцо призыва мерцающей златоглазки", "item.eternal_starlight.grimstone_golem_spawn_egg": "Яйцо призыва мракокаменного голема", + "item.eternal_starlight.aethersent_golem_spawn_egg": "Aethersent Golem Spawn Egg", "item.eternal_starlight.tower_squid_spawn_egg": "Яйцо призыва башенного спрута", "item.eternal_starlight.luminofish_spawn_egg": "Яйцо призыва светорыбы", "item.eternal_starlight.luminaris_spawn_egg": "Яйцо призыва люминара", @@ -907,6 +908,7 @@ "entity.eternal_starlight.crystallized_moth": "Кристаллизованный мотылёк", "entity.eternal_starlight.shimmer_lacewing": "Мерцающая златоглазка", "entity.eternal_starlight.grimstone_golem": "Мракокаменный голем", + "entity.eternal_starlight.aethersent_golem": "Aethersent Golem", "entity.eternal_starlight.tower_squid": "Башенный спрут", "entity.eternal_starlight.luminofish": "Светорыба", "entity.eternal_starlight.luminaris": "Люминар", @@ -1059,6 +1061,8 @@ "advancements.eternal_starlight.witness_meteor_shower.description": "Станьте свидетелем метеоритного дождя", "advancements.eternal_starlight.obtain_aethersent_ingot.title": "Подарок с небес", "advancements.eternal_starlight.obtain_aethersent_ingot.description": "Получите эфиросцентный слиток", + "advancements.eternal_starlight.summon_aethersent_golem.title": "Planetary Protection Policy", + "advancements.eternal_starlight.summon_aethersent_golem.description": "Summon an Aethersent Golem by putting a Carved Lunaris Cactus Fruit on a Aethersent Block", "advancements.eternal_starlight.kill_creteor.title": "Давай, ТАРС!", "advancements.eternal_starlight.kill_creteor.description": "Победите метеорипера, который падает с неба во время метеоритного дождя", "advancements.eternal_starlight.obtain_aetherstrike_rocket.title": "Космический дождь", diff --git a/common/src/main/resources/assets/eternal_starlight/lang/zh_cn.json b/common/src/main/resources/assets/eternal_starlight/lang/zh_cn.json index 6d75d7c5..e9a33744 100644 --- a/common/src/main/resources/assets/eternal_starlight/lang/zh_cn.json +++ b/common/src/main/resources/assets/eternal_starlight/lang/zh_cn.json @@ -645,6 +645,7 @@ "item.eternal_starlight.crystallized_moth_spawn_egg": "晶化蛾刷怪蛋", "item.eternal_starlight.shimmer_lacewing_spawn_egg": "光羽蛉刷怪蛋", "item.eternal_starlight.grimstone_golem_spawn_egg": "阴沉石傀儡刷怪蛋", + "item.eternal_starlight.aethersent_golem_spawn_egg": "天赐傀儡刷怪蛋", "item.eternal_starlight.tower_squid_spawn_egg": "高塔乌贼刷怪蛋", "item.eternal_starlight.luminofish_spawn_egg": "光鲀刷怪蛋", "item.eternal_starlight.luminaris_spawn_egg": "光角食人鱼刷怪蛋", @@ -907,6 +908,7 @@ "entity.eternal_starlight.crystallized_moth": "晶化蛾", "entity.eternal_starlight.shimmer_lacewing": "光羽蛉", "entity.eternal_starlight.grimstone_golem": "阴沉石傀儡", + "entity.eternal_starlight.aethersent_golem": "天赐傀儡", "entity.eternal_starlight.tower_squid": "高塔乌贼", "entity.eternal_starlight.luminofish": "光鲀", "entity.eternal_starlight.luminaris": "光角食人鱼", @@ -1059,6 +1061,8 @@ "advancements.eternal_starlight.witness_meteor_shower.description": "目睹流星雨", "advancements.eternal_starlight.obtain_aethersent_ingot.title": "天赐良机", "advancements.eternal_starlight.obtain_aethersent_ingot.description": "获得天赐锭", + "advancements.eternal_starlight.summon_aethersent_golem.title": "行星保护政策", + "advancements.eternal_starlight.summon_aethersent_golem.description": "通过在天赐块上放置一个雕刻月螟仙人掌果实召唤一个天赐傀儡", "advancements.eternal_starlight.kill_creteor.title": "加把劲,TARS!", "advancements.eternal_starlight.kill_creteor.description": "杀死一个在流星雨期间生成的苦彗怕", "advancements.eternal_starlight.obtain_aetherstrike_rocket.title": "呼星唤雨", diff --git a/common/src/main/resources/assets/eternal_starlight/textures/block/starlight_seagrass.png b/common/src/main/resources/assets/eternal_starlight/textures/block/starlight_seagrass.png index 45bbb954..d93dbbb7 100644 Binary files a/common/src/main/resources/assets/eternal_starlight/textures/block/starlight_seagrass.png and b/common/src/main/resources/assets/eternal_starlight/textures/block/starlight_seagrass.png differ diff --git a/common/src/main/resources/assets/eternal_starlight/textures/entity/aethersent_golem.png b/common/src/main/resources/assets/eternal_starlight/textures/entity/aethersent_golem.png new file mode 100644 index 00000000..25c3897e Binary files /dev/null and b/common/src/main/resources/assets/eternal_starlight/textures/entity/aethersent_golem.png differ diff --git a/common/src/main/resources/assets/eternal_starlight/textures/item/starlight_seagrass.png b/common/src/main/resources/assets/eternal_starlight/textures/item/starlight_seagrass.png index c80661c0..ba1d04f9 100644 Binary files a/common/src/main/resources/assets/eternal_starlight/textures/item/starlight_seagrass.png and b/common/src/main/resources/assets/eternal_starlight/textures/item/starlight_seagrass.png differ diff --git a/neoforge/src/main/java/cn/leolezury/eternalstarlight/neoforge/datagen/provider/advancement/ESAdvancementGenerator.java b/neoforge/src/main/java/cn/leolezury/eternalstarlight/neoforge/datagen/provider/advancement/ESAdvancementGenerator.java index 189d1d79..20607cc2 100644 --- a/neoforge/src/main/java/cn/leolezury/eternalstarlight/neoforge/datagen/provider/advancement/ESAdvancementGenerator.java +++ b/neoforge/src/main/java/cn/leolezury/eternalstarlight/neoforge/datagen/provider/advancement/ESAdvancementGenerator.java @@ -152,6 +152,8 @@ public void generate(HolderLookup.Provider registries, Consumer