Enforcer WIP

This commit is contained in:
GearShocky 2025-03-11 00:22:14 +05:00
parent c323f70a97
commit d2371b03f6
15 changed files with 396 additions and 1 deletions

1
src/bb/enforcer.bbmodel Normal file

File diff suppressed because one or more lines are too long

View File

@ -127,6 +127,7 @@ fun addItemModels(provider: MatteryItemModelProvider) {
provider.generated(MItems.BREAD_MONSTER_SPAWN_EGG, modLocation("item/egg/bread_monster"))
provider.generated(MItems.LOADER_SPAWN_EGG, modLocation("item/egg/loader"))
provider.generated(MItems.CLEANER_DRONE_KIT, modLocation("item/egg/cleaner"))
provider.generated(MItems.ANDROID_MELEE_SPAWN_EGG, modLocation("item/egg/android_melee"))
provider.generatedTiered(MItems.BATTERIES, "battery_tier")

View File

@ -952,6 +952,9 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.LOADER_SPAWN_EGG, "Loader Spawn Egg")
add(MEntityTypes.LOADER, "Loader")
add(MItems.CLEANER_DRONE_KIT, "Cleaner Drone Kit")
add(MEntityTypes.CLEANER, "Cleaner Drone")
add(MItems.ANDROID_MELEE_SPAWN_EGG, "Melee Android Spawn Egg")
add(MEntityTypes.ANDROID_MELEE, "Melee Android")
}

View File

@ -945,6 +945,9 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.LOADER_SPAWN_EGG, "Яйцо призыва погрузчика")
add(MEntityTypes.LOADER, "Погрузчик")
add(MItems.CLEANER_DRONE_KIT, "Набор Дрона-уборщика")
add(MEntityTypes.CLEANER, "Дрон-уборщик")
add(MItems.ANDROID_MELEE_SPAWN_EGG, "Яйцо призыва андроида ближнего боя")
add(MEntityTypes.ANDROID_MELEE, "Андроид ближнего боя")
}

View File

