cleaner drone wip

This commit is contained in:
GearShocky 2025-03-09 19:55:42 +05:00
parent 4c282d51a8
commit 45ba5a6d55
17 changed files with 206 additions and 22 deletions

View File

@ -4,15 +4,18 @@ import net.minecraft.advancements.AdvancementHolder
import net.minecraft.advancements.AdvancementRewards
import net.minecraft.advancements.AdvancementRequirements.Strategy
import net.minecraft.advancements.AdvancementType
import net.minecraft.advancements.critereon.InventoryChangeTrigger
import net.minecraft.advancements.Criterion
import net.minecraft.advancements.critereon.*
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.datagen.lang.MatteryLanguageProvider
import ru.dbotthepony.mc.otm.datagen.modLocation
import ru.dbotthepony.mc.otm.registry.MItemTags
import ru.dbotthepony.mc.otm.registry.game.MItems
import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.registry.game.MEntityTypes
import ru.dbotthepony.mc.otm.triggers.BlackHoleTrigger
import ru.dbotthepony.mc.otm.triggers.NailedEntityTrigger
import java.util.function.Consumer

View File

@ -6,10 +6,7 @@ import net.minecraft.advancements.AdvancementRewards
import net.minecraft.advancements.AdvancementType
import net.minecraft.advancements.Criterion
import net.minecraft.advancements.DisplayInfo
import net.minecraft.advancements.critereon.ContextAwarePredicate
import net.minecraft.advancements.critereon.EntityPredicate
import net.minecraft.advancements.critereon.InventoryChangeTrigger
import net.minecraft.advancements.critereon.ItemPredicate
import net.minecraft.advancements.critereon.*
import net.minecraft.core.registries.Registries
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceKey

View File

@ -874,7 +874,7 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.FALLING_SUN, "desc2", "Deals extra damage to androids when empowered")
add(MItems.FALLING_SUN, "desc3", "Always strikes surrounding enemies with full damage if empowered")
add(MItems.FALLING_SUN, "desc4", "Does not benefit from Sweeping Edge enchantment")
add(MItems.FALLING_SUN, "desc5", "§oHas my judgement come so soon?")
add(MItems.FALLING_SUN, "desc5", "Has my judgement come so soon?")
add(MItems.PORTABLE_CONDENSATION_DRIVE, "Portable Condensation Drive")
add(MItems.PORTABLE_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive")

View File

@ -867,7 +867,7 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.FALLING_SUN, "desc2", "Наносит дополнительный урон андроидам если имеет заряд")
add(MItems.FALLING_SUN, "desc3", "Всегда наносит полный урон по площади если имеет заряд")
add(MItems.FALLING_SUN, "desc4", "Зачарование 'Разящий клинок' не имеет никакого эффекта на данном оружии")
add(MItems.FALLING_SUN, "desc5", "§oМой судный день пришел так скоро?")
add(MItems.FALLING_SUN, "desc5", "Мой судный день пришел так скоро?")
add(MItems.PORTABLE_CONDENSATION_DRIVE, "Portable Condensation Drive")
add(MItems.PORTABLE_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive")

View File

@ -0,0 +1,19 @@
package ru.dbotthepony.mc.otm.client.animation;
import net.minecraft.client.animation.AnimationChannel;
import net.minecraft.client.animation.AnimationDefinition;
import net.minecraft.client.animation.Keyframe;
import net.minecraft.client.animation.KeyframeAnimations;
public class CleanerAnimation {
public static final AnimationDefinition MOVE = AnimationDefinition.Builder.withLength(0.48F).looping()
.addAnimation("brushR", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.48F, KeyframeAnimations.degreeVec(0.0F, -360.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("brushL", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.48F, KeyframeAnimations.degreeVec(0.0F, 360.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.build();
}

View File

@ -0,0 +1,76 @@
package ru.dbotthepony.mc.otm.client.model.entity;
import net.minecraft.client.model.HierarchicalModel;
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.neoforged.neoforge.client.event.EntityRenderersEvent;
import org.jetbrains.annotations.NotNull;
import ru.dbotthepony.mc.otm.client.animation.BreadMonsterAnimation;
import ru.dbotthepony.mc.otm.client.animation.CleanerAnimation;
import ru.dbotthepony.mc.otm.entity.Cleaner;
import ru.dbotthepony.mc.otm.registry.MNames;
import static ru.dbotthepony.mc.otm.OverdriveThatMatters.loc;
public class CleanerModel {
public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(loc(MNames.CLEANER), "main");
private static HierarchicalModel<Cleaner> model;
private static LayerDefinition def;
public static HierarchicalModel<Cleaner> getModel() {
if (def == null) {
def = createBodyLayer();
}
if (model == null) {
return model = new CleanerHierarchicalModel<>(def.bakeRoot());
}
return model;
}
public static LayerDefinition createBodyLayer() {
MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot();
PartDefinition root = partdefinition.addOrReplaceChild("root", CubeListBuilder.create().texOffs(0, 0).addBox(-7.0F, -3.3F, -7.0F, 14.0F, 3.0F, 14.0F, new CubeDeformation(0.0F))
.texOffs(0, 17).addBox(-3.0F, -3.8F, 0.0F, 6.0F, 1.0F, 6.0F, new CubeDeformation(0.0F))
.texOffs(0, 7).addBox(-6.0F, -1.0F, 3.0F, 1.0F, 1.0F, 3.0F, new CubeDeformation(0.0F))
.texOffs(0, 7).addBox(5.0F, -1.0F, 3.0F, 1.0F, 1.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 24.0F, 0.0F));
PartDefinition brushR = root.addOrReplaceChild("brushR", CubeListBuilder.create(), PartPose.offset(-4.5F, -0.1F, -4.5F));
PartDefinition brushr_r1 = brushR.addOrReplaceChild("brushr_r1", CubeListBuilder.create().texOffs(7, 0).addBox(10.5F, -1.0F, -3.5F, -7.0F, 0.0F, 7.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(7.0F, -1.1F, 0.0F, 0.0F, 0.0F, -3.1416F));
PartDefinition brushL = root.addOrReplaceChild("brushL", CubeListBuilder.create().texOffs(-7, 0).addBox(-3.5F, -0.1F, -3.5F, 7.0F, 0.0F, 7.0F, new CubeDeformation(0.0F)), PartPose.offset(4.5F, -0.1F, -4.5F));
model = null;
return def = LayerDefinition.create(meshdefinition, 64, 32);
}
private static class CleanerHierarchicalModel<T extends Cleaner> extends HierarchicalModel<T> {
private final ModelPart root;
public CleanerHierarchicalModel(ModelPart root) {
this.root = root.getChild("root");
}
@Override
public void setupAnim(@NotNull T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
this.root().getAllParts().forEach(ModelPart::resetPose);
this.animate(entity.getIdleState(), CleanerAnimation.MOVE, ageInTicks, 1.0F);
}
@Override
public @NotNull ModelPart root() {
return this.root;
}
}
public static void register(EntityRenderersEvent.RegisterLayerDefinitions event) {
event.registerLayerDefinition(LAYER_LOCATION, CleanerModel::createBodyLayer);
}
}

View File

@ -21,7 +21,7 @@ public class LoaderModel {
public static HierarchicalModel<Loader> getModel() {
if (def == null) {
def = createBodyLayer(); // Ensure def is created before using it
def = createBodyLayer();
}
if (model == null) {

View File

@ -0,0 +1,18 @@
package ru.dbotthepony.mc.otm.client.render.entity
import net.minecraft.client.model.HierarchicalModel
import net.minecraft.client.renderer.entity.EntityRendererProvider
import net.minecraft.client.renderer.entity.MobRenderer
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.OverdriveThatMatters.loc
import ru.dbotthepony.mc.otm.client.model.entity.CleanerModel
import ru.dbotthepony.mc.otm.entity.Cleaner
class CleanerRenderer(context: EntityRendererProvider.Context)
: MobRenderer<Cleaner, HierarchicalModel<Cleaner>>(context, CleanerModel.getModel(), 0.5f) {
override fun getTextureLocation(entity: Cleaner): ResourceLocation = TEXTURE_LOCATION
companion object {
private val TEXTURE_LOCATION = loc("textures/entity/cleaner.png")
}
}

View File

@ -0,0 +1,56 @@
package ru.dbotthepony.mc.otm.entity
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.AnimationState
import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
import net.minecraft.world.entity.ai.navigation.PathNavigation
import net.minecraft.world.entity.monster.Monster
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level
class Cleaner(type: EntityType<Cleaner>, level: Level) : Monster(type, level) {
val idleState = AnimationState()
init {
idleState.start(tickCount)
}
override fun registerGoals() {
goalSelector.addGoal(7, WaterAvoidingRandomStrollGoal(this, 0.8))
}
override fun createNavigation(level: Level): PathNavigation = GroundPathNavigation(this, level)
override fun isPushable(): Boolean {
return false
}
override fun getControllingPassenger(): LivingEntity? {
return null
}
override fun isMultipartEntity(): Boolean {
return false
}
override fun mobInteract(player: Player, hand: InteractionHand): InteractionResult {
if (!this.level().isClientSide) {
player.startRiding(this)
return InteractionResult.SUCCESS
}
return InteractionResult.CONSUME
}
companion object {
fun createAttributes() : AttributeSupplier.Builder {
return createMonsterAttributes()
.add(Attributes.MAX_HEALTH, 4.0)
.add(Attributes.MOVEMENT_SPEED, 0.2)
}
}
}

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.item.weapon
import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos
import net.minecraft.core.component.DataComponents
import net.minecraft.tags.BlockTags
@ -130,7 +131,7 @@ class FallingSunItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.EPIC))
addSimpleDescription("2")
addSimpleDescription("3")
addSimpleDescription("4")
addSimpleDescription("5")
addSimpleDescription("5",ChatFormatting.ITALIC)
}
override fun mineBlock(

View File

@ -334,6 +334,7 @@ object MNames {
const val RIDEABLE_DUMMY = "rideable_dummy"
const val BREAD_MONSTER = "bread_monster"
const val LOADER = "loader"
const val CLEANER = "cleaner"
const val ANDROID_MELEE = "android_melee"
const val ANDROID_RANGED = "android_ranged"

View File

@ -15,6 +15,7 @@ import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent
import ru.dbotthepony.mc.otm.client.render.entity.BreadMonsterRenderer
import ru.dbotthepony.mc.otm.client.render.entity.LoaderRenderer
import ru.dbotthepony.mc.otm.client.render.entity.CleanerRenderer
import ru.dbotthepony.mc.otm.client.render.entity.PlasmaProjectileRenderer
import ru.dbotthepony.mc.otm.client.render.entity.RogueAndroidRenderer
import ru.dbotthepony.mc.otm.entity.*
@ -49,6 +50,15 @@ object MEntityTypes {
.build(MNames.BREAD_MONSTER)
}
val CLEANER: EntityType<Cleaner> by registry.register(MNames.CLEANER) {
EntityType.Builder.of(::Cleaner, MobCategory.AMBIENT)
.sized(0.9f, 0.225f)
.eyeHeight(0.1875f)
.passengerAttachments(0.225f)
.clientTrackingRange(8)
.build(MNames.CLEANER)
}
val LOADER: EntityType<Loader> by registry.register(MNames.LOADER) {
EntityType.Builder.of(::Loader, MobCategory.MONSTER)
.sized(1.2f, 2.5f)
@ -77,7 +87,10 @@ object MEntityTypes {
private fun registerAttributes(event: EntityAttributeCreationEvent) {
event.put(BREAD_MONSTER, BreadMonster.createAttributes().build())
event.put(LOADER, Loader.createAttributes().build())
event.put(ANDROID_MELEE, AndroidMelee.createAttributes().build())
event.put(CLEANER, Cleaner.createAttributes().build())
}
@Suppress("unchecked_cast")
@ -93,6 +106,8 @@ object MEntityTypes {
EntityRenderers.register(BREAD_MONSTER, ::BreadMonsterRenderer)
EntityRenderers.register(LOADER, ::LoaderRenderer)
EntityRenderers.register(CLEANER, ::CleanerRenderer)
EntityRenderers.register(ANDROID_MELEE) { context ->
RogueAndroidRenderer(context, ANDROID_MELEE, "melee",context.modelManager)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

View File

@ -1,34 +1,32 @@
{
"type": "minecraft:jigsaw",
"biomes": "#overdrive_that_matters:laboratory",
"dimension_padding": 10,
"max_distance_from_center": 80,
"liquid_settings": "ignore_waterlogging",
"size": 20,
"start_height": {
"type": "minecraft:biased_to_bottom",
"type": "minecraft:uniform",
"max_inclusive": {
"absolute": 0
"absolute": -20
},
"min_inclusive": {
"absolute": -16
"absolute": -40
}
},
"spawn_overrides": {
"ambient": {
"bounding_box": "piece",
"spawns": []
},
"monster": {
"bounding_box": "piece",
"spawns": [
{
"type": "overdrive_that_matters:android_melee",
"weight": 1,
"minCount": 1,
"maxCount": 2
}
]
"spawns": []
}
},
"start_jigsaw_name": "overdrive_that_matters:laboratory_anchor",
"start_pool": "overdrive_that_matters:laboratory/entrance",
"step": "underground_decoration",
"terrain_adaption": "encapsulate",
"step": "underground_structures",
"terrain_adaptation": "encapsulate",
"use_expansion_hack": false
}