mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-17 10:24:23 +01:00
Added a wip new mob
This commit is contained in:
parent
1305b972a5
commit
ec2242f22a
9 changed files with 471 additions and 0 deletions
1
assets/models/sombra.bbmodel
Normal file
1
assets/models/sombra.bbmodel
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/models/sombra.png
Normal file
BIN
assets/models/sombra.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -78,6 +78,7 @@ public interface URenderers {
|
|||
EntityRendererRegistry.register(UEntities.CAST_SPELL, CastSpellEntityRenderer::new);
|
||||
EntityRendererRegistry.register(UEntities.TWITTERMITE, FairyEntityRenderer::new);
|
||||
EntityRendererRegistry.register(UEntities.SPELLBOOK, SpellbookEntityRenderer::new);
|
||||
EntityRendererRegistry.register(UEntities.SOMBRA, SombraEntityRenderer::new);
|
||||
EntityRendererRegistry.register(UEntities.AIR_BALLOON, AirBalloonEntityRenderer::new);
|
||||
|
||||
BlockEntityRendererFactories.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new);
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
package com.minelittlepony.unicopia.client.render.entity;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.SombraEntity;
|
||||
|
||||
import net.minecraft.client.model.ModelData;
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.model.ModelPartBuilder;
|
||||
import net.minecraft.client.model.ModelPartData;
|
||||
import net.minecraft.client.model.ModelTransform;
|
||||
import net.minecraft.client.model.Dilation;
|
||||
import net.minecraft.client.model.TexturedModelData;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class SombraEntityModel extends EntityModel<SombraEntity> {
|
||||
|
||||
private final ModelPart part;
|
||||
|
||||
private final ModelPart head;
|
||||
private final ModelPart mane;
|
||||
private final ModelPart upperJaw;
|
||||
private final ModelPart lowerJaw;
|
||||
|
||||
private final ModelPart body;
|
||||
|
||||
public SombraEntityModel(ModelPart root) {
|
||||
this.part = root;
|
||||
this.head = root.getChild("head");
|
||||
this.mane = head.getChild("mane");
|
||||
this.upperJaw = head.getChild("upper_jaw");
|
||||
this.lowerJaw = head.getChild("lower_jaw");
|
||||
this.body = root.getChild("body");
|
||||
}
|
||||
|
||||
public static TexturedModelData getTexturedModelData() {
|
||||
ModelData data = new ModelData();
|
||||
ModelPartData root = data.getRoot();
|
||||
|
||||
ModelPartData neck = root.addChild("body", ModelPartBuilder.create(), ModelTransform.of(0, 20, 0, 0, 0, 0.0436F));
|
||||
neck.addChild("tail", ModelPartBuilder.create()
|
||||
.uv(50, 12).cuboid(3.0958F, -3.8679F, -1, 3, 7, 3, Dilation.NONE), ModelTransform.of(4, 3, -1, 0, 0, -1.0036F));
|
||||
neck.addChild("neck", ModelPartBuilder.create()
|
||||
.uv(32, 10).cuboid(2.0438F, -5.9668F, -3, 4, 7, 5, Dilation.NONE), ModelTransform.of(0, 0, 0, 0, 0, -0.6981F));
|
||||
|
||||
ModelPartData head = root.addChild("head", ModelPartBuilder.create()
|
||||
.uv(0, 0).cuboid(-5, -13, -4, 8, 8, 8, Dilation.NONE) // head
|
||||
.uv(0, 4).cuboid(1, -15, -4, 2, 2, 2, Dilation.NONE) // ear
|
||||
.uv(0, 4).cuboid(1, -15, 2, 2, 2, 2, Dilation.NONE) // ear
|
||||
, ModelTransform.pivot(0, 20, 0));
|
||||
|
||||
head.addChild("mane", ModelPartBuilder.create()
|
||||
.uv(32, 0).cuboid(-2.4982F, -6.1228F, -1.5F, 8, 7, 3, Dilation.NONE), ModelTransform.of(-1, -12, 0, 0, 0, 0.48F));
|
||||
|
||||
head.addChild("lower_jaw", ModelPartBuilder.create()
|
||||
.uv(32, 22).cuboid(-5, 0, -3, 7, 2, 6, Dilation.NONE), ModelTransform.of(-1, -3, 0, 0, 0, -0.5672F));
|
||||
head.addChild("upper_jaw", ModelPartBuilder.create()
|
||||
.uv(32, 30).cuboid(-5, -2, -3, 6, 2, 6, Dilation.NONE), ModelTransform.of(-4, -5, 0, 0, 0, -0.1745F));
|
||||
head.addChild("hair", ModelPartBuilder.create()
|
||||
.uv(0, 16).cuboid(-2, -8, -4, 8, 9, 8, new Dilation(0.25F)), ModelTransform.of(-3, -7.75F, 0, 0, 0, 0.0436F));
|
||||
|
||||
ModelPartData crown = head.addChild("crown", ModelPartBuilder.create()
|
||||
.uv(0, 16).cuboid(-2, -8, -4, 8, 3, 8, new Dilation(0.5F))
|
||||
.uv(1, 1).cuboid(-3, -6, -0.75F, 1, 1, 1, Dilation.NONE), ModelTransform.of(-4, -8.75F, 0, 0, 0, 0.1309F));
|
||||
|
||||
crown.addChild("spike_r2", ModelPartBuilder.create()
|
||||
.uv(2, 20).cuboid(-1, -4, 0, 1, 4, 0, Dilation.NONE), ModelTransform.of(0, -5, 4.25F, -0.5087F, -0.1298F, -0.228F));
|
||||
crown.addChild("spike_l2", ModelPartBuilder.create()
|
||||
.uv(2, 20).cuboid(-1, -4, 0, 1, 4, 0, Dilation.NONE), ModelTransform.of(3, -5, -4.25F, 0.5236F, 0, 0));
|
||||
crown.addChild("spike_l1", ModelPartBuilder.create()
|
||||
.uv(2, 20).cuboid(-1, -4, 0, 1, 4, 0, Dilation.NONE), ModelTransform.of(0, -5, -4.25F, 0.5087F, -0.1298F, -0.228F));
|
||||
crown.addChild("spike_r1", ModelPartBuilder.create()
|
||||
.uv(2, 20).cuboid(-1, -4, 0, 1, 4, 0, Dilation.NONE), ModelTransform.of(3, -5, 4.25F, -0.5236F, 0, 0));
|
||||
|
||||
head.addChild("horn", ModelPartBuilder.create()
|
||||
.uv(0, 0).cuboid(2.2139F, -6.8302F, -1, 1, 3, 1, new Dilation(0.1F)), ModelTransform.of(-3, -6, 0.5F, 0, 0, -0.829F))
|
||||
.addChild("bone", ModelPartBuilder.create()
|
||||
.uv(4, 0).cuboid(2.5F, -6.3301F, -0.5F, 1, 2, 1, Dilation.NONE), ModelTransform.of(-1, -3, -0.5F, 0, 0, 0.1745F))
|
||||
.addChild("horn_tip", ModelPartBuilder.create()
|
||||
.uv(4, 0).cuboid(1.5035F, -6.7686F, -0.5F, 1, 2, 1, new Dilation(-0.1F)), ModelTransform.of(0, -2, 0, 0, 0, 0.2182F));
|
||||
|
||||
return TexturedModelData.of(data, 64, 64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAngles(SombraEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
|
||||
|
||||
part.yaw = -MathHelper.HALF_PI;
|
||||
part.pivotY = MathHelper.sin(ageInTicks * 0.05F) - 3;
|
||||
part.pivotZ = MathHelper.cos(ageInTicks * 0.045F);
|
||||
|
||||
//part.yaw = (float)entity.getVelocity().getX();
|
||||
|
||||
head.pitch = headPitch * MathHelper.RADIANS_PER_DEGREE;
|
||||
head.yaw = netHeadYaw * MathHelper.RADIANS_PER_DEGREE;
|
||||
|
||||
lowerJaw.resetTransform();
|
||||
float jawsOpenAmount = (1 - Math.max(0, MathHelper.sin(ageInTicks * 0.1F)));
|
||||
lowerJaw.pivotY -= jawsOpenAmount * 3;
|
||||
lowerJaw.pivotX -= jawsOpenAmount * 3;
|
||||
lowerJaw.roll += jawsOpenAmount - 0.9F;
|
||||
|
||||
upperJaw.resetTransform();
|
||||
upperJaw.roll -= jawsOpenAmount * 0.2F;
|
||||
|
||||
body.roll = limbSwingAmount * 0.3F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, float blue, float alpha) {
|
||||
part.render(matrices, vertexConsumer, light, overlay, red, green, blue, alpha);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.minelittlepony.unicopia.client.render.entity;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.SombraEntity;
|
||||
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||
import net.minecraft.client.render.entity.LivingEntityRenderer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class SombraEntityRenderer extends LivingEntityRenderer<SombraEntity, SombraEntityModel> {
|
||||
private static final Identifier TEXTURE = Unicopia.id("textures/entity/sombra/head.png");
|
||||
|
||||
public SombraEntityRenderer(EntityRendererFactory.Context context) {
|
||||
super(context, new SombraEntityModel(SombraEntityModel.getTexturedModelData().createModel()), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(SombraEntity entity) {
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasLabel(SombraEntity targetEntity) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.item.AmuletItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.util.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.goal.ActiveTargetGoal;
|
||||
import net.minecraft.entity.ai.goal.AttackGoal;
|
||||
import net.minecraft.entity.ai.goal.LookAroundGoal;
|
||||
import net.minecraft.entity.ai.goal.LookAtEntityGoal;
|
||||
import net.minecraft.entity.ai.goal.PounceAtTargetGoal;
|
||||
import net.minecraft.entity.ai.goal.RevengeGoal;
|
||||
import net.minecraft.entity.ai.goal.WanderAroundGoal;
|
||||
import net.minecraft.entity.ai.pathing.EntityNavigation;
|
||||
import net.minecraft.entity.ai.pathing.MobNavigation;
|
||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.boss.BossBar;
|
||||
import net.minecraft.entity.boss.ServerBossBar;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.entity.mob.HostileEntity;
|
||||
import net.minecraft.entity.passive.IronGolemEntity;
|
||||
import net.minecraft.entity.passive.MerchantEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.registry.tag.*;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.event.GameEvent;
|
||||
|
||||
public class SombraEntity extends HostileEntity {
|
||||
|
||||
private static final TrackedData<Optional<BlockPos>> HOME_POS = DataTracker.registerData(SombraEntity.class, TrackedDataHandlerRegistry.OPTIONAL_BLOCK_POS);
|
||||
|
||||
private final ServerBossBar bossBar = (ServerBossBar)new ServerBossBar(getDisplayName(), BossBar.Color.PURPLE, BossBar.Style.PROGRESS)
|
||||
.setDarkenSky(true)
|
||||
.setThickenFog(true);
|
||||
|
||||
public SombraEntity(EntityType<SombraEntity> type, World world) {
|
||||
super(type, world);
|
||||
bossBar.setStyle(BossBar.Style.NOTCHED_10);
|
||||
}
|
||||
|
||||
public static DefaultAttributeContainer.Builder createMobAttributes() {
|
||||
return HostileEntity.createMobAttributes()
|
||||
.add(EntityAttributes.GENERIC_MAX_HEALTH, 2000)
|
||||
.add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 102);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entity.MoveEffect getMoveEffect() {
|
||||
return Entity.MoveEffect.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAvoidTraps() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SoundEvent getHurtSound(DamageSource source) {
|
||||
return SoundEvents.ENTITY_WARDEN_HURT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SoundEvent getDeathSound() {
|
||||
return SoundEvents.ENTITY_WARDEN_DEATH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initDataTracker() {
|
||||
super.initDataTracker();
|
||||
dataTracker.startTracking(HOME_POS, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initGoals() {
|
||||
goalSelector.add(5, new WanderAroundGoal(this, 1));
|
||||
goalSelector.add(6, new LookAtEntityGoal(this, PlayerEntity.class, 8F));
|
||||
goalSelector.add(7, new LookAroundGoal(this));
|
||||
goalSelector.add(8, new PounceAtTargetGoal(this, 0.3f));
|
||||
goalSelector.add(8, new AttackGoal(this));
|
||||
targetSelector.add(1, new RevengeGoal(this));
|
||||
targetSelector.add(2, new ActiveTargetGoal<>(this, PlayerEntity.class, false));
|
||||
targetSelector.add(3, new ActiveTargetGoal<>(this, MerchantEntity.class, false));
|
||||
targetSelector.add(3, new ActiveTargetGoal<>(this, IronGolemEntity.class, true));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected EntityNavigation createNavigation(World world) {
|
||||
MobNavigation nav = new MobNavigation(this, world);
|
||||
nav.setCanPathThroughDoors(true);
|
||||
nav.setCanSwim(true);
|
||||
nav.setCanEnterOpenDoors(true);
|
||||
return nav;
|
||||
}
|
||||
|
||||
public Optional<BlockPos> getHomePos() {
|
||||
return dataTracker.get(HOME_POS);
|
||||
}
|
||||
|
||||
public void setHomePos(BlockPos pos) {
|
||||
dataTracker.set(HOME_POS, Optional.of(pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
|
||||
Optional<BlockPos> homePos = getHomePos();
|
||||
|
||||
if (homePos.isEmpty() && !isRemoved()) {
|
||||
remove(RemovalReason.DISCARDED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.getBlockPos().getSquaredDistance(homePos.get()) > 16) {
|
||||
teleportTo(Vec3d.ofCenter(homePos.get()));
|
||||
setTarget(null);
|
||||
}
|
||||
|
||||
super.tick();
|
||||
|
||||
addVelocity(0, 0.002F, 0);
|
||||
if (isSubmergedInWater()) {
|
||||
jump();
|
||||
}
|
||||
|
||||
if (age % 50 == 0) {
|
||||
playSound(SoundEvents.ENTITY_POLAR_BEAR_AMBIENT, 3, 0.3F);
|
||||
}
|
||||
|
||||
if (age % 125 == 0) {
|
||||
playSound(SoundEvents.AMBIENT_CAVE.value(), 1, 0.3F);
|
||||
}
|
||||
|
||||
if (getWorld().isClient) {
|
||||
float range = 9;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
var particle = new SphereParticleEffect(UParticles.SPHERE,
|
||||
0x222222,
|
||||
0.7F,
|
||||
(float)getWorld().getRandom().nextTriangular(2.5F, 0.7F)
|
||||
);
|
||||
getWorld().addParticle(particle,
|
||||
getWorld().getRandom().nextTriangular(getX(), range),
|
||||
getWorld().getRandom().nextTriangular(getY(), range),
|
||||
getWorld().getRandom().nextTriangular(getZ(), range),
|
||||
getWorld().getRandom().nextGaussian() / 6F,
|
||||
getWorld().getRandom().nextGaussian() / 6F,
|
||||
getWorld().getRandom().nextGaussian() / 6F
|
||||
);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 13; i++) {
|
||||
getWorld().addParticle(ParticleTypes.LARGE_SMOKE,
|
||||
getWorld().getRandom().nextTriangular(getX(), 1),
|
||||
getWorld().getRandom().nextTriangular(getY(), 1),
|
||||
getWorld().getRandom().nextTriangular(getZ(), 1),
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getWorld().getOtherEntities(this, this.getBoundingBox().expand(5), EntityPredicates.VALID_LIVING_ENTITY).forEach(target -> {
|
||||
((LivingEntity)target).addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, 100, 1));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mobTick() {
|
||||
super.mobTick();
|
||||
bossBar.setPercent(getHealth() / getMaxHealth());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(double distance) {
|
||||
double d = 64 * getRenderDistanceMultiplier();
|
||||
return distance < d * d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPushable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void pushAway(Entity entity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tickCramming() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleFallDamage(float distance, float damageMultiplier, DamageSource cause) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean damage(DamageSource source, float amount) {
|
||||
if (source.getAttacker() instanceof PlayerEntity player) {
|
||||
if (AmuletSelectors.ALICORN_AMULET.test(player)) {
|
||||
if (!getWorld().isClient) {
|
||||
player.sendMessage(Text.translatable("entity.unicopia.sombra.taunt"));
|
||||
}
|
||||
}
|
||||
ItemStack amulet = AmuletItem.getForEntity(player);
|
||||
if (amulet.isOf(UItems.ALICORN_AMULET)) {
|
||||
amulet.decrement(1);
|
||||
}
|
||||
}
|
||||
boolean damaged = super.damage(source, amount);
|
||||
|
||||
if (source.getAttacker() instanceof PlayerEntity player) {
|
||||
teleportRandomly(16);
|
||||
}
|
||||
|
||||
return damaged;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fall(double y, boolean onGroundIn, BlockState state, BlockPos pos) {
|
||||
}
|
||||
|
||||
protected boolean teleportRandomly(int maxDistance) {
|
||||
if (getWorld().isClient() || !isAlive()) {
|
||||
return false;
|
||||
}
|
||||
return teleportTo(getPos().add(VecHelper.supply(() -> random.nextTriangular(0, maxDistance))));
|
||||
}
|
||||
|
||||
private boolean teleportTo(Vec3d destination) {
|
||||
Vec3d oldPos = getPos();
|
||||
if (canTeleportTo(destination) && teleport(destination.x, destination.y, destination.z, true)) {
|
||||
getWorld().emitGameEvent(GameEvent.TELEPORT, oldPos, GameEvent.Emitter.of(this));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean canTeleportTo(Vec3d destination) {
|
||||
BlockPos.Mutable mutable = new BlockPos.Mutable(destination.x, destination.y, destination.z);
|
||||
while (mutable.getY() > getWorld().getBottomY() && !getWorld().getBlockState(mutable).blocksMovement()) {
|
||||
mutable.move(Direction.DOWN);
|
||||
}
|
||||
BlockState destinationState = getWorld().getBlockState(mutable);
|
||||
return destinationState.blocksMovement() && !destinationState.getFluidState().isIn(FluidTags.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public float getBrightnessAtEyes() {
|
||||
return super.getBrightnessAtEyes() * 0.2F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomName(@Nullable Text name) {
|
||||
super.setCustomName(name);
|
||||
bossBar.setName(getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartedTrackingBy(ServerPlayerEntity player) {
|
||||
super.onStartedTrackingBy(player);
|
||||
bossBar.addPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStoppedTrackingBy(ServerPlayerEntity player) {
|
||||
super.onStoppedTrackingBy(player);
|
||||
bossBar.removePlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCustomDataToNbt(NbtCompound nbt) {
|
||||
super.writeCustomDataToNbt(nbt);
|
||||
getHomePos().map(NbtHelper::fromBlockPos).ifPresent(pos -> {
|
||||
nbt.put("homePos", pos);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readCustomDataFromNbt(NbtCompound nbt) {
|
||||
super.readCustomDataFromNbt(nbt);
|
||||
if (nbt.contains("homePos", NbtElement.COMPOUND_TYPE)) {
|
||||
setHomePos(NbtHelper.toBlockPos(nbt.getCompound("homePos")));
|
||||
}
|
||||
if (hasCustomName()) {
|
||||
bossBar.setName(getDisplayName());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,6 +46,9 @@ public interface UEntities {
|
|||
EntityType<SpellbookEntity> SPELLBOOK = register("spellbook", FabricEntityTypeBuilder.create(SpawnGroup.MISC, SpellbookEntity::new)
|
||||
.trackRangeBlocks(200)
|
||||
.dimensions(EntityDimensions.fixed(0.9F, 0.5F)));
|
||||
EntityType<SombraEntity> SOMBRA = register("sombra", FabricEntityTypeBuilder.create(SpawnGroup.MONSTER, SombraEntity::new)
|
||||
.trackRangeBlocks(200)
|
||||
.dimensions(EntityDimensions.fixed(1F, 1F)));
|
||||
EntityType<AirBalloonEntity> AIR_BALLOON = register("air_balloon", FabricEntityTypeBuilder.create(SpawnGroup.MISC, AirBalloonEntity::new)
|
||||
.trackRangeBlocks(1000)
|
||||
.dimensions(EntityDimensions.changing(2.5F, 0.1F)));
|
||||
|
@ -60,6 +63,7 @@ public interface UEntities {
|
|||
FabricDefaultAttributeRegistry.register(SPELLBOOK, SpellbookEntity.createMobAttributes());
|
||||
FabricDefaultAttributeRegistry.register(TWITTERMITE, FairyEntity.createMobAttributes());
|
||||
FabricDefaultAttributeRegistry.register(AIR_BALLOON, FlyingEntity.createMobAttributes());
|
||||
FabricDefaultAttributeRegistry.register(SOMBRA, SombraEntity.createMobAttributes());
|
||||
|
||||
if (!Unicopia.getConfig().disableButterflySpawning.get()) {
|
||||
final Predicate<BiomeSelectionContext> butterflySpawnable = BiomeSelectors.foundInOverworld()
|
||||
|
|
|
@ -197,6 +197,8 @@
|
|||
"entity.unicopia.cast_spell": "Cast Spell",
|
||||
"entity.unicopia.cast_spell.by": "a spell cast by %s",
|
||||
"entity.unicopia.spellbook": "Spellbook",
|
||||
"entity.unicopia.sombra": "King Sombra",
|
||||
"entity.unicopia.sombra.taunt": "That's not going to work on me!",
|
||||
|
||||
"player.reachDistance": "Reach Distance",
|
||||
"player.miningSpeed": "Mining Speed",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in a new issue