Specters can now spawn with and carry equipment

This commit is contained in:
Sollace 2024-05-20 00:42:30 +01:00
parent a42aaeefc0
commit a1ed8e5319
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
3 changed files with 101 additions and 11 deletions

View file

@ -56,7 +56,6 @@ import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.client.render.*;
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;
import net.minecraft.client.render.entity.EmptyEntityRenderer;
import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.json.ModelTransformationMode;
@ -115,7 +114,7 @@ public interface URenderers {
EntityRendererRegistry.register(UEntities.LOOT_BUG, LootBugEntityRenderer::new);
EntityRendererRegistry.register(UEntities.TENTACLE, TentacleEntityRenderer::new);
EntityRendererRegistry.register(UEntities.IGNOMINIOUS_BULB, IgnominiousBulbEntityRenderer::new);
EntityRendererRegistry.register(UEntities.SPECTER, EmptyEntityRenderer::new);
EntityRendererRegistry.register(UEntities.SPECTER, SpecterEntityRenderer::new);
EntityRendererRegistry.register(UEntities.MIMIC, MimicEntityRenderer::new);
BlockEntityRendererFactories.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new);

View file

@ -0,0 +1,41 @@
package com.minelittlepony.unicopia.client.render.entity;
import com.minelittlepony.unicopia.entity.mob.SpecterEntity;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.BipedEntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory.Context;
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.model.EntityModelLayers;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.util.Identifier;
public class SpecterEntityRenderer extends BipedEntityRenderer<SpecterEntity, SpecterEntityRenderer.SpecterEntityModel> {
public SpecterEntityRenderer(Context context) {
super(context, new SpecterEntityModel(context.getPart(EntityModelLayers.PLAYER)), 0);
addFeature(new ArmorFeatureRenderer<>(this,
new BipedEntityModel<>(context.getPart(EntityModelLayers.PLAYER_INNER_ARMOR)),
new BipedEntityModel<>(context.getPart(EntityModelLayers.PLAYER_OUTER_ARMOR)),
context.getModelManager()));
}
@Override
public Identifier getTexture(SpecterEntity entity) {
return PlayerScreenHandler.BLOCK_ATLAS_TEXTURE;
}
static class SpecterEntityModel extends BipedEntityModel<SpecterEntity> {
public SpecterEntityModel(ModelPart root) {
super(root);
}
@Override
public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha) {
// noop
}
}
}

View file

@ -2,11 +2,15 @@ package com.minelittlepony.unicopia.entity.mob;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.particle.FootprintParticleEffect;
import com.minelittlepony.unicopia.particle.ParticleUtils;
import net.minecraft.entity.EntityData;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.ai.goal.ActiveTargetGoal;
import net.minecraft.entity.ai.goal.LookAroundGoal;
import net.minecraft.entity.ai.goal.LookAtEntityGoal;
@ -19,12 +23,18 @@ import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.particle.BlockStateParticleEffect;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.Difficulty;
import net.minecraft.world.GameRules;
import net.minecraft.world.LocalDifficulty;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.World;
public class SpecterEntity extends HostileEntity {
@ -44,21 +54,21 @@ public class SpecterEntity extends HostileEntity {
@Override
protected void initGoals() {
this.goalSelector.add(1, new SwimGoal(this));
this.goalSelector.add(4, new MeleeAttackGoal(this, 1.0, true));
this.goalSelector.add(5, new WanderAroundFarGoal(this, 0.8));
this.goalSelector.add(6, new LookAtEntityGoal(this, PlayerEntity.class, 8.0f));
this.goalSelector.add(6, new LookAroundGoal(this));
this.targetSelector.add(1, new RevengeGoal(this));
this.targetSelector.add(2, new TargetGoal<>(this, PlayerEntity.class));
goalSelector.add(1, new SwimGoal(this));
goalSelector.add(4, new MeleeAttackGoal(this, 1.0, true));
goalSelector.add(5, new WanderAroundFarGoal(this, 0.8));
goalSelector.add(6, new LookAtEntityGoal(this, PlayerEntity.class, 8.0f));
goalSelector.add(6, new LookAroundGoal(this));
targetSelector.add(1, new RevengeGoal(this));
//this.targetSelector.add(2, new TargetGoal<>(this, PlayerEntity.class));
}
@SuppressWarnings("deprecation")
@Override
public void tick() {
Vec3d prevPosition = getPos();
super.tick();
if (getBrightnessAtEyes() < 0.5F || getTarget() != null) {
if (getTarget() != null) {
ParticleUtils.spawnParticles(ParticleTypes.AMBIENT_ENTITY_EFFECT, this, 6);
if (getWorld().getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) {
@ -66,6 +76,8 @@ public class SpecterEntity extends HostileEntity {
getWorld().breakBlock(getBlockPos(), true);
}
}
}
if (!hasVehicle() && isOnGround()) {
@ -83,6 +95,23 @@ public class SpecterEntity extends HostileEntity {
}
}
@Override
public void setAttacker(@Nullable LivingEntity attacker) {
if (!getWorld().isClient && attacker != null) {
getWorld().getEntitiesByClass(SpecterEntity.class, this.getBoundingBox().expand(5), e -> e != this && e.getTarget() == null).forEach(specter -> {
specter.notifyPartyAttacker(this, attacker);
});
}
super.setAttacker(attacker);
}
private void notifyPartyAttacker(SpecterEntity sender, @Nullable LivingEntity attacker) {
super.setAttacker(attacker);
getNavigation().stop();
getNavigation().startMovingTo(sender, 3);
playSound(USounds.Vanilla.ENTITY_VEX_HURT, 1, 0.5F);
}
@Override
public float getSoundPitch() {
return super.getSoundPitch() * 0.3F;
@ -104,6 +133,27 @@ public class SpecterEntity extends HostileEntity {
}
@Nullable
@Override
public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData data, @Nullable NbtCompound entityNbt) {
data = super.initialize(world, difficulty, spawnReason, data, entityNbt);
Random random = world.getRandom();
float diff = difficulty.getClampedLocalDifficulty();
setCanPickUpLoot(random.nextFloat() < 0.55F * diff);
initEquipment(random, difficulty);
return data;
}
@Override
protected void initEquipment(Random random, LocalDifficulty localDifficulty) {
if (random.nextFloat() < (getWorld().getDifficulty() == Difficulty.HARD ? 0.05F : 0.01F)) {
if (random.nextFloat() < (getWorld().getDifficulty() == Difficulty.HARD ? 0.5F : 0.1F)) {
super.initEquipment(random, localDifficulty);
}
equipStack(EquipmentSlot.MAINHAND, (random.nextInt(3) == 0 ? Items.STONE_SWORD : Items.WOODEN_SWORD).getDefaultStack());
}
}
static class TargetGoal<T extends LivingEntity> extends ActiveTargetGoal<T> {
public TargetGoal(SpecterEntity specter, Class<T> targetEntityClass) {
super(specter, targetEntityClass, true);