253 lines
8.6 KiB
Java
253 lines
8.6 KiB
Java
|
|
package hal.studios.hpm.entity;
|
|
|
|
import net.minecraftforge.registries.ForgeRegistries;
|
|
import net.minecraftforge.network.PlayMessages;
|
|
import net.minecraftforge.network.NetworkHooks;
|
|
import net.minecraftforge.items.wrapper.EntityHandsInvWrapper;
|
|
import net.minecraftforge.items.wrapper.EntityArmorInvWrapper;
|
|
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
|
import net.minecraftforge.items.ItemStackHandler;
|
|
import net.minecraftforge.items.CapabilityItemHandler;
|
|
import net.minecraftforge.common.util.LazyOptional;
|
|
import net.minecraftforge.common.capabilities.Capability;
|
|
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.ServerLevelAccessor;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
|
import net.minecraft.world.entity.projectile.ThrownPotion;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.entity.player.Inventory;
|
|
import net.minecraft.world.entity.ai.attributes.Attributes;
|
|
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
|
|
import net.minecraft.world.entity.SpawnGroupData;
|
|
import net.minecraft.world.entity.PathfinderMob;
|
|
import net.minecraft.world.entity.MobType;
|
|
import net.minecraft.world.entity.MobSpawnType;
|
|
import net.minecraft.world.entity.Mob;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.AreaEffectCloud;
|
|
import net.minecraft.world.damagesource.DamageSource;
|
|
import net.minecraft.world.MenuProvider;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.DifficultyInstance;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.network.protocol.Packet;
|
|
import net.minecraft.network.chat.TextComponent;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.network.FriendlyByteBuf;
|
|
import net.minecraft.nbt.Tag;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.BlockPos;
|
|
|
|
import javax.annotation.Nullable;
|
|
import javax.annotation.Nonnull;
|
|
|
|
import io.netty.buffer.Unpooled;
|
|
|
|
import hal.studios.hpm.world.inventory.CutterinventoryMenu;
|
|
import hal.studios.hpm.procedures.CutterRightClickedOnEntityProcedure;
|
|
import hal.studios.hpm.procedures.CutterOnInitialEntitySpawnProcedure;
|
|
import hal.studios.hpm.procedures.CutterOnEntityTickUpdateProcedure;
|
|
import hal.studios.hpm.procedures.CutterEntityIsHurtProcedure;
|
|
import hal.studios.hpm.procedures.CutterEntityDiesProcedure;
|
|
import hal.studios.hpm.init.HpmModEntities;
|
|
|
|
public class CutterEntity extends PathfinderMob {
|
|
public CutterEntity(PlayMessages.SpawnEntity packet, Level world) {
|
|
this(HpmModEntities.CUTTER.get(), world);
|
|
}
|
|
|
|
public CutterEntity(EntityType<CutterEntity> type, Level world) {
|
|
super(type, world);
|
|
maxUpStep = 0.6f;
|
|
xpReward = 0;
|
|
setNoAi(false);
|
|
setPersistenceRequired();
|
|
}
|
|
|
|
@Override
|
|
public Packet<?> getAddEntityPacket() {
|
|
return NetworkHooks.getEntitySpawningPacket(this);
|
|
}
|
|
|
|
@Override
|
|
protected void registerGoals() {
|
|
super.registerGoals();
|
|
|
|
}
|
|
|
|
@Override
|
|
public MobType getMobType() {
|
|
return MobType.UNDEFINED;
|
|
}
|
|
|
|
@Override
|
|
public boolean removeWhenFarAway(double distanceToClosestPlayer) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public double getPassengersRidingOffset() {
|
|
return super.getPassengersRidingOffset() + -0.5;
|
|
}
|
|
|
|
@Override
|
|
public void playStepSound(BlockPos pos, BlockState blockIn) {
|
|
this.playSound(ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("entity.generic.splash")), 0.15f, 1);
|
|
}
|
|
|
|
@Override
|
|
public SoundEvent getHurtSound(DamageSource ds) {
|
|
return ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("entity.zombie.attack_wooden_door"));
|
|
}
|
|
|
|
@Override
|
|
public SoundEvent getDeathSound() {
|
|
return ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("entity.zombie.break_wooden_door"));
|
|
}
|
|
|
|
@Override
|
|
public boolean hurt(DamageSource source, float amount) {
|
|
CutterEntityIsHurtProcedure.execute(this.level, this.getX(), this.getY(), this.getZ(), this, source.getEntity());
|
|
if (source.getDirectEntity() instanceof ThrownPotion || source.getDirectEntity() instanceof AreaEffectCloud)
|
|
return false;
|
|
if (source == DamageSource.DROWN)
|
|
return false;
|
|
if (source == DamageSource.DRAGON_BREATH)
|
|
return false;
|
|
return super.hurt(source, amount);
|
|
}
|
|
|
|
@Override
|
|
public void die(DamageSource source) {
|
|
super.die(source);
|
|
CutterEntityDiesProcedure.execute(this.level, this.getX(), this.getY(), this.getZ(), this);
|
|
}
|
|
|
|
@Override
|
|
public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType reason, @Nullable SpawnGroupData livingdata, @Nullable CompoundTag tag) {
|
|
SpawnGroupData retval = super.finalizeSpawn(world, difficulty, reason, livingdata, tag);
|
|
CutterOnInitialEntitySpawnProcedure.execute(world, this.getX(), this.getY(), this.getZ(), this);
|
|
return retval;
|
|
}
|
|
|
|
private final ItemStackHandler inventory = new ItemStackHandler(228) {
|
|
@Override
|
|
public int getSlotLimit(int slot) {
|
|
return 64;
|
|
}
|
|
};
|
|
private final CombinedInvWrapper combined = new CombinedInvWrapper(inventory, new EntityHandsInvWrapper(this), new EntityArmorInvWrapper(this));
|
|
|
|
@Override
|
|
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction side) {
|
|
if (this.isAlive() && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && side == null)
|
|
return LazyOptional.of(() -> combined).cast();
|
|
return super.getCapability(capability, side);
|
|
}
|
|
|
|
@Override
|
|
protected void dropEquipment() {
|
|
super.dropEquipment();
|
|
for (int i = 0; i < inventory.getSlots(); ++i) {
|
|
ItemStack itemstack = inventory.getStackInSlot(i);
|
|
if (!itemstack.isEmpty() && !EnchantmentHelper.hasVanishingCurse(itemstack)) {
|
|
this.spawnAtLocation(itemstack);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void addAdditionalSaveData(CompoundTag compound) {
|
|
super.addAdditionalSaveData(compound);
|
|
compound.put("InventoryCustom", inventory.serializeNBT());
|
|
}
|
|
|
|
@Override
|
|
public void readAdditionalSaveData(CompoundTag compound) {
|
|
super.readAdditionalSaveData(compound);
|
|
Tag inventoryCustom = compound.get("InventoryCustom");
|
|
if (inventoryCustom instanceof CompoundTag inventoryTag)
|
|
inventory.deserializeNBT(inventoryTag);
|
|
}
|
|
|
|
@Override
|
|
public InteractionResult mobInteract(Player sourceentity, InteractionHand hand) {
|
|
ItemStack itemstack = sourceentity.getItemInHand(hand);
|
|
InteractionResult retval = InteractionResult.sidedSuccess(this.level.isClientSide());
|
|
if (sourceentity.isSecondaryUseActive()) {
|
|
if (sourceentity instanceof ServerPlayer serverPlayer) {
|
|
NetworkHooks.openGui(serverPlayer, new MenuProvider() {
|
|
@Override
|
|
public Component getDisplayName() {
|
|
return new TextComponent("cutter");
|
|
}
|
|
|
|
@Override
|
|
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
|
|
FriendlyByteBuf packetBuffer = new FriendlyByteBuf(Unpooled.buffer());
|
|
packetBuffer.writeBlockPos(sourceentity.blockPosition());
|
|
packetBuffer.writeByte(0);
|
|
packetBuffer.writeVarInt(CutterEntity.this.getId());
|
|
return new CutterinventoryMenu(id, inventory, packetBuffer);
|
|
}
|
|
}, buf -> {
|
|
buf.writeBlockPos(sourceentity.blockPosition());
|
|
buf.writeByte(0);
|
|
buf.writeVarInt(this.getId());
|
|
});
|
|
}
|
|
return InteractionResult.sidedSuccess(this.level.isClientSide());
|
|
}
|
|
super.mobInteract(sourceentity, hand);
|
|
sourceentity.startRiding(this);
|
|
double x = this.getX();
|
|
double y = this.getY();
|
|
double z = this.getZ();
|
|
Entity entity = this;
|
|
Level world = this.level;
|
|
|
|
CutterRightClickedOnEntityProcedure.execute(world, x, y, z, entity, sourceentity);
|
|
return retval;
|
|
}
|
|
|
|
@Override
|
|
public void baseTick() {
|
|
super.baseTick();
|
|
CutterOnEntityTickUpdateProcedure.execute(this.level, this.getX(), this.getY(), this.getZ(), this);
|
|
}
|
|
|
|
@Override
|
|
public boolean canCollideWith(Entity entity) {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean canBeCollidedWith() {
|
|
return true;
|
|
}
|
|
|
|
public static void init() {
|
|
}
|
|
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
AttributeSupplier.Builder builder = Mob.createMobAttributes();
|
|
builder = builder.add(Attributes.MOVEMENT_SPEED, 0.05);
|
|
builder = builder.add(Attributes.MAX_HEALTH, 50);
|
|
builder = builder.add(Attributes.ARMOR, 0);
|
|
builder = builder.add(Attributes.ATTACK_DAMAGE, 3);
|
|
builder = builder.add(Attributes.FOLLOW_RANGE, 16);
|
|
builder = builder.add(Attributes.KNOCKBACK_RESISTANCE, 2);
|
|
return builder;
|
|
}
|
|
}
|