@ -0,0 +1,36 @@
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 EnforcerAnimation {
public static final AnimationDefinition CHARGE = AnimationDefinition.Builder.withLength(0.0F).looping()
.addAnimation("root", new AnimationChannel(AnimationChannel.Targets.POSITION,
new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, -1.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("Body", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(7.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("leg_FL", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.3244F, 25.5371F, -4.9817F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("leg_FR", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.5426F, -23.0465F, 4.9996F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("leg_BR", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(-0.3244F, 25.5371F, 4.9817F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("leg_BL", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(-0.3244F, -25.5371F, -4.9817F), AnimationChannel.Interpolations.LINEAR)
))
.build();
public static final AnimationDefinition IDLE = AnimationDefinition.Builder.withLength(0.12F).looping()
.addAnimation("Body", new AnimationChannel(AnimationChannel.Targets.POSITION,
new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.12F, KeyframeAnimations.posVec(0.0F, -0.2F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.build();
}

View File

@ -0,0 +1,128 @@
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.EnforcerAnimation;
import ru.dbotthepony.mc.otm.client.animation.LoaderAnimation;
import ru.dbotthepony.mc.otm.entity.Enforcer;
import ru.dbotthepony.mc.otm.registry.MNames;
import static ru.dbotthepony.mc.otm.OverdriveThatMatters.loc;
public class EnforcerModel {
public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(loc(MNames.ENFORCER), "main");
private static HierarchicalModel<Enforcer> model;
private static LayerDefinition def;
public static HierarchicalModel<Enforcer> getModel() {
if (def == null) {
def = createBodyLayer();
}
if (model == null) {
return model = new EnforcerHierarchicalModel<>(def.bakeRoot());
}
return model;
}
public static LayerDefinition createBodyLayer() {
MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot();
PartDefinition root = partdefinition.addOrReplaceChild("root", CubeListBuilder.create(), PartPose.offset(0.0F, 25.0F, 0.0F));
PartDefinition cube_r1 = root.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(178, 168).addBox(0.0F, -18.5F, -1.0F, 0.0F, 19.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(8.0F, -41.5F, 8.0F, -0.1745F, 0.0F, 0.0F));
PartDefinition base = root.addOrReplaceChild("base", CubeListBuilder.create().texOffs(140, 104).addBox(-8.0F, -4.0F, -7.0F, 16.0F, 5.0F, 14.0F, new CubeDeformation(0.0F))
.texOffs(92, 33).addBox(-5.0F, -2.0F, -10.0F, 10.0F, 14.0F, 20.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -22.0F, 0.0F));
PartDefinition Body = base.addOrReplaceChild("Body", CubeListBuilder.create().texOffs(80, 76).addBox(-11.0F, -17.4F, 10.9F, 22.0F, 14.0F, 14.0F, new CubeDeformation(0.0F))
.texOffs(0, 0).addBox(-12.0F, -15.4F, -11.1F, 24.0F, 16.0F, 22.0F, new CubeDeformation(0.0F))
.texOffs(0, 38).addBox(-12.0F, -15.4F, -11.1F, 24.0F, 16.0F, 22.0F, new CubeDeformation(0.5F))
.texOffs(122, 168).addBox(12.0F, -13.4F, -6.1F, 2.0F, 12.0F, 12.0F, new CubeDeformation(0.0F))
.texOffs(150, 168).addBox(-14.0F, -13.4F, -6.1F, 2.0F, 12.0F, 12.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -4.6F, 0.1F));
PartDefinition Head = Body.addOrReplaceChild("Head", CubeListBuilder.create().texOffs(92, 67).addBox(-4.0F, -3.0F, -1.0F, 7.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(-4.0F, 1.6F, -11.1F));
PartDefinition rocket = Body.addOrReplaceChild("rocket", CubeListBuilder.create().texOffs(0, 76).addBox(-12.0F, -10.5F, -14.0F, 12.0F, 21.0F, 28.0F, new CubeDeformation(0.0F)), PartPose.offset(-14.0F, -7.9F, -0.1F));
PartDefinition flamethrower = Body.addOrReplaceChild("flamethrower", CubeListBuilder.create().texOffs(44, 168).addBox(-0.25F, -5.2654F, -4.9728F, 10.0F, 10.0F, 10.0F, new CubeDeformation(0.0F))
.texOffs(92, 0).addBox(2.75F, 1.7346F, -13.9728F, 10.0F, 10.0F, 23.0F, new CubeDeformation(0.0F))
.texOffs(84, 168).addBox(4.75F, 3.7346F, -26.9728F, 6.0F, 6.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offset(14.25F, -7.1346F, -0.1272F));
PartDefinition cube_r2 = flamethrower.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(152, 33).addBox(-4.0F, -4.0F, 0.5F, 8.0F, 8.0F, 15.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(7.75F, 5.7346F, 6.5272F, 0.5236F, 0.0F, 0.0F));
PartDefinition leg_FL = root.addOrReplaceChild("leg_FL", CubeListBuilder.create().texOffs(158, 0).addBox(-4.5F, -5.5F, -9.5F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F))
.texOffs(80, 104).addBox(-5.5F, -2.5F, -24.5F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(9.5F, -13.5F, -6.5F, 0.1047F, -0.5061F, -0.0349F));
PartDefinition leg_FR = root.addOrReplaceChild("leg_FR", CubeListBuilder.create().texOffs(0, 125).addBox(-5.5F, -2.5F, -24.5F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F))
.texOffs(152, 80).addBox(-4.5F, -5.5F, -9.5F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-9.5F, -13.5F, -6.5F, 0.1047F, 0.5061F, 0.0349F));
PartDefinition leg_BL = root.addOrReplaceChild("leg_BL", CubeListBuilder.create().texOffs(60, 136).addBox(-5.5F, -2.1667F, 5.1667F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F))
.texOffs(199, 24).addBox(-4.5F, -7.1667F, 13.1667F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F))
.texOffs(0, 157).addBox(-4.5F, -5.1667F, -3.8333F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(9.5F, -13.8333F, 6.8333F, -0.1047F, 0.5061F, -0.0349F));
PartDefinition leg_BR = root.addOrReplaceChild("leg_BR", CubeListBuilder.create().texOffs(152, 56).addBox(-4.5F, -5.1667F, -3.1667F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F))
.texOffs(120, 136).addBox(-5.5F, -2.1667F, 5.8333F, 11.0F, 13.0F, 19.0F, new CubeDeformation(0.0F))
.texOffs(202, 0).addBox(-4.5F, -7.1667F, 13.8333F, 9.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-9.5F, -13.8333F, 6.1667F, -0.1047F, -0.5061F, 0.0349F));
model = null;
return def = LayerDefinition.create(meshdefinition, 256, 256);
}
private static class EnforcerHierarchicalModel<T extends Enforcer> extends HierarchicalModel<T> {
private final ModelPart root;
private final ModelPart base;
private final ModelPart Body;
private final ModelPart Head;
private final ModelPart rocket;
private final ModelPart flamethrower;
public EnforcerHierarchicalModel(ModelPart root) {
this.root = root.getChild("root");
this.base = this.root.getChild("base");
this.Body = this.base.getChild("Body");
this.Head = this.Body.getChild("Head");
this.rocket = this.Body.getChild("rocket");
this.flamethrower = this.Body.getChild("flamethrower");
}
@Override
public void setupAnim(@NotNull T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
this.root().getAllParts().forEach(ModelPart::resetPose);
this.Body.getChild("Head").xRot = headPitch * ((float) Math.PI / 180F);
this.base.getChild("Body").yRot = netHeadYaw * ((float) Math.PI / 180F);
this.Body.getChild("rocket").xRot = headPitch * ((float) Math.PI / 180F);
this.Body.getChild("flamethrower").xRot = headPitch * ((float) Math.PI / 180F);
//this.animate(entity.getChargeState(), EnforcerAnimation.CHARGE, ageInTicks, 1.0F);
this.animateWalk(EnforcerAnimation.CHARGE, limbSwing, limbSwingAmount, 0.8F, 2.5F);
this.animate(entity.getIdleState(), EnforcerAnimation.IDLE, ageInTicks, 1.0F);
}
public ModelPart getHead() {
return this.Body.getChild("Head");
}
@Override
public @NotNull ModelPart root() {
return this.root;
}
}
public static void register(EntityRenderersEvent.RegisterLayerDefinitions event) {
event.registerLayerDefinition(LAYER_LOCATION, EnforcerModel::createBodyLayer);
}
}

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.EnforcerModel
import ru.dbotthepony.mc.otm.entity.Enforcer
class EnforcerRenderer(context: EntityRendererProvider.Context)
: MobRenderer<Enforcer, HierarchicalModel<Enforcer>>(context, EnforcerModel.getModel(), 2.2f) {
override fun getTextureLocation(entity: Enforcer): ResourceLocation = TEXTURE_LOCATION
companion object {
private val TEXTURE_LOCATION = loc("textures/entity/enforcer.png")
}
}

View File

@ -1,5 +1,7 @@
package ru.dbotthepony.mc.otm.entity
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundEvents
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.AnimationState
@ -7,6 +9,7 @@ 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.RandomLookAroundGoal
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
import net.minecraft.world.entity.ai.navigation.PathNavigation
@ -21,6 +24,7 @@ class Cleaner(type: EntityType<Cleaner>, level: Level) : Monster(type, level) {
}
override fun registerGoals() {
goalSelector.addGoal(8, RandomLookAroundGoal(this))
goalSelector.addGoal(7, WaterAvoidingRandomStrollGoal(this, 0.8))
}
@ -38,6 +42,14 @@ class Cleaner(type: EntityType<Cleaner>, level: Level) : Monster(type, level) {
return false
}
override fun getHurtSound(damageSource: net.minecraft.world.damagesource.DamageSource): SoundEvent {
return SoundEvents.HEAVY_CORE_BREAK
}
override fun getDeathSound(): SoundEvent {
return SoundEvents.VAULT_BREAK
}
override fun mobInteract(player: Player, hand: InteractionHand): InteractionResult {
if (!this.level().isClientSide) {
player.startRiding(this)

View File

@ -0,0 +1,166 @@
package ru.dbotthepony.mc.otm.entity
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
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.*
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
import net.minecraft.world.entity.ai.navigation.PathNavigation
import net.minecraft.world.entity.monster.*
import net.minecraft.world.entity.npc.Villager
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
val idleState = AnimationState()
val chargeState = AnimationState()
init {
idleState.start(tickCount)
}
override fun registerGoals() {
goalSelector.addGoal(7, LookAtPlayerGoal(this, Player::class.java, 8f))
goalSelector.addGoal(3, NearestAttackableTargetGoal(this, LivingEntity::class.java, 10, true, true) { entity ->
entity is Player ||
entity is Villager ||
entity is AbstractIllager ||
entity is Zombie ||
entity is AbstractSkeleton
})
goalSelector.addGoal(2, RammingGoal(this))
targetSelector.addGoal(1, HurtByTargetGoal(this))
}
override fun createNavigation(level: Level): PathNavigation = GroundPathNavigation(this, level)
override fun isPushable(): Boolean {
return false
}
override fun getHurtSound(damageSource: net.minecraft.world.damagesource.DamageSource): SoundEvent {
return SoundEvents.HEAVY_CORE_BREAK
}
override fun getDeathSound(): SoundEvent {
return SoundEvents.VAULT_BREAK
}
//charge attack, could possibly leave a smoke trail too idk
class RammingGoal(private val mob: Enforcer) : Goal() {
private var target: LivingEntity? = null
private var chargeTime = 0
private val windupTime = 20
private val maxChargeTime = 40
private var chargeDir: Vec3? = null
private var cooldown = 0
private val minCooldown = 20
private val maxCooldown = 60
private var isCharging = false
override fun canUse(): Boolean {
if (cooldown > 0) {
cooldown--
return false
}
target = mob.target
return target != null
}
override fun canContinueToUse(): Boolean {
return isCharging && chargeTime < maxChargeTime
}
override fun start() {
mob.playSound(MSoundEvents.PLASMA_WEAPON_OVERHEAT, 1.0f, 1.0f)
chargeTime = 0
mob.navigation.stop()
cooldown = minCooldown + mob.random.nextInt(maxCooldown - minCooldown)
isCharging = true
mob.chargeState.start(mob.tickCount)
}
override fun tick() {
if (!isCharging) return
chargeTime++
val target = mob.target ?: return
if (chargeTime < windupTime) {
chargeDir = Vec3(target.x - mob.x, 0.0, target.z - mob.z).normalize()
mob.lookControl.setLookAt(target, 30.0f, 30.0f)
return
}
if (chargeTime == windupTime) {
if (chargeDir == null || chargeDir!!.length() < 0.1) {
stop()
return
}
mob.playSound(MSoundEvents.ANDROID_JUMP_BOOST, 1.0f, 1.0f)
}
val dir = chargeDir ?: return
mob.yRot = (-Mth.atan2(dir.x, dir.z) * (180f / Math.PI)).toFloat()
mob.yHeadRot = mob.yRot
mob.move(net.minecraft.world.entity.MoverType.SELF, dir.scale(1.2))
if (mob.horizontalCollision) {
mob.level().playSound(
null,
mob.x, mob.y, mob.z,
SoundEvents.GENERIC_EXPLODE,
SoundSource.HOSTILE,
1.0f,
1.0f
)
stop()
return
}
if (mob.boundingBox.intersects(target.boundingBox)) {
val knockbackStrength = 1.5
val knockback = dir.scale(knockbackStrength)
target.push(knockback.x, 0.5, knockback.z)
val damageAmount = 6.0f
target.hurt(mob.damageSources().mobAttack(mob), damageAmount)
stop()
}
}
override fun stop() {
mob.setDeltaMovement(Vec3.ZERO)
chargeTime = 0
chargeDir = null
isCharging = false
mob.chargeState.stop()
}
}
companion object {
fun createAttributes() : AttributeSupplier.Builder {
return createMonsterAttributes()
.add(Attributes.MAX_HEALTH, 300.0)
.add(Attributes.ARMOR, 10.0)
.add(Attributes.MOVEMENT_SPEED, 0.3)
.add(Attributes.STEP_HEIGHT, 1.0)
.add(Attributes.KNOCKBACK_RESISTANCE, 1.0)
}
}
}

View File

@ -208,6 +208,8 @@ object MNames {
const val BREAD_MONSTER_SPAWN_EGG = "bead_monster_spawn_egg"
const val LOADER_SPAWN_EGG = "loader_spawn_egg"
const val CLEANER_DRONE_KIT = "cleaner_drone_kit"
const val ANDROID_MELEE_SPAWN_EGG = "android_melee_spawn_egg"
// items: crafting components
@ -340,6 +342,8 @@ object MNames {
const val ANDROID_RANGED = "android_ranged"
const val ANDROID_OVERSEER = "android_overseer"
const val ENFORCER = "enforcer"
const val PHANTOM_ATTRACTOR = "phantom_attractor"
const val JUMP_BOOST = "jump_boost"
const val ENDER_TELEPORTER = "ender_teleporter"

View File

@ -16,6 +16,7 @@ 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.EnforcerRenderer
import ru.dbotthepony.mc.otm.client.render.entity.PlasmaProjectileRenderer
import ru.dbotthepony.mc.otm.client.render.entity.RogueAndroidRenderer
import ru.dbotthepony.mc.otm.entity.*
@ -77,6 +78,14 @@ object MEntityTypes {
.build(MNames.ANDROID_MELEE)
}
val ENFORCER: EntityType<Enforcer> by registry.register(MNames.ENFORCER) {
EntityType.Builder.of(::Enforcer, MobCategory.MONSTER)
.sized(2.4f, 2.5f)
.eyeHeight(2.0f)
.passengerAttachments(2.5f)
.clientTrackingRange(12)
.build(MNames.ENFORCER)
}
fun register(bus: IEventBus) {
registry.register(bus)
@ -90,6 +99,8 @@ object MEntityTypes {
event.put(ANDROID_MELEE, AndroidMelee.createAttributes().build())
event.put(ENFORCER, Enforcer.createAttributes().build())
event.put(CLEANER, Cleaner.createAttributes().build())
}
@ -108,6 +119,8 @@ object MEntityTypes {
EntityRenderers.register(CLEANER, ::CleanerRenderer)
EntityRenderers.register(ENFORCER, ::EnforcerRenderer)
EntityRenderers.register(ANDROID_MELEE) { context ->
RogueAndroidRenderer(context, ANDROID_MELEE, "melee",context.modelManager)
}

View File

@ -678,6 +678,9 @@ object MItems {
val BREAD_MONSTER_SPAWN_EGG: Item by registry.register(MNames.BREAD_MONSTER_SPAWN_EGG){ SpawnEggItem(MEntityTypes.BREAD_MONSTER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
val LOADER_SPAWN_EGG: Item by registry.register(MNames.LOADER_SPAWN_EGG){ SpawnEggItem(MEntityTypes.LOADER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
val CLEANER_DRONE_KIT: Item by registry.register(MNames.CLEANER_DRONE_KIT){ SpawnEggItem(MEntityTypes.CLEANER, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
val ANDROID_MELEE_SPAWN_EGG: Item by registry.register(MNames.ANDROID_MELEE_SPAWN_EGG){ SpawnEggItem(MEntityTypes.ANDROID_MELEE, 0xFFFFFF, 0xFFFFFF, Item.Properties())}
val ROFLITE_ALLOY_INGOT: Item by registry.register(MNames.ROFLITE_ALLOY_INGOT) { Item(DEFAULT_PROPERTIES) }

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

View File

@ -17,7 +17,14 @@
"spawn_overrides": {
"ambient": {
"bounding_box": "piece",
"spawns": []
"spawns": [
{
"type": "overdrive_that_matters:cleaner",
"maxCount": 1,
"minCount": 1,
"weight": 1
}
]
},
"monster": {
"bounding_box": "piece",