mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Fixed crystal heart health not syncing to the client and implement health/destruction and animations for the crystal shards
This commit is contained in:
parent
e923882ebf
commit
543adefd6d
6 changed files with 164 additions and 62 deletions
|
@ -1,5 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.client.render.entity;
|
package com.minelittlepony.unicopia.client.render.entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.entity.mob.CrystalShardsEntity;
|
import com.minelittlepony.unicopia.entity.mob.CrystalShardsEntity;
|
||||||
|
|
||||||
import net.minecraft.client.model.Dilation;
|
import net.minecraft.client.model.Dilation;
|
||||||
|
@ -12,12 +14,15 @@ import net.minecraft.client.model.TexturedModelData;
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
import net.minecraft.client.render.entity.model.EntityModel;
|
import net.minecraft.client.render.entity.model.EntityModel;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
public class CrystalShardsEntityModel extends EntityModel<CrystalShardsEntity> {
|
public class CrystalShardsEntityModel extends EntityModel<CrystalShardsEntity> {
|
||||||
private final ModelPart part;
|
private final ModelPart part;
|
||||||
|
private final List<ModelPart> crystals;
|
||||||
|
|
||||||
public CrystalShardsEntityModel(ModelPart root) {
|
public CrystalShardsEntityModel(ModelPart root) {
|
||||||
this.part = root;
|
this.part = root;
|
||||||
|
this.crystals = List.of(part.getChild("west"), part.getChild("north"), part.getChild("south"), part.getChild("east"), part.getChild("primary"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TexturedModelData getTexturedModelData() {
|
public static TexturedModelData getTexturedModelData() {
|
||||||
|
@ -33,6 +38,22 @@ public class CrystalShardsEntityModel extends EntityModel<CrystalShardsEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAngles(CrystalShardsEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
|
public void setAngles(CrystalShardsEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
|
||||||
|
|
||||||
|
float offset = 0;
|
||||||
|
float amplitude = 0.02F;
|
||||||
|
|
||||||
|
for (ModelPart part : crystals) {
|
||||||
|
part.resetTransform();
|
||||||
|
|
||||||
|
if (entity.isShaking()) {
|
||||||
|
float animationTime = (entity.age + ++offset) * 122F;
|
||||||
|
float sin = MathHelper.sin(animationTime) * amplitude;
|
||||||
|
|
||||||
|
part.pitch += sin;
|
||||||
|
part.yaw += MathHelper.cos(animationTime) * amplitude;
|
||||||
|
part.roll += -sin;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,8 +9,10 @@ import net.minecraft.client.render.OverlayTexture;
|
||||||
import net.minecraft.client.render.VertexConsumerProvider;
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
import net.minecraft.client.render.entity.EntityRenderer;
|
import net.minecraft.client.render.entity.EntityRenderer;
|
||||||
import net.minecraft.client.render.entity.EntityRendererFactory;
|
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||||
|
import net.minecraft.client.render.model.ModelLoader;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.RotationAxis;
|
import net.minecraft.util.math.RotationAxis;
|
||||||
|
|
||||||
public class CrystalShardsEntityRenderer extends EntityRenderer<CrystalShardsEntity> {
|
public class CrystalShardsEntityRenderer extends EntityRenderer<CrystalShardsEntity> {
|
||||||
|
@ -37,6 +39,11 @@ public class CrystalShardsEntityRenderer extends EntityRenderer<CrystalShardsEnt
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw));
|
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw));
|
||||||
|
|
||||||
model.setAngles(entity, 0, 0, 0, 0, 0);
|
model.setAngles(entity, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
int destructionStage = (int)(MathHelper.clamp(1F - (entity.getHealth() / entity.getMaxHealth()), 0F, 1F) * (ModelLoader.field_32983 - 1F));
|
||||||
|
|
||||||
|
vertices = FloatingArtefactEntityRenderer.getDestructionOverlayProvider(matrices, vertices, destructionStage);
|
||||||
|
|
||||||
model.render(matrices, vertices.getBuffer(model.getLayer(getTexture(entity))), light, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
|
model.render(matrices, vertices.getBuffer(model.getLayer(getTexture(entity))), light, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
|
||||||
matrices.pop();
|
matrices.pop();
|
||||||
super.render(entity, yaw, tickDelta, matrices, vertices, light);
|
super.render(entity, yaw, tickDelta, matrices, vertices, light);
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class FloatingArtefactEntityRenderer extends EntityRenderer<FloatingArtef
|
||||||
matrices.translate(0, verticalOffset + variance * modelScaleY, 0);
|
matrices.translate(0, verticalOffset + variance * modelScaleY, 0);
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.getRotation(timeDelta)));
|
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(entity.getRotation(timeDelta)));
|
||||||
|
|
||||||
int destructionStage = (int)(MathHelper.clamp(1 - (entity.getHealth() / entity.getMaxHealth()), 0, 1) * (ModelLoader.field_32983 - 1));
|
int destructionStage = (int)(MathHelper.clamp(1F - (entity.getHealth() / entity.getMaxHealth()), 0F, 1F) * (ModelLoader.field_32983 - 1F));
|
||||||
|
|
||||||
itemRenderer.renderItem(stack, ModelTransformationMode.GROUND, false, matrices, getDestructionOverlayProvider(matrices, vertices, destructionStage), lightUv, OverlayTexture.DEFAULT_UV, model);
|
itemRenderer.renderItem(stack, ModelTransformationMode.GROUND, false, matrices, getDestructionOverlayProvider(matrices, vertices, destructionStage), lightUv, OverlayTexture.DEFAULT_UV, model);
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,10 @@ import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.entity.MagicImmune;
|
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
|
|
||||||
import net.minecraft.block.SideShapeType;
|
import net.minecraft.block.SideShapeType;
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
|
||||||
import net.minecraft.entity.data.DataTracker;
|
import net.minecraft.entity.data.DataTracker;
|
||||||
import net.minecraft.entity.data.TrackedData;
|
import net.minecraft.entity.data.TrackedData;
|
||||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||||
|
@ -27,16 +24,16 @@ import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class CrystalShardsEntity extends Entity implements MagicImmune {
|
public class CrystalShardsEntity extends StationaryObjectEntity {
|
||||||
static final byte SHAKE = 1;
|
static final byte SHAKE = 1;
|
||||||
|
|
||||||
static final int FULL_GROWTH_AGE = 25;
|
static final int FULL_GROWTH_AGE = 25;
|
||||||
|
|
||||||
private static final Set<Direction> ALL_DIRECTIONS = Set.of(Direction.values());
|
private static final Set<Direction> ALL_DIRECTIONS = Set.of(Direction.values());
|
||||||
private static final TrackedData<Direction> ATTACHMENT_FACE = DataTracker.registerData(SombraEntity.class, TrackedDataHandlerRegistry.FACING);
|
private static final TrackedData<Direction> ATTACHMENT_FACE = DataTracker.registerData(CrystalShardsEntity.class, TrackedDataHandlerRegistry.FACING);
|
||||||
private static final TrackedData<Integer> GROWTH = DataTracker.registerData(SombraEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
private static final TrackedData<Integer> GROWTH = DataTracker.registerData(CrystalShardsEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||||
private static final TrackedData<Boolean> DECAYING = DataTracker.registerData(SombraEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
private static final TrackedData<Boolean> DECAYING = DataTracker.registerData(CrystalShardsEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||||
private static final TrackedData<Boolean> CORRUPT = DataTracker.registerData(SombraEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
private static final TrackedData<Boolean> CORRUPT = DataTracker.registerData(CrystalShardsEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||||
|
|
||||||
public static boolean infestBlock(ServerWorld world, BlockPos pos) {
|
public static boolean infestBlock(ServerWorld world, BlockPos pos) {
|
||||||
if (world.isAir(pos) || !world.getFluidState(pos).isOf(Fluids.EMPTY)) {
|
if (world.isAir(pos) || !world.getFluidState(pos).isOf(Fluids.EMPTY)) {
|
||||||
|
@ -89,12 +86,18 @@ public class CrystalShardsEntity extends Entity implements MagicImmune {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDataTracker() {
|
protected void initDataTracker() {
|
||||||
|
super.initDataTracker();
|
||||||
dataTracker.startTracking(ATTACHMENT_FACE, Direction.UP);
|
dataTracker.startTracking(ATTACHMENT_FACE, Direction.UP);
|
||||||
dataTracker.startTracking(GROWTH, 0);
|
dataTracker.startTracking(GROWTH, 0);
|
||||||
dataTracker.startTracking(DECAYING, false);
|
dataTracker.startTracking(DECAYING, false);
|
||||||
dataTracker.startTracking(CORRUPT, false);
|
dataTracker.startTracking(CORRUPT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMaxHealth() {
|
||||||
|
return 15F;
|
||||||
|
}
|
||||||
|
|
||||||
public float getGrowth(float tickDelta) {
|
public float getGrowth(float tickDelta) {
|
||||||
int age = getGrowth();
|
int age = getGrowth();
|
||||||
float lerped = MathHelper.clamp(MathHelper.lerp(tickDelta, prevAge, age), 0, FULL_GROWTH_AGE) / (float)FULL_GROWTH_AGE;
|
float lerped = MathHelper.clamp(MathHelper.lerp(tickDelta, prevAge, age), 0, FULL_GROWTH_AGE) / (float)FULL_GROWTH_AGE;
|
||||||
|
@ -157,19 +160,22 @@ public class CrystalShardsEntity extends Entity implements MagicImmune {
|
||||||
|
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (getGrowth() < FULL_GROWTH_AGE) {
|
if (ticksShaking > 0 || getGrowth() < FULL_GROWTH_AGE) {
|
||||||
playSound(USounds.Vanilla.BLOCK_AMETHYST_BLOCK_CHIME, 1, 1);
|
if (age % random.nextBetween(2, 5) == 0) {
|
||||||
|
playSound(USounds.Vanilla.BLOCK_AMETHYST_BLOCK_HIT, 1,
|
||||||
|
1 - MathHelper.clamp(getGrowth(1), 0, 1) * 0.5F);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInvalid(getWorld(), getBlockPos(), getAttachmentFace())) {
|
if (isDead() || isInvalid(getWorld(), getBlockPos(), getAttachmentFace())) {
|
||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean damage(DamageSource source, float amount) {
|
protected void onHurt() {
|
||||||
getWorld().sendEntityStatus(this, SHAKE);
|
getWorld().sendEntityStatus(this, SHAKE);
|
||||||
return super.damage(source, amount);
|
ticksShaking = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -185,7 +191,7 @@ public class CrystalShardsEntity extends Entity implements MagicImmune {
|
||||||
public void handleStatus(byte status) {
|
public void handleStatus(byte status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SHAKE:
|
case SHAKE:
|
||||||
ticksShaking = 30;
|
ticksShaking = 10;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
super.handleStatus(status);
|
super.handleStatus(status);
|
||||||
|
@ -194,7 +200,8 @@ public class CrystalShardsEntity extends Entity implements MagicImmune {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeCustomDataToNbt(NbtCompound nbt) {
|
public void writeCustomDataToNbt(NbtCompound nbt) {
|
||||||
nbt.putFloat("yaw", this.getYaw());
|
super.writeCustomDataToNbt(nbt);
|
||||||
|
nbt.putFloat("yaw", getYaw());
|
||||||
nbt.putInt("growth", getGrowth());
|
nbt.putInt("growth", getGrowth());
|
||||||
nbt.putString("face", getAttachmentFace().getName());
|
nbt.putString("face", getAttachmentFace().getName());
|
||||||
nbt.putBoolean("decaying", isDecaying());
|
nbt.putBoolean("decaying", isDecaying());
|
||||||
|
@ -203,6 +210,7 @@ public class CrystalShardsEntity extends Entity implements MagicImmune {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readCustomDataFromNbt(NbtCompound nbt) {
|
public void readCustomDataFromNbt(NbtCompound nbt) {
|
||||||
|
super.readCustomDataFromNbt(nbt);
|
||||||
setYaw(nbt.getFloat("yaw"));
|
setYaw(nbt.getFloat("yaw"));
|
||||||
setGrowth(nbt.getInt("growth"));
|
setGrowth(nbt.getInt("growth"));
|
||||||
setAttachmentFace(Direction.byName(nbt.getString("face")));
|
setAttachmentFace(Direction.byName(nbt.getString("face")));
|
||||||
|
|
|
@ -3,12 +3,9 @@ package com.minelittlepony.unicopia.entity.mob;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.entity.MagicImmune;
|
|
||||||
import com.minelittlepony.unicopia.entity.damage.UDamageSources;
|
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.server.world.Altar;
|
import com.minelittlepony.unicopia.server.world.Altar;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import net.minecraft.entity.data.DataTracker;
|
import net.minecraft.entity.data.DataTracker;
|
||||||
|
@ -21,7 +18,7 @@ import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class FloatingArtefactEntity extends Entity implements UDamageSources, MagicImmune {
|
public class FloatingArtefactEntity extends StationaryObjectEntity {
|
||||||
private static final TrackedData<ItemStack> ITEM = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.ITEM_STACK);
|
private static final TrackedData<ItemStack> ITEM = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.ITEM_STACK);
|
||||||
private static final TrackedData<Byte> STATE = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.BYTE);
|
private static final TrackedData<Byte> STATE = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.BYTE);
|
||||||
private static final TrackedData<Float> TARGET_ROTATION_SPEED = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
private static final TrackedData<Float> TARGET_ROTATION_SPEED = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
|
@ -40,7 +37,6 @@ public class FloatingArtefactEntity extends Entity implements UDamageSources, Ma
|
||||||
|
|
||||||
private int boostDuration;
|
private int boostDuration;
|
||||||
|
|
||||||
private float health;
|
|
||||||
private int ticksUntilRegen;
|
private int ticksUntilRegen;
|
||||||
public final float positionSeed;
|
public final float positionSeed;
|
||||||
|
|
||||||
|
@ -50,11 +46,11 @@ public class FloatingArtefactEntity extends Entity implements UDamageSources, Ma
|
||||||
super(entityType, world);
|
super(entityType, world);
|
||||||
|
|
||||||
positionSeed = (float)(Math.random() * Math.PI * 2);
|
positionSeed = (float)(Math.random() * Math.PI * 2);
|
||||||
health = getMaxHealth();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDataTracker() {
|
protected void initDataTracker() {
|
||||||
|
super.initDataTracker();
|
||||||
dataTracker.startTracking(ITEM, ItemStack.EMPTY);
|
dataTracker.startTracking(ITEM, ItemStack.EMPTY);
|
||||||
dataTracker.startTracking(STATE, (byte)0);
|
dataTracker.startTracking(STATE, (byte)0);
|
||||||
dataTracker.startTracking(TARGET_ROTATION_SPEED, 1F);
|
dataTracker.startTracking(TARGET_ROTATION_SPEED, 1F);
|
||||||
|
@ -93,16 +89,9 @@ public class FloatingArtefactEntity extends Entity implements UDamageSources, Ma
|
||||||
return MathHelper.lerp(tickDelta, prevRotationSpeed, rotationSpeed);
|
return MathHelper.lerp(tickDelta, prevRotationSpeed, rotationSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxHealth() {
|
@Override
|
||||||
return 20;
|
public float getMaxHealth() {
|
||||||
}
|
return 20F;
|
||||||
|
|
||||||
public void setHealth(float health) {
|
|
||||||
this.health = MathHelper.clamp(health, 0, getMaxHealth());
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getHealth() {
|
|
||||||
return health;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,16 +152,17 @@ public class FloatingArtefactEntity extends Entity implements UDamageSources, Ma
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readCustomDataFromNbt(NbtCompound compound) {
|
protected void readCustomDataFromNbt(NbtCompound compound) {
|
||||||
|
super.readCustomDataFromNbt(compound);
|
||||||
setStack(ItemStack.fromNbt(compound.getCompound("Item")));
|
setStack(ItemStack.fromNbt(compound.getCompound("Item")));
|
||||||
setState(State.valueOf(compound.getInt("State")));
|
setState(State.valueOf(compound.getInt("State")));
|
||||||
setRotationSpeed(compound.getFloat("spin"), compound.getInt("spinDuration"));
|
setRotationSpeed(compound.getFloat("spin"), compound.getInt("spinDuration"));
|
||||||
setHealth(compound.getFloat("health"));
|
|
||||||
ticksUntilRegen = compound.getInt("regen");
|
ticksUntilRegen = compound.getInt("regen");
|
||||||
altar = Altar.SERIALIZER.readOptional("altar", compound);
|
altar = Altar.SERIALIZER.readOptional("altar", compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeCustomDataToNbt(NbtCompound compound) {
|
protected void writeCustomDataToNbt(NbtCompound compound) {
|
||||||
|
super.writeCustomDataToNbt(compound);
|
||||||
ItemStack stack = getStack();
|
ItemStack stack = getStack();
|
||||||
if (!stack.isEmpty()) {
|
if (!stack.isEmpty()) {
|
||||||
compound.put("Item", stack.writeNbt(new NbtCompound()));
|
compound.put("Item", stack.writeNbt(new NbtCompound()));
|
||||||
|
@ -180,46 +170,46 @@ public class FloatingArtefactEntity extends Entity implements UDamageSources, Ma
|
||||||
compound.putInt("State", getState().ordinal());
|
compound.putInt("State", getState().ordinal());
|
||||||
compound.putFloat("spin", getRotationSpeed());
|
compound.putFloat("spin", getRotationSpeed());
|
||||||
compound.putInt("spinDuration", boostDuration);
|
compound.putInt("spinDuration", boostDuration);
|
||||||
compound.putFloat("health", getHealth());
|
|
||||||
compound.putInt("regen", ticksUntilRegen);
|
compound.putInt("regen", ticksUntilRegen);
|
||||||
Altar.SERIALIZER.writeOptional("altar", compound, altar);
|
Altar.SERIALIZER.writeOptional("altar", compound, altar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean damage(DamageSource damageSource, float amount) {
|
public boolean damage(DamageSource source, float damage) {
|
||||||
|
|
||||||
if (getWorld().isClient || isInvulnerable()) {
|
if (getWorld().isClient || isInvulnerable()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInvulnerableTo(damageSource) || !getStack().getItem().damage(damageSource)) {
|
if (isInvulnerableTo(source) || !getStack().getItem().damage(source)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damageSource.isSourceCreativePlayer()) {
|
ticksUntilRegen = REGEN_PAUSE_TICKS;
|
||||||
health = 0;
|
|
||||||
} else {
|
if (source.isSourceCreativePlayer()) {
|
||||||
health -= amount;
|
damage = getHealth();
|
||||||
ticksUntilRegen = REGEN_PAUSE_TICKS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (health <= 0) {
|
return super.damage(source, damage);
|
||||||
remove(RemovalReason.KILLED);
|
}
|
||||||
|
|
||||||
ItemStack stack = getStack();
|
@Override
|
||||||
|
protected void onKilled(DamageSource source) {
|
||||||
|
ItemStack stack = getStack();
|
||||||
|
|
||||||
if (altar.isEmpty()) {
|
if (altar.isEmpty()) {
|
||||||
if (!(stack.getItem() instanceof Artifact) || ((Artifact)stack.getItem()).onArtifactDestroyed(this) != ActionResult.SUCCESS) {
|
if (!(stack.getItem() instanceof Artifact) || ((Artifact)stack.getItem()).onArtifactDestroyed(this) != ActionResult.SUCCESS) {
|
||||||
if (!damageSource.isSourceCreativePlayer()) {
|
if (!source.isSourceCreativePlayer()) {
|
||||||
dropStack(stack);
|
dropStack(stack);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
playSound(USounds.ITEM_ICARUS_WINGS_WARN, 1, 1);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
@Override
|
||||||
|
protected void onHurt() {
|
||||||
|
playSound(USounds.ITEM_ICARUS_WINGS_WARN, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -228,16 +218,6 @@ public class FloatingArtefactEntity extends Entity implements UDamageSources, Ma
|
||||||
altar.ifPresent(altar -> altar.tearDown(this, getWorld()));
|
altar.ifPresent(altar -> altar.tearDown(this, getWorld()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canHit() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public World asWorld() {
|
|
||||||
return getWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
INITIALISING,
|
INITIALISING,
|
||||||
RUNNING,
|
RUNNING,
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.minelittlepony.unicopia.entity.mob;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.MagicImmune;
|
||||||
|
import com.minelittlepony.unicopia.entity.damage.UDamageSources;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
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.nbt.NbtCompound;
|
||||||
|
import net.minecraft.nbt.NbtElement;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public abstract class StationaryObjectEntity extends Entity implements UDamageSources, MagicImmune {
|
||||||
|
private static final TrackedData<Float> HEALTH = DataTracker.registerData(StationaryObjectEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||||
|
|
||||||
|
public StationaryObjectEntity(EntityType<?> entityType, World world) {
|
||||||
|
super(entityType, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initDataTracker() {
|
||||||
|
dataTracker.startTracking(HEALTH, getMaxHealth());
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract float getMaxHealth();
|
||||||
|
|
||||||
|
public final float setHealth(float health) {
|
||||||
|
health = MathHelper.clamp(health, 0, getMaxHealth());
|
||||||
|
dataTracker.set(HEALTH, health);
|
||||||
|
return health;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final float getHealth() {
|
||||||
|
return dataTracker.get(HEALTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isDead() {
|
||||||
|
return isRemoved() || getHealth() <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean damage(DamageSource source, float damage) {
|
||||||
|
if (!isDead()) {
|
||||||
|
if (setHealth(getHealth() - damage) <= 0) {
|
||||||
|
kill();
|
||||||
|
onKilled(source);
|
||||||
|
} else {
|
||||||
|
onHurt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onKilled(DamageSource source) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onHurt() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readCustomDataFromNbt(NbtCompound compound) {
|
||||||
|
if (compound.contains("health", NbtElement.FLOAT_TYPE)) {
|
||||||
|
setHealth(compound.getFloat("health"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeCustomDataToNbt(NbtCompound compound) {
|
||||||
|
compound.putFloat("health", getHealth());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean canHit() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final World asWorld() {
|
||||||
|
return getWorld();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue