mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Added specter
This commit is contained in:
parent
c91b5ac985
commit
fd03dabdd6
10 changed files with 256 additions and 130 deletions
|
@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.client.particle.CloudsEscapingParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.DiskParticle;
|
import com.minelittlepony.unicopia.client.particle.DiskParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.DustCloudParticle;
|
import com.minelittlepony.unicopia.client.particle.DustCloudParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.FloatingBubbleParticle;
|
import com.minelittlepony.unicopia.client.particle.FloatingBubbleParticle;
|
||||||
|
import com.minelittlepony.unicopia.client.particle.FootprintParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.GroundPoundParticle;
|
import com.minelittlepony.unicopia.client.particle.GroundPoundParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.HealthDrainParticle;
|
import com.minelittlepony.unicopia.client.particle.HealthDrainParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.LightningBoltParticle;
|
import com.minelittlepony.unicopia.client.particle.LightningBoltParticle;
|
||||||
|
@ -19,7 +20,6 @@ import com.minelittlepony.unicopia.client.particle.MagicParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.RainboomParticle;
|
import com.minelittlepony.unicopia.client.particle.RainboomParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle;
|
import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.RaindropsParticle;
|
import com.minelittlepony.unicopia.client.particle.RaindropsParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.RunesParticle;
|
|
||||||
import com.minelittlepony.unicopia.client.particle.ShockwaveParticle;
|
import com.minelittlepony.unicopia.client.particle.ShockwaveParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
||||||
import com.minelittlepony.unicopia.client.render.*;
|
import com.minelittlepony.unicopia.client.render.*;
|
||||||
|
@ -54,6 +54,7 @@ import net.minecraft.client.particle.SpriteProvider;
|
||||||
import net.minecraft.client.render.*;
|
import net.minecraft.client.render.*;
|
||||||
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
||||||
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;
|
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.entity.FlyingItemEntityRenderer;
|
||||||
import net.minecraft.client.render.item.ItemRenderer;
|
import net.minecraft.client.render.item.ItemRenderer;
|
||||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||||
|
@ -68,7 +69,6 @@ import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.BlockRenderView;
|
import net.minecraft.world.BlockRenderView;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public interface URenderers {
|
public interface URenderers {
|
||||||
BlockEntity CHEST_RENDER_ENTITY = new CloudChestBlock.TileData(BlockPos.ORIGIN, UBlocks.CLOUD_CHEST.getDefaultState());
|
BlockEntity CHEST_RENDER_ENTITY = new CloudChestBlock.TileData(BlockPos.ORIGIN, UBlocks.CLOUD_CHEST.getDefaultState());
|
||||||
|
|
||||||
|
@ -78,10 +78,10 @@ public interface URenderers {
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.BUBBLE, createFactory(FloatingBubbleParticle::new));
|
ParticleFactoryRegistry.getInstance().register(UParticles.BUBBLE, createFactory(FloatingBubbleParticle::new));
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAIN_DROPS, createFactory(RaindropsParticle::new));
|
ParticleFactoryRegistry.getInstance().register(UParticles.RAIN_DROPS, createFactory(RaindropsParticle::new));
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.HEALTH_DRAIN, createFactory(HealthDrainParticle::create));
|
ParticleFactoryRegistry.getInstance().register(UParticles.HEALTH_DRAIN, createFactory(HealthDrainParticle::create));
|
||||||
|
ParticleFactoryRegistry.getInstance().register(UParticles.FOOTPRINT, createFactory(FootprintParticle::new));
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_RING, RainboomParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_RING, RainboomParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_TRAIL, RainbowTrailParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_TRAIL, RainbowTrailParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.SHOCKWAVE, ShockwaveParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.SHOCKWAVE, ShockwaveParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.MAGIC_RUNES, RunesParticle::new);
|
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.SPHERE, SphereParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.SPHERE, SphereParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.GROUND_POUND, GroundPoundParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.GROUND_POUND, GroundPoundParticle::new);
|
||||||
|
@ -111,6 +111,7 @@ public interface URenderers {
|
||||||
EntityRendererRegistry.register(UEntities.LOOT_BUG, LootBugEntityRenderer::new);
|
EntityRendererRegistry.register(UEntities.LOOT_BUG, LootBugEntityRenderer::new);
|
||||||
EntityRendererRegistry.register(UEntities.TENTACLE, TentacleEntityRenderer::new);
|
EntityRendererRegistry.register(UEntities.TENTACLE, TentacleEntityRenderer::new);
|
||||||
EntityRendererRegistry.register(UEntities.IGNOMINIOUS_BULB, IgnominiousBulbEntityRenderer::new);
|
EntityRendererRegistry.register(UEntities.IGNOMINIOUS_BULB, IgnominiousBulbEntityRenderer::new);
|
||||||
|
EntityRendererRegistry.register(UEntities.SPECTER, EmptyEntityRenderer::new);
|
||||||
|
|
||||||
BlockEntityRendererFactories.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new);
|
BlockEntityRendererFactories.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new);
|
||||||
BlockEntityRendererFactories.register(UBlockEntities.FANCY_BED, CloudBedBlockEntityRenderer::new);
|
BlockEntityRendererFactories.register(UBlockEntities.FANCY_BED, CloudBedBlockEntityRenderer::new);
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.minelittlepony.unicopia.client.particle;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.particle.FootprintParticleEffect;
|
||||||
|
|
||||||
|
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||||
|
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||||
|
import net.minecraft.client.particle.SpriteProvider;
|
||||||
|
import net.minecraft.client.render.Camera;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class FootprintParticle extends SpriteBillboardParticle {
|
||||||
|
// specter
|
||||||
|
|
||||||
|
public FootprintParticle(FootprintParticleEffect effect, SpriteProvider provider, ClientWorld world, double x, double y, double z, double dx, double dy, double dz) {
|
||||||
|
super(world, x, y, z, 0, 0, 0);
|
||||||
|
setVelocity(0, 0, 0);
|
||||||
|
setSprite(provider.getSprite(world.random));
|
||||||
|
this.angle = effect.yaw() * MathHelper.RADIANS_PER_DEGREE;
|
||||||
|
this.maxAge = 1000;
|
||||||
|
this.gravityStrength = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParticleTextureSheet getType() {
|
||||||
|
return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) {
|
||||||
|
Vec3d cam = camera.getPos();
|
||||||
|
|
||||||
|
float renderX = (float)(MathHelper.lerp(tickDelta, prevPosX, x) - cam.getX());
|
||||||
|
float renderY = (float)(MathHelper.lerp(tickDelta, prevPosY, y) - cam.getY());
|
||||||
|
float renderZ = (float)(MathHelper.lerp(tickDelta, prevPosZ, z) - cam.getZ());
|
||||||
|
|
||||||
|
Vector3f[] corners = new Vector3f[]{
|
||||||
|
new Vector3f(-1, 0, -1),
|
||||||
|
new Vector3f(-1, 0, 1),
|
||||||
|
new Vector3f( 1, 0, 1),
|
||||||
|
new Vector3f( 1, 0, -1)
|
||||||
|
};
|
||||||
|
for (int k = 0; k < 4; ++k) {
|
||||||
|
Vector3f corner = corners[k];
|
||||||
|
corner.mul(0.2F);
|
||||||
|
corner.rotateAxis(angle, 0, 1, 0);
|
||||||
|
corner.add(renderX, renderY + 0.0001F, renderZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
float alpha = this.alpha * (1 - ((float)age / maxAge));
|
||||||
|
int light = getBrightness(tickDelta);
|
||||||
|
|
||||||
|
float minU = this.sprite.getMinU();
|
||||||
|
float maxU = this.sprite.getMaxU();
|
||||||
|
|
||||||
|
float minV = this.sprite.getMinV();
|
||||||
|
float maxV = this.sprite.getMaxV();
|
||||||
|
|
||||||
|
drawer.vertex(corners[0].x, corners[0].y, corners[0].z).texture(minU, minV).color(red, green, blue, alpha).light(light).next();
|
||||||
|
drawer.vertex(corners[1].x, corners[1].y, corners[1].z).texture(maxU, minV).color(red, green, blue, alpha).light(light).next();
|
||||||
|
drawer.vertex(corners[2].x, corners[2].y, corners[2].z).texture(maxU, maxV).color(red, green, blue, alpha).light(light).next();
|
||||||
|
drawer.vertex(corners[3].x, corners[3].y, corners[3].z).texture(minU, maxV).color(red, green, blue, alpha).light(light).next();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,123 +0,0 @@
|
||||||
package com.minelittlepony.unicopia.client.particle;
|
|
||||||
|
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
|
||||||
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
import net.minecraft.client.render.BufferBuilder;
|
|
||||||
import net.minecraft.client.render.Tessellator;
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.*;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class RunesParticle extends OrientedBillboardParticle {
|
|
||||||
|
|
||||||
private static final Identifier[] TEXTURES = new Identifier[] {
|
|
||||||
Unicopia.id("textures/particles/runes_0.png"),
|
|
||||||
Unicopia.id("textures/particles/runes_1.png"),
|
|
||||||
Unicopia.id("textures/particles/runes_2.png"),
|
|
||||||
Unicopia.id("textures/particles/runes_3.png"),
|
|
||||||
Unicopia.id("textures/particles/runes_4.png"),
|
|
||||||
Unicopia.id("textures/particles/runes_5.png")
|
|
||||||
};
|
|
||||||
|
|
||||||
protected float targetSize = 3;
|
|
||||||
|
|
||||||
protected float prevBaseSize = 0;
|
|
||||||
protected float baseSize = 0;
|
|
||||||
|
|
||||||
private float prevRotationAngle;
|
|
||||||
private float rotationAngle;
|
|
||||||
|
|
||||||
public RunesParticle(OrientedBillboardParticleEffect effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
|
||||||
super(effect, world, x, y, z, velocityX, velocityY, velocityZ);
|
|
||||||
setMaxAge(70);
|
|
||||||
|
|
||||||
red = world.random.nextFloat();
|
|
||||||
green = world.random.nextFloat();
|
|
||||||
blue = world.random.nextFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getScale(float tickDelta) {
|
|
||||||
return MathHelper.lerp(tickDelta, prevBaseSize, baseSize) * super.getScale(tickDelta);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Identifier getTexture() {
|
|
||||||
return TEXTURES[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private float getAlphaScale() {
|
|
||||||
float transitionScale = age < maxAge / 2 ? 5 : 3;
|
|
||||||
return (float)Math.min(1, Math.sin(Math.PI * age / maxAge) * transitionScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getBrightness(float tint) {
|
|
||||||
return 0xF000F0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta) {
|
|
||||||
|
|
||||||
float alpha = this.alpha * getAlphaScale();
|
|
||||||
|
|
||||||
float angle = MathHelper.lerp(tickDelta, prevRotationAngle, rotationAngle);
|
|
||||||
|
|
||||||
for (int i = 0; i < TEXTURES.length; i++) {
|
|
||||||
for (int dim = 0; dim < 3; dim++) {
|
|
||||||
RenderSystem.setShaderTexture(0, TEXTURES[i]);
|
|
||||||
RenderSystem.setShaderColor(red, green, blue, alpha / ((float)(dim * 3) + 1));
|
|
||||||
|
|
||||||
Vector3f[] corners = new Vector3f[]{
|
|
||||||
new Vector3f(-1, -1, 0),
|
|
||||||
new Vector3f(-1, 1, 0),
|
|
||||||
new Vector3f( 1, 1, 0),
|
|
||||||
new Vector3f( 1, -1, 0)
|
|
||||||
};
|
|
||||||
float scale = getScale(tickDelta);
|
|
||||||
|
|
||||||
float ringSpeed = (i % 2 == 0 ? i : -1) * i;
|
|
||||||
|
|
||||||
Quaternionf ringAngle = RotationAxis.POSITIVE_Z.rotationDegrees(angle * ringSpeed);
|
|
||||||
Quaternionf ringFlip = RotationAxis.POSITIVE_Y.rotationDegrees(angle * ringSpeed * dim);
|
|
||||||
Quaternionf ringRoll = RotationAxis.POSITIVE_X.rotationDegrees(angle * ringSpeed * dim);
|
|
||||||
|
|
||||||
for(int k = 0; k < 4; ++k) {
|
|
||||||
Vector3f corner = corners[k];
|
|
||||||
corner.rotate(ringAngle);
|
|
||||||
corner.rotate(ringFlip);
|
|
||||||
corner.rotate(ringRoll);
|
|
||||||
corner.rotate(rotation);
|
|
||||||
corner.mul(scale);
|
|
||||||
corner.add(x, y + 0.001F, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderQuad(te, buffer, corners, alpha, tickDelta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
super.tick();
|
|
||||||
|
|
||||||
prevBaseSize = baseSize;
|
|
||||||
if (baseSize < targetSize) {
|
|
||||||
baseSize += 0.1F;
|
|
||||||
}
|
|
||||||
if (baseSize > targetSize) {
|
|
||||||
baseSize -= 0.1F;
|
|
||||||
}
|
|
||||||
|
|
||||||
rotationAngle = (rotationAngle + 0.3F) % 360;
|
|
||||||
prevRotationAngle = rotationAngle - 0.3F;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.minelittlepony.unicopia.entity.mob;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.particle.FootprintParticleEffect;
|
||||||
|
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.goal.ActiveTargetGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.LookAroundGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.LookAtEntityGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.MeleeAttackGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.RevengeGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.SwimGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.WanderAroundFarGoal;
|
||||||
|
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||||
|
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.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.world.GameRules;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class SpecterEntity extends HostileEntity {
|
||||||
|
public static DefaultAttributeContainer.Builder createAttributes() {
|
||||||
|
return HostileEntity.createHostileAttributes()
|
||||||
|
.add(EntityAttributes.GENERIC_MAX_HEALTH, 16F)
|
||||||
|
.add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.5F);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double stepDistance;
|
||||||
|
private double nextStepDistance;
|
||||||
|
private boolean wasLeft;
|
||||||
|
|
||||||
|
public SpecterEntity(EntityType<? extends HostileEntity> entityType, World world) {
|
||||||
|
super(entityType, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
Vec3d prevPosition = getPos();
|
||||||
|
super.tick();
|
||||||
|
if (getBrightnessAtEyes() < 0.5F || getTarget() != null) {
|
||||||
|
ParticleUtils.spawnParticles(ParticleTypes.AMBIENT_ENTITY_EFFECT, this, 6);
|
||||||
|
|
||||||
|
if (getWorld().getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) {
|
||||||
|
if (getWorld().getBlockState(getBlockPos()).isIn(BlockTags.REPLACEABLE_BY_TREES)) {
|
||||||
|
getWorld().breakBlock(getBlockPos(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasVehicle() && isOnGround()) {
|
||||||
|
stepDistance += getPos().subtract(prevPosition).horizontalLength() * 0.6F;
|
||||||
|
if (stepDistance >= nextStepDistance) {
|
||||||
|
nextStepDistance = stepDistance + 1;
|
||||||
|
wasLeft = !wasLeft;
|
||||||
|
float offset = 0.4F;
|
||||||
|
float yaw = getHeadYaw();
|
||||||
|
Vec3d offsetVec = new Vec3d((wasLeft ? offset : -offset), 0, 0).rotateY(yaw);
|
||||||
|
getWorld().addParticle(new FootprintParticleEffect(yaw), true, getX() + offsetVec.getX(), getY(), getZ() + offsetVec.getZ(), 0, 0, 0);
|
||||||
|
ParticleUtils.spawnParticles(new BlockStateParticleEffect(ParticleTypes.BLOCK, getSteppingBlockState()), getWorld(), getPos(), 6);
|
||||||
|
playSound(getSteppingBlockState().getSoundGroup().getStepSound(), 0.5F, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getSoundPitch() {
|
||||||
|
return super.getSoundPitch() * 0.3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
protected SoundEvent getHurtSound(DamageSource source) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void playSwimSound(float volume) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSwimmingStart() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TargetGoal<T extends LivingEntity> extends ActiveTargetGoal<T> {
|
||||||
|
public TargetGoal(SpecterEntity specter, Class<T> targetEntityClass) {
|
||||||
|
super(specter, targetEntityClass, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public boolean canStart() {
|
||||||
|
return mob.getBrightnessAtEyes() < 0.5F && super.canStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour;
|
||||||
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
import com.minelittlepony.unicopia.projectile.MagicBeamEntity;
|
||||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||||
import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity;
|
import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
||||||
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
|
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
|
||||||
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
|
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
|
||||||
|
@ -17,10 +16,13 @@ import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityDimensions;
|
import net.minecraft.entity.EntityDimensions;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.SpawnGroup;
|
import net.minecraft.entity.SpawnGroup;
|
||||||
|
import net.minecraft.entity.SpawnRestriction.Location;
|
||||||
import net.minecraft.entity.decoration.painting.PaintingVariant;
|
import net.minecraft.entity.decoration.painting.PaintingVariant;
|
||||||
import net.minecraft.entity.mob.FlyingEntity;
|
import net.minecraft.entity.mob.FlyingEntity;
|
||||||
|
import net.minecraft.entity.mob.HostileEntity;
|
||||||
import net.minecraft.registry.*;
|
import net.minecraft.registry.*;
|
||||||
import net.minecraft.registry.tag.BiomeTags;
|
import net.minecraft.registry.tag.BiomeTags;
|
||||||
|
import net.minecraft.world.Heightmap.Type;
|
||||||
|
|
||||||
public interface UEntities {
|
public interface UEntities {
|
||||||
EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new)
|
EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new)
|
||||||
|
@ -74,6 +76,11 @@ public interface UEntities {
|
||||||
EntityType<IgnominiousBulbEntity> IGNOMINIOUS_BULB = register("ignominious_bulb", FabricEntityTypeBuilder.<IgnominiousBulbEntity>create(SpawnGroup.MISC, IgnominiousBulbEntity::new)
|
EntityType<IgnominiousBulbEntity> IGNOMINIOUS_BULB = register("ignominious_bulb", FabricEntityTypeBuilder.<IgnominiousBulbEntity>create(SpawnGroup.MISC, IgnominiousBulbEntity::new)
|
||||||
.trackRangeChunks(8)
|
.trackRangeChunks(8)
|
||||||
.dimensions(EntityDimensions.fixed(3, 2)));
|
.dimensions(EntityDimensions.fixed(3, 2)));
|
||||||
|
EntityType<SpecterEntity> SPECTER = register("specter", FabricEntityTypeBuilder.createMob().spawnGroup(SpawnGroup.MONSTER).entityFactory(SpecterEntity::new)
|
||||||
|
.spawnRestriction(Location.ON_GROUND, Type.WORLD_SURFACE, HostileEntity::canSpawnInDark)
|
||||||
|
.fireImmune()
|
||||||
|
.spawnableFarFromPlayer()
|
||||||
|
.dimensions(EntityDimensions.fixed(1, 2)));
|
||||||
|
|
||||||
static <T extends Entity> EntityType<T> register(String name, FabricEntityTypeBuilder<T> builder) {
|
static <T extends Entity> EntityType<T> register(String name, FabricEntityTypeBuilder<T> builder) {
|
||||||
EntityType<T> type = builder.build();
|
EntityType<T> type = builder.build();
|
||||||
|
@ -89,6 +96,7 @@ public interface UEntities {
|
||||||
FabricDefaultAttributeRegistry.register(FRIENDLY_CREEPER, FriendlyCreeperEntity.createCreeperAttributes());
|
FabricDefaultAttributeRegistry.register(FRIENDLY_CREEPER, FriendlyCreeperEntity.createCreeperAttributes());
|
||||||
FabricDefaultAttributeRegistry.register(LOOT_BUG, LootBugEntity.createSilverfishAttributes());
|
FabricDefaultAttributeRegistry.register(LOOT_BUG, LootBugEntity.createSilverfishAttributes());
|
||||||
FabricDefaultAttributeRegistry.register(IGNOMINIOUS_BULB, IgnominiousBulbEntity.createMobAttributes());
|
FabricDefaultAttributeRegistry.register(IGNOMINIOUS_BULB, IgnominiousBulbEntity.createMobAttributes());
|
||||||
|
FabricDefaultAttributeRegistry.register(SPECTER, SpecterEntity.createAttributes());
|
||||||
|
|
||||||
if (!Unicopia.getConfig().disableButterflySpawning.get()) {
|
if (!Unicopia.getConfig().disableButterflySpawning.get()) {
|
||||||
final Predicate<BiomeSelectionContext> butterflySpawnable = BiomeSelectors.foundInOverworld()
|
final Predicate<BiomeSelectionContext> butterflySpawnable = BiomeSelectors.foundInOverworld()
|
||||||
|
@ -105,6 +113,8 @@ public interface UEntities {
|
||||||
), SpawnGroup.AMBIENT, BUTTERFLY, 7, 5, 19);
|
), SpawnGroup.AMBIENT, BUTTERFLY, 7, 5, 19);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BiomeModifications.addSpawn(BiomeSelectors.spawnsOneOf(EntityType.ZOMBIE), SpawnGroup.MONSTER, SPECTER, 2, 1, 2);
|
||||||
|
|
||||||
UTradeOffers.bootstrap();
|
UTradeOffers.bootstrap();
|
||||||
EntityBehaviour.bootstrap();
|
EntityBehaviour.bootstrap();
|
||||||
UEntityAttributes.bootstrap();
|
UEntityAttributes.bootstrap();
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.minelittlepony.unicopia.particle;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.StringReader;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
|
import net.minecraft.particle.ParticleEffect;
|
||||||
|
import net.minecraft.particle.ParticleType;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
|
||||||
|
public record FootprintParticleEffect (
|
||||||
|
float yaw
|
||||||
|
) implements ParticleEffect {
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public static final ParticleEffect.Factory<FootprintParticleEffect> FACTORY = ParticleFactoryHelper.of(FootprintParticleEffect::new, FootprintParticleEffect::new);
|
||||||
|
|
||||||
|
protected FootprintParticleEffect(ParticleType<FootprintParticleEffect> type, StringReader reader) throws CommandSyntaxException {
|
||||||
|
this(ParticleFactoryHelper.readFloat(reader));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FootprintParticleEffect(ParticleType<FootprintParticleEffect> particleType, PacketByteBuf buf) {
|
||||||
|
this(buf.readFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParticleType<?> getType() {
|
||||||
|
return UParticles.FOOTPRINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(PacketByteBuf buf) {
|
||||||
|
buf.writeFloat(yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String asString() {
|
||||||
|
return String.format(Locale.ROOT, "%s %.2f", Registries.PARTICLE_TYPE.getId(getType()), yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,14 +14,12 @@ public interface UParticles {
|
||||||
ParticleType<MagicParticleEffect> UNICORN_MAGIC = register("unicorn_magic", FabricParticleTypes.complex(MagicParticleEffect.FACTORY));
|
ParticleType<MagicParticleEffect> UNICORN_MAGIC = register("unicorn_magic", FabricParticleTypes.complex(MagicParticleEffect.FACTORY));
|
||||||
DefaultParticleType CHANGELING_MAGIC = register("changeling_magic", FabricParticleTypes.simple());
|
DefaultParticleType CHANGELING_MAGIC = register("changeling_magic", FabricParticleTypes.simple());
|
||||||
DefaultParticleType BUBBLE = register("bubble", FabricParticleTypes.simple());
|
DefaultParticleType BUBBLE = register("bubble", FabricParticleTypes.simple());
|
||||||
|
ParticleType<FootprintParticleEffect> FOOTPRINT = register("footprint", FabricParticleTypes.complex(FootprintParticleEffect.FACTORY));
|
||||||
ParticleType<BlockStateParticleEffect> DUST_CLOUD = register("dust_cloud", FabricParticleTypes.complex(BlockStateParticleEffect.PARAMETERS_FACTORY));
|
ParticleType<BlockStateParticleEffect> DUST_CLOUD = register("dust_cloud", FabricParticleTypes.complex(BlockStateParticleEffect.PARAMETERS_FACTORY));
|
||||||
|
|
||||||
ParticleType<OrientedBillboardParticleEffect> RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY));
|
ParticleType<OrientedBillboardParticleEffect> RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY));
|
||||||
ParticleType<TargetBoundParticleEffect> RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.complex(TargetBoundParticleEffect.FACTORY));
|
ParticleType<TargetBoundParticleEffect> RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.complex(TargetBoundParticleEffect.FACTORY));
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
ParticleType<OrientedBillboardParticleEffect> MAGIC_RUNES = register("magic_runes", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY));
|
|
||||||
|
|
||||||
DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple());
|
DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple());
|
||||||
|
|
||||||
ParticleType<SphereParticleEffect> SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY));
|
ParticleType<SphereParticleEffect> SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY));
|
||||||
|
|
|
@ -355,6 +355,7 @@
|
||||||
|
|
||||||
"entity.unicopia.butterfly": "Butterfly",
|
"entity.unicopia.butterfly": "Butterfly",
|
||||||
"entity.unicopia.twittermite": "Twittermite",
|
"entity.unicopia.twittermite": "Twittermite",
|
||||||
|
"entity.unicopia.specter": "Specter",
|
||||||
"entity.unicopia.cast_spell": "Cast Spell",
|
"entity.unicopia.cast_spell": "Cast Spell",
|
||||||
"entity.unicopia.cast_spell.by": "a spell cast by %s",
|
"entity.unicopia.cast_spell.by": "a spell cast by %s",
|
||||||
"entity.unicopia.spellbook": "Spellbook",
|
"entity.unicopia.spellbook": "Spellbook",
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
"unicopia:footprint"
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
Loading…
Reference in a new issue