mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 06:26:43 +01:00
Added a rainboom ability for pegasi
This commit is contained in:
parent
4596b474b0
commit
38f1cc99c8
24 changed files with 667 additions and 106 deletions
|
@ -1,6 +1,7 @@
|
||||||
package com.minelittlepony.unicopia;
|
package com.minelittlepony.unicopia;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.tag.TagRegistry;
|
import net.fabricmc.fabric.api.tag.TagRegistry;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.tag.Tag;
|
import net.minecraft.tag.Tag;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
@ -13,6 +14,8 @@ public interface UTags {
|
||||||
Tag<Item> FAIRLY_TOXIC = register("fairly_toxic");
|
Tag<Item> FAIRLY_TOXIC = register("fairly_toxic");
|
||||||
Tag<Item> SEVERELY_TOXIC = register("severely_toxic");
|
Tag<Item> SEVERELY_TOXIC = register("severely_toxic");
|
||||||
|
|
||||||
|
Tag<Block> FRAGILE = TagRegistry.block(new Identifier("unicopia", "fragile"));
|
||||||
|
|
||||||
static Tag<Item> register(String name) {
|
static Tag<Item> register(String name) {
|
||||||
return TagRegistry.item(new Identifier("unicopia", name));
|
return TagRegistry.item(new Identifier("unicopia", name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ public interface Abilities {
|
||||||
Ability<?> GROW = register(new EarthPonyGrowAbility(), "grow", AbilitySlot.SECONDARY);
|
Ability<?> GROW = register(new EarthPonyGrowAbility(), "grow", AbilitySlot.SECONDARY);
|
||||||
Ability<?> STOMP = register(new EarthPonyStompAbility(), "stomp", AbilitySlot.TERTIARY);
|
Ability<?> STOMP = register(new EarthPonyStompAbility(), "stomp", AbilitySlot.TERTIARY);
|
||||||
|
|
||||||
|
// pegasus
|
||||||
|
Ability<?> RAINBOOM = register(new PegasusRainboomAbility(), "rainboom", AbilitySlot.PRIMARY);
|
||||||
|
|
||||||
// pegasus / bat / alicorn / changeling
|
// pegasus / bat / alicorn / changeling
|
||||||
Ability<?> CARRY = register(new CarryAbility(), "carry", AbilitySlot.PASSIVE);
|
Ability<?> CARRY = register(new CarryAbility(), "carry", AbilitySlot.PASSIVE);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.minelittlepony.unicopia.ability;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Race;
|
||||||
|
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.JoustingSpell;
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
|
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||||
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changeling ability to restore health from mobs
|
||||||
|
*/
|
||||||
|
public class PegasusRainboomAbility implements Ability<Hit> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWarmupTime(Pony player) {
|
||||||
|
return 59;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCooldownTime(Pony player) {
|
||||||
|
return 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUse(Race race) {
|
||||||
|
return race.canInteractWithClouds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Hit tryActivate(Pony player) {
|
||||||
|
|
||||||
|
if (!player.getMaster().isCreative() && player.getMagicalReserves().getMana().getPercentFill() < 0.2F) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.getPhysics().isFlying() && !player.hasSpell()) {
|
||||||
|
return Hit.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Hit.Serializer<Hit> getSerializer() {
|
||||||
|
return Hit.SERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCostEstimate(Pony player) {
|
||||||
|
return player.getMagicalReserves().getMana().getMax() * 0.9F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Pony player, Hit data) {
|
||||||
|
|
||||||
|
if (!player.getMaster().isCreative() && player.getMagicalReserves().getMana().getPercentFill() < 0.2F) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.getPhysics().isFlying() && !player.hasSpell()) {
|
||||||
|
player.getMagicalReserves().getMana().multiply(0.1F);
|
||||||
|
player.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, player.getPhysics().getMotionAngle()), player.getOriginVector(), Vec3d.ZERO);
|
||||||
|
player.setSpell(new JoustingSpell());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preApply(Pony player, AbilitySlot slot) {
|
||||||
|
player.getMagicalReserves().getExertion().add(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postApply(Pony player, AbilitySlot slot) {
|
||||||
|
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import java.util.stream.Stream;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Owned;
|
import com.minelittlepony.unicopia.Owned;
|
||||||
|
import com.minelittlepony.unicopia.entity.Physics;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleSource;
|
import com.minelittlepony.unicopia.particle.ParticleSource;
|
||||||
import com.minelittlepony.unicopia.util.VecHelper;
|
import com.minelittlepony.unicopia.util.VecHelper;
|
||||||
|
@ -21,6 +22,8 @@ import net.minecraft.world.World;
|
||||||
*/
|
*/
|
||||||
public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affine, Magical, ParticleSource {
|
public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affine, Magical, ParticleSource {
|
||||||
|
|
||||||
|
Physics getPhysics();
|
||||||
|
|
||||||
EffectSync getPrimarySpellSlot();
|
EffectSync getPrimarySpellSlot();
|
||||||
|
|
||||||
default void setSpell(@Nullable Spell spell) {
|
default void setSpell(@Nullable Spell spell) {
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
|
import com.minelittlepony.unicopia.UTags;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||||
|
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||||
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||||
|
import com.minelittlepony.unicopia.util.PosHelper;
|
||||||
|
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||||
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.GameRules;
|
||||||
|
|
||||||
|
public class JoustingSpell extends AbstractRangedAreaSpell implements Thrown {
|
||||||
|
|
||||||
|
private final int rad = 5;
|
||||||
|
private final Shape effect_range = new Sphere(false, rad);
|
||||||
|
|
||||||
|
private final ParticleHandle particlEffect = new ParticleHandle();
|
||||||
|
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "joust";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Affinity getAffinity() {
|
||||||
|
return Affinity.GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTint() {
|
||||||
|
return 0xBDBDF9;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDead() {
|
||||||
|
super.setDead();
|
||||||
|
particlEffect.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(Caster<?> source) {
|
||||||
|
LivingEntity owner = source.getMaster();
|
||||||
|
|
||||||
|
source.findAllEntitiesInRange(rad).forEach(e -> {
|
||||||
|
e.damage(MagicalDamageSource.create("rainboom", owner), 6);
|
||||||
|
});
|
||||||
|
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range).forEach(pos -> {
|
||||||
|
BlockState state = source.getWorld().getBlockState(pos);
|
||||||
|
if (state.isIn(UTags.FRAGILE) && canBreak(pos, owner)) {
|
||||||
|
owner.world.breakBlock(pos, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Vec3d motion = source.getEntity().getRotationVec(1).multiply(1.5);
|
||||||
|
Vec3d velocity = source.getEntity().getVelocity().add(motion);
|
||||||
|
|
||||||
|
while (velocity.length() > 3) {
|
||||||
|
velocity = velocity.multiply(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
source.getEntity().setVelocity(velocity);
|
||||||
|
if (source instanceof Pony) {
|
||||||
|
((Pony)source).getMagicalReserves().getEnergy().multiply(0.2F);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !source.getEntity().removed && age++ < 90 + 7 * (source.getLevel().get() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canBreak(BlockPos pos, LivingEntity entity) {
|
||||||
|
|
||||||
|
if (entity instanceof PlayerEntity) {
|
||||||
|
return entity.world.canPlayerModifyAt((PlayerEntity)entity, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity.world.getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(Caster<?> source) {
|
||||||
|
particlEffect.ifAbsent(source, spawner -> {
|
||||||
|
spawner.addParticle(UParticles.RAINBOOM_TRAIL, source.getOriginVector(), Vec3d.ZERO);
|
||||||
|
spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, source.getPhysics().getMotionAngle()), source.getOriginVector(), Vec3d.ZERO);
|
||||||
|
}).ifPresent(p -> p.attach(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toNBT(CompoundTag compound) {
|
||||||
|
super.toNBT(compound);
|
||||||
|
compound.putInt("age", age);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromNBT(CompoundTag compound) {
|
||||||
|
super.fromNBT(compound);
|
||||||
|
age = compound.getInt("age");
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,7 @@ public class SpellRegistry {
|
||||||
register(RevealingSpell::new);
|
register(RevealingSpell::new);
|
||||||
register(ScorchSpell::new);
|
register(ScorchSpell::new);
|
||||||
register(DisguiseSpell::new);
|
register(DisguiseSpell::new);
|
||||||
|
register(JoustingSpell::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.client.particle.ChangelingMagicParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.DiskParticle;
|
import com.minelittlepony.unicopia.client.particle.DiskParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.MagicParticle;
|
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.RaindropsParticle;
|
import com.minelittlepony.unicopia.client.particle.RaindropsParticle;
|
||||||
import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
@ -24,6 +25,7 @@ public interface URenderers {
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.CHANGELING_MAGIC, createFactory(ChangelingMagicParticle::new));
|
ParticleFactoryRegistry.getInstance().register(UParticles.CHANGELING_MAGIC, createFactory(ChangelingMagicParticle::new));
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.RAIN_DROPS, createFactory(RaindropsParticle::new));
|
ParticleFactoryRegistry.getInstance().register(UParticles.RAIN_DROPS, createFactory(RaindropsParticle::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.SPHERE, SphereParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.SPHERE, SphereParticle::new);
|
||||||
ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new);
|
ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.minelittlepony.unicopia.client.particle;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||||
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
|
import net.minecraft.client.render.Camera;
|
||||||
|
import net.minecraft.client.render.Tessellator;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.render.VertexFormats;
|
||||||
|
import net.minecraft.client.util.math.Vector3f;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public abstract class AbstractBillboardParticle extends Particle {
|
||||||
|
|
||||||
|
protected float scale = 1;
|
||||||
|
|
||||||
|
public AbstractBillboardParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||||
|
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParticleTextureSheet getType() {
|
||||||
|
return ParticleTextureSheet.CUSTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) {
|
||||||
|
Tessellator te = Tessellator.getInstance();
|
||||||
|
BufferBuilder buffer = te.getBuffer();
|
||||||
|
|
||||||
|
MinecraftClient.getInstance().getTextureManager().bindTexture(getTexture());
|
||||||
|
|
||||||
|
RenderSystem.disableCull();
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.blendFuncSeparate(
|
||||||
|
GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA,
|
||||||
|
GlStateManager.SrcFactor.ONE, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA
|
||||||
|
);
|
||||||
|
RenderSystem.alphaFunc(516, 0.003921569F);
|
||||||
|
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
renderQuads(te, buffer, renderX, renderY, renderZ, tickDelta);
|
||||||
|
|
||||||
|
RenderSystem.enableCull();
|
||||||
|
RenderSystem.defaultAlphaFunc();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta);
|
||||||
|
|
||||||
|
protected void renderQuad(Tessellator te, BufferBuilder buffer, Vector3f[] corners, float alpha, float tickDelta) {
|
||||||
|
int light = getColorMultiplier(tickDelta);
|
||||||
|
|
||||||
|
buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
|
||||||
|
buffer.vertex(corners[0].getX(), corners[0].getY(), corners[0].getZ()).texture(0, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
||||||
|
buffer.vertex(corners[1].getX(), corners[1].getY(), corners[1].getZ()).texture(1, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
||||||
|
buffer.vertex(corners[2].getX(), corners[2].getY(), corners[2].getZ()).texture(1, 1).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
||||||
|
buffer.vertex(corners[3].getX(), corners[3].getY(), corners[3].getZ()).texture(0, 1).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
||||||
|
|
||||||
|
te.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Identifier getTexture();
|
||||||
|
|
||||||
|
public float getScale(float tickDelta) {
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Particle scale(float scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
return super.scale(scale);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.minelittlepony.unicopia.client.particle;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
|
import net.minecraft.client.render.Camera;
|
||||||
|
import net.minecraft.client.render.Tessellator;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.util.math.Vector3f;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.util.math.Quaternion;
|
||||||
|
|
||||||
|
public abstract class OrientedBillboardParticle extends AbstractBillboardParticle {
|
||||||
|
|
||||||
|
protected boolean fixed;
|
||||||
|
protected Quaternion rotation = new Quaternion(0, 0, 0, 1);
|
||||||
|
|
||||||
|
public OrientedBillboardParticle(OrientedBillboardParticleEffect effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||||
|
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||||
|
|
||||||
|
fixed = effect.isAngleFixed();
|
||||||
|
if (!fixed) {
|
||||||
|
rotation.hamiltonProduct(Vector3f.POSITIVE_X.getDegreesQuaternion(180 - effect.getYaw()));
|
||||||
|
rotation.hamiltonProduct(Vector3f.POSITIVE_Y.getDegreesQuaternion(effect.getPitch()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) {
|
||||||
|
if (fixed) {
|
||||||
|
rotation = camera.getRotation();
|
||||||
|
}
|
||||||
|
super.buildGeometry(drawer, camera, tickDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
for(int k = 0; k < 4; ++k) {
|
||||||
|
Vector3f corner = corners[k];
|
||||||
|
corner.rotate(rotation);
|
||||||
|
corner.scale(scale);
|
||||||
|
corner.add(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
float alpha = colorAlpha * (1 - ((float)age / maxAge));
|
||||||
|
|
||||||
|
renderQuad(te, buffer, corners, alpha, tickDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,111 +1,32 @@
|
||||||
package com.minelittlepony.unicopia.client.particle;
|
package com.minelittlepony.unicopia.client.particle;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.particle.Particle;
|
|
||||||
import net.minecraft.client.particle.ParticleTextureSheet;
|
|
||||||
import net.minecraft.client.render.BufferBuilder;
|
|
||||||
import net.minecraft.client.render.Camera;
|
|
||||||
import net.minecraft.client.render.Tessellator;
|
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
|
||||||
import net.minecraft.client.render.VertexFormats;
|
|
||||||
import net.minecraft.client.util.math.Vector3f;
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.particle.DefaultParticleType;
|
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.sound.SoundEvents;
|
import net.minecraft.sound.SoundEvents;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Quaternion;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
|
|
||||||
public class RainboomParticle extends Particle {
|
|
||||||
|
|
||||||
|
public class RainboomParticle extends OrientedBillboardParticle {
|
||||||
private static final Identifier TEXTURE = new Identifier("unicopia", "textures/particles/rainboom_ring.png");
|
private static final Identifier TEXTURE = new Identifier("unicopia", "textures/particles/rainboom_ring.png");
|
||||||
|
|
||||||
protected float prevBaseSize = 0;
|
protected float prevBaseSize = 0;
|
||||||
protected float baseSize = 0;
|
protected float baseSize = 0;
|
||||||
protected float scale = 1;
|
|
||||||
|
|
||||||
protected Quaternion rotation;
|
public RainboomParticle(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);
|
||||||
public RainboomParticle(DefaultParticleType effect, ClientWorld world, double x, double y, double z, double angleX, double angleY, double angleZ) {
|
|
||||||
super(world, x, y, z);
|
|
||||||
|
|
||||||
rotation = Vector3f.POSITIVE_X.getRadialQuaternion((float)angleX);
|
|
||||||
rotation.hamiltonProduct(Vector3f.POSITIVE_Y.getRadialQuaternion((float)angleY));
|
|
||||||
rotation.hamiltonProduct(Vector3f.POSITIVE_Z.getRadialQuaternion((float)angleZ));
|
|
||||||
setMaxAge(40);
|
setMaxAge(40);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ParticleTextureSheet getType() {
|
public float getScale(float tickDelta) {
|
||||||
return ParticleTextureSheet.CUSTOM;
|
return MathHelper.lerp(tickDelta, prevBaseSize, baseSize) * super.getScale(tickDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) {
|
protected Identifier getTexture() {
|
||||||
Vec3d cam = camera.getPos();
|
return TEXTURE;
|
||||||
|
|
||||||
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.0F, -1.0F, 0.0F),
|
|
||||||
new Vector3f(-1.0F, 1.0F, 0.0F),
|
|
||||||
new Vector3f(1.0F, 1.0F, 0.0F),
|
|
||||||
new Vector3f(1.0F, -1.0F, 0.0F)
|
|
||||||
};
|
|
||||||
float scale = getSize(tickDelta);
|
|
||||||
|
|
||||||
for(int k = 0; k < 4; ++k) {
|
|
||||||
Vector3f corner = corners[k];
|
|
||||||
corner.rotate(rotation);
|
|
||||||
corner.scale(scale);
|
|
||||||
corner.add(renderX, renderY, renderZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
float alpha = colorAlpha * (1 - ((float)age / maxAge));
|
|
||||||
|
|
||||||
int light = getColorMultiplier(tickDelta);
|
|
||||||
|
|
||||||
Tessellator te = Tessellator.getInstance();
|
|
||||||
BufferBuilder buffer = te.getBuffer();
|
|
||||||
|
|
||||||
MinecraftClient.getInstance().getTextureManager().bindTexture(TEXTURE);
|
|
||||||
|
|
||||||
RenderSystem.disableCull();
|
|
||||||
RenderSystem.enableBlend();
|
|
||||||
RenderSystem.blendFuncSeparate(
|
|
||||||
GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA,
|
|
||||||
GlStateManager.SrcFactor.ONE, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA
|
|
||||||
);
|
|
||||||
RenderSystem.alphaFunc(516, 0.003921569F);
|
|
||||||
|
|
||||||
buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
|
|
||||||
buffer.vertex(corners[0].getX(), corners[0].getY(), corners[0].getZ()).texture(0, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
|
||||||
buffer.vertex(corners[1].getX(), corners[1].getY(), corners[1].getZ()).texture(1, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
|
||||||
buffer.vertex(corners[2].getX(), corners[2].getY(), corners[2].getZ()).texture(0, 0).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
|
||||||
buffer.vertex(corners[3].getX(), corners[3].getY(), corners[3].getZ()).texture(0, 1).color(colorRed, colorGreen, colorBlue, alpha).light(light).next();
|
|
||||||
|
|
||||||
te.draw();
|
|
||||||
|
|
||||||
RenderSystem.enableCull();
|
|
||||||
RenderSystem.defaultAlphaFunc();
|
|
||||||
RenderSystem.defaultBlendFunc();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getSize(float tickDelta) {
|
|
||||||
return MathHelper.lerp(tickDelta, prevBaseSize, baseSize) * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Particle scale(float scale) {
|
|
||||||
this.scale = scale;
|
|
||||||
return super.scale(scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -115,9 +36,9 @@ public class RainboomParticle extends Particle {
|
||||||
prevBaseSize = baseSize;
|
prevBaseSize = baseSize;
|
||||||
baseSize++;
|
baseSize++;
|
||||||
|
|
||||||
if (this.age == 1) {
|
if (age == 1) {
|
||||||
this.world.playSound(x, y, z, SoundEvents.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.AMBIENT, 5, 0.3F, true);
|
world.playSound(x, y, z, SoundEvents.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.AMBIENT, 5, 0.3F, true);
|
||||||
this.world.playSound(x, y, z, SoundEvents.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.AMBIENT, 10, 1.3F, true);
|
world.playSound(x, y, z, SoundEvents.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.AMBIENT, 10, 1.3F, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
package com.minelittlepony.unicopia.client.particle;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment;
|
||||||
|
import com.minelittlepony.unicopia.particle.ParticleHandle.Link;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
|
import net.minecraft.client.render.Tessellator;
|
||||||
|
import net.minecraft.client.util.math.Vector3f;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.particle.DefaultParticleType;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class RainbowTrailParticle extends AbstractBillboardParticle implements Attachment {
|
||||||
|
private static final Identifier TEXTURE = new Identifier("unicopia", "textures/particles/rainboom_trail.png");
|
||||||
|
|
||||||
|
private final List<Segment> segments = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Link link = new Link();
|
||||||
|
|
||||||
|
public RainbowTrailParticle(DefaultParticleType effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||||
|
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||||
|
segments.add(new Segment(new Vec3d(x, y, z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Identifier getTexture() {
|
||||||
|
return TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStillAlive() {
|
||||||
|
return age < (maxAge - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(Caster<?> caster) {
|
||||||
|
link.attach(caster);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void detach() {
|
||||||
|
link.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribute(int key, Object value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta) {
|
||||||
|
for (int i = 0; i < segments.size() - 1; i++) {
|
||||||
|
Vector3f[] corners = segments.get(i).getPlane(segments.get(i + 1));
|
||||||
|
float scale = getScale(tickDelta);
|
||||||
|
|
||||||
|
for (int k = 0; k < 4; ++k) {
|
||||||
|
Vector3f corner = corners[k];
|
||||||
|
corner.scale(scale);
|
||||||
|
corner.add(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderQuad(te, buffer, corners, segments.get(i).getAlpha(), tickDelta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void follow(Caster<?> caster) {
|
||||||
|
Vec3d next = caster.getOriginVector();
|
||||||
|
|
||||||
|
if (segments.isEmpty()) {
|
||||||
|
segments.add(new Segment(next));
|
||||||
|
} else {
|
||||||
|
Vec3d last = segments.get(segments.size() - 1).position;
|
||||||
|
if (next.distanceTo(last) > 0.2) {
|
||||||
|
segments.add(new Segment(next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
age = 0;
|
||||||
|
|
||||||
|
if (link.linked()) {
|
||||||
|
link.ifAbsent(() -> {}).ifPresent(this::follow);
|
||||||
|
} else {
|
||||||
|
follow(Pony.of(MinecraftClient.getInstance().player));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segments.size() > 1) {
|
||||||
|
segments.removeIf(Segment::tick);
|
||||||
|
}
|
||||||
|
if (segments.isEmpty()) {
|
||||||
|
markDead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class Segment {
|
||||||
|
Vec3d position;
|
||||||
|
Vector3f offset;
|
||||||
|
|
||||||
|
int age;
|
||||||
|
int maxAge;
|
||||||
|
|
||||||
|
Segment(Vec3d position) {
|
||||||
|
this.position = position;
|
||||||
|
this.offset = new Vector3f((float)(position.getX() - x), (float)(position.getY() - y), (float)(position.getZ() - z));
|
||||||
|
this.maxAge = 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getAlpha() {
|
||||||
|
return colorAlpha * (1 - ((float)age / maxAge));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean tick() {
|
||||||
|
return segments.indexOf(this) < segments.size() - 1 && age++ >= maxAge;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3f[] getPlane(Segment to) {
|
||||||
|
float fromX = offset.getX();
|
||||||
|
float toX = to.offset.getX();
|
||||||
|
|
||||||
|
float fromZ = offset.getZ();
|
||||||
|
float toZ = to.offset.getZ();
|
||||||
|
|
||||||
|
float fromTopY = offset.getY() + 1;
|
||||||
|
float fromBottomY = offset.getY();
|
||||||
|
|
||||||
|
float toTopY = to.offset.getY() + 1;
|
||||||
|
float toBottomY = to.offset.getY();
|
||||||
|
|
||||||
|
return new Vector3f[]{
|
||||||
|
new Vector3f(fromX, fromBottomY, fromZ), // bottom left
|
||||||
|
new Vector3f(fromX, fromTopY, fromZ), // top left
|
||||||
|
new Vector3f(toX, toTopY, toZ), // top right
|
||||||
|
new Vector3f(toX, toBottomY, toZ) // bottom right
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.data.DataTracker;
|
import net.minecraft.entity.data.DataTracker;
|
||||||
import net.minecraft.entity.data.TrackedData;
|
import net.minecraft.entity.data.TrackedData;
|
||||||
|
|
|
@ -16,7 +16,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class EntityPhysics<T extends Equine<?> & Owned<? extends Entity>> implements Physics, Copieable<EntityPhysics<T>> {
|
public class EntityPhysics<T extends Owned<? extends Entity>> implements Physics, Copieable<EntityPhysics<T>> {
|
||||||
|
|
||||||
private float gravity = 1;
|
private float gravity = 1;
|
||||||
|
|
||||||
|
@ -31,6 +31,11 @@ public class EntityPhysics<T extends Equine<?> & Owned<? extends Entity>> implem
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3d getMotionAngle() {
|
||||||
|
return new Vec3d(pony.getMaster().getPitch(1), pony.getMaster().getYaw(1), 0);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double calcGravity(double worldConstant) {
|
public double calcGravity(double worldConstant) {
|
||||||
return worldConstant * getGravityModifier();
|
return worldConstant * getGravityModifier();
|
||||||
|
@ -94,17 +99,11 @@ public class EntityPhysics<T extends Equine<?> & Owned<? extends Entity>> implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toNBT(CompoundTag compound) {
|
public void toNBT(CompoundTag compound) {
|
||||||
if (gravity != 0) {
|
compound.putFloat("gravity", gravity);
|
||||||
compound.putFloat("gravity", gravity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromNBT(CompoundTag compound) {
|
public void fromNBT(CompoundTag compound) {
|
||||||
if (compound.contains("gravity")) {
|
gravity = compound.getFloat("gravity");
|
||||||
gravity = compound.getFloat("gravity");
|
|
||||||
} else {
|
|
||||||
gravity = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,14 @@ package com.minelittlepony.unicopia.entity;
|
||||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public interface Physics extends NbtSerialisable {
|
public interface Physics extends NbtSerialisable {
|
||||||
|
|
||||||
double calcGravity(double worldConstant);
|
double calcGravity(double worldConstant);
|
||||||
|
|
||||||
|
Vec3d getMotionAngle();
|
||||||
|
|
||||||
float getGravityModifier();
|
float getGravityModifier();
|
||||||
|
|
||||||
void setBaseGravityModifier(float constant);
|
void setBaseGravityModifier(float constant);
|
||||||
|
|
|
@ -344,5 +344,4 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
||||||
|
|
||||||
pony.getMaster().calculateDimensions();
|
pony.getMaster().calculateDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,7 +310,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
||||||
prevSneaking = entity.isSneaking();
|
prevSneaking = entity.isSneaking();
|
||||||
prevLanded = entity.isOnGround();
|
prevLanded = entity.isOnGround();
|
||||||
|
|
||||||
|
|
||||||
if (gravity.isGravityNegative() && entity.getY() > entity.world.getHeight() + 64) {
|
if (gravity.isGravityNegative() && entity.getY() > entity.world.getHeight() + 64) {
|
||||||
entity.damage(DamageSource.OUT_OF_WORLD, 4.0F);
|
entity.damage(DamageSource.OUT_OF_WORLD, 4.0F);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import net.minecraft.util.registry.Registry;
|
||||||
public class MagicParticleEffect implements ParticleEffect {
|
public class MagicParticleEffect implements ParticleEffect {
|
||||||
|
|
||||||
public static final MagicParticleEffect UNICORN = new MagicParticleEffect(false, 0, 0, 0);
|
public static final MagicParticleEffect UNICORN = new MagicParticleEffect(false, 0, 0, 0);
|
||||||
public static final ParticleEffect.Factory<MagicParticleEffect> UNICORN_FACTORY = new ParticleEffect.Factory<MagicParticleEffect>() {
|
public static final ParticleEffect.Factory<MagicParticleEffect> FACTORY = new ParticleEffect.Factory<MagicParticleEffect>() {
|
||||||
@Override
|
@Override
|
||||||
public MagicParticleEffect read(ParticleType<MagicParticleEffect> particleType, StringReader reader) throws CommandSyntaxException {
|
public MagicParticleEffect read(ParticleType<MagicParticleEffect> particleType, StringReader reader) throws CommandSyntaxException {
|
||||||
reader.expect(' ');
|
reader.expect(' ');
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
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.util.math.Vec3d;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
public class OrientedBillboardParticleEffect implements ParticleEffect {
|
||||||
|
public static final ParticleEffect.Factory<OrientedBillboardParticleEffect> FACTORY = new ParticleEffect.Factory<OrientedBillboardParticleEffect>() {
|
||||||
|
@Override
|
||||||
|
public OrientedBillboardParticleEffect read(ParticleType<OrientedBillboardParticleEffect> type, StringReader reader) throws CommandSyntaxException {
|
||||||
|
reader.expect(' ');
|
||||||
|
boolean fixed = reader.readBoolean();
|
||||||
|
reader.expect(' ');
|
||||||
|
float yaw = (float)reader.readDouble();
|
||||||
|
reader.expect(' ');
|
||||||
|
float pitch = (float)reader.readDouble();
|
||||||
|
return new OrientedBillboardParticleEffect(type, fixed, yaw, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OrientedBillboardParticleEffect read(ParticleType<OrientedBillboardParticleEffect> particleType, PacketByteBuf buf) {
|
||||||
|
return new OrientedBillboardParticleEffect(particleType, buf.readBoolean(), buf.readFloat(), buf.readFloat());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final boolean fixed;
|
||||||
|
private final float yaw;
|
||||||
|
private final float pitch;
|
||||||
|
|
||||||
|
private final ParticleType<OrientedBillboardParticleEffect> type;
|
||||||
|
|
||||||
|
public OrientedBillboardParticleEffect(ParticleType<OrientedBillboardParticleEffect> type, Vec3d orientation) {
|
||||||
|
this(type, (float)orientation.getX(), (float)orientation.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrientedBillboardParticleEffect(ParticleType<OrientedBillboardParticleEffect> type, float yaw, float pitch) {
|
||||||
|
this(type, true, yaw, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrientedBillboardParticleEffect(ParticleType<OrientedBillboardParticleEffect> type, boolean fixed, float yaw, float pitch) {
|
||||||
|
this.fixed = fixed;
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAngleFixed() {
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getYaw() {
|
||||||
|
return yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPitch() {
|
||||||
|
return pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParticleType<?> getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(PacketByteBuf buf) {
|
||||||
|
buf.writeBoolean(fixed);
|
||||||
|
buf.writeFloat(yaw);
|
||||||
|
buf.writeFloat(pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String asString() {
|
||||||
|
return String.format(Locale.ROOT, "%s %b %.2f %.2f", Registry.PARTICLE_TYPE.getId(getType()), fixed, yaw, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -68,6 +68,11 @@ public class ParticleHandle {
|
||||||
this.effect = caster.getSpell(false).getName();
|
this.effect = caster.getSpell(false).getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void detach() {
|
||||||
|
linked = false;
|
||||||
|
caster = Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean linked() {
|
public boolean linked() {
|
||||||
return linked;
|
return linked;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,11 @@ import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
public interface UParticles {
|
public interface UParticles {
|
||||||
|
|
||||||
ParticleType<MagicParticleEffect> UNICORN_MAGIC = register("unicorn_magic", FabricParticleTypes.complex(MagicParticleEffect.UNICORN_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 RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.simple());
|
ParticleType<OrientedBillboardParticleEffect> RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY));
|
||||||
|
DefaultParticleType RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.simple());
|
||||||
|
|
||||||
DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple());
|
DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple());
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ import com.minelittlepony.unicopia.ability.magic.Magical;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
|
||||||
|
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||||
|
import com.minelittlepony.unicopia.entity.Physics;
|
||||||
import com.minelittlepony.unicopia.network.Channel;
|
import com.minelittlepony.unicopia.network.Channel;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
|
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
|
||||||
|
@ -49,6 +51,8 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
|
|
||||||
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
|
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
|
||||||
|
|
||||||
|
private final EntityPhysics<MagicProjectileEntity> physics = new EntityPhysics<>(this);
|
||||||
|
|
||||||
private BlockPos lastBlockPos;
|
private BlockPos lastBlockPos;
|
||||||
|
|
||||||
public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world) {
|
public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world) {
|
||||||
|
@ -97,6 +101,11 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
return LEVELS;
|
return LEVELS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Physics getPhysics() {
|
||||||
|
return physics;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Affinity getAffinity() {
|
public Affinity getAffinity() {
|
||||||
return hasSpell() ? Affinity.NEUTRAL : getSpell(true).getAffinity();
|
return hasSpell() ? Affinity.NEUTRAL : getSpell(true).getAffinity();
|
||||||
|
@ -206,7 +215,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
@Override
|
@Override
|
||||||
public void readCustomDataFromTag(CompoundTag compound) {
|
public void readCustomDataFromTag(CompoundTag compound) {
|
||||||
super.readCustomDataFromTag(compound);
|
super.readCustomDataFromTag(compound);
|
||||||
|
physics.fromNBT(compound);
|
||||||
if (compound.contains("effect")) {
|
if (compound.contains("effect")) {
|
||||||
setSpell(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect")));
|
setSpell(SpellRegistry.instance().createEffectFromNBT(compound.getCompound("effect")));
|
||||||
}
|
}
|
||||||
|
@ -215,6 +224,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
@Override
|
@Override
|
||||||
public void writeCustomDataToTag(CompoundTag compound) {
|
public void writeCustomDataToTag(CompoundTag compound) {
|
||||||
super.writeCustomDataToTag(compound);
|
super.writeCustomDataToTag(compound);
|
||||||
|
physics.toNBT(compound);
|
||||||
|
|
||||||
if (hasSpell()) {
|
if (hasSpell()) {
|
||||||
compound.put("effect", SpellRegistry.toNBT(getSpell(true)));
|
compound.put("effect", SpellRegistry.toNBT(getSpell(true)));
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
{
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
41
src/main/resources/data/unicopia/tags/blocks/fragile.json
Normal file
41
src/main/resources/data/unicopia/tags/blocks/fragile.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"minecraft:glass",
|
||||||
|
"minecraft:glass_pane",
|
||||||
|
"minecraft:white_stained_glass",
|
||||||
|
"minecraft:orange_stained_glass",
|
||||||
|
"minecraft:magenta_stained_glass",
|
||||||
|
"minecraft:light_blue_stained_glass",
|
||||||
|
"minecraft:yellow_stained_glass",
|
||||||
|
"minecraft:lime_stained_glass",
|
||||||
|
"minecraft:pink_stained_glass",
|
||||||
|
"minecraft:gray_stained_glass",
|
||||||
|
"minecraft:light_gray_stained_glass",
|
||||||
|
"minecraft:cyan_stained_glass",
|
||||||
|
"minecraft:purple_stained_glass",
|
||||||
|
"minecraft:blue_stained_glass",
|
||||||
|
"minecraft:brown_stained_glass",
|
||||||
|
"minecraft:green_stained_glass",
|
||||||
|
"minecraft:red_stained_glass",
|
||||||
|
"minecraft:black_stained_glass",
|
||||||
|
"minecraft:white_stained_glass_pane",
|
||||||
|
"minecraft:orange_stained_glass_pane",
|
||||||
|
"minecraft:magenta_stained_glass_pane",
|
||||||
|
"minecraft:light_blue_stained_glass_pane",
|
||||||
|
"minecraft:yellow_stained_glass_pane",
|
||||||
|
"minecraft:lime_stained_glass_pane",
|
||||||
|
"minecraft:pink_stained_glass_pane",
|
||||||
|
"minecraft:gray_stained_glass_pane",
|
||||||
|
"minecraft:light_gray_stained_glass_pane",
|
||||||
|
"minecraft:cyan_stained_glass_pane",
|
||||||
|
"minecraft:purple_stained_glass_pane",
|
||||||
|
"minecraft:blue_stained_glass_pane",
|
||||||
|
"minecraft:brown_stained_glass_pane",
|
||||||
|
"minecraft:green_stained_glass_pane",
|
||||||
|
"minecraft:red_stained_glass_pane",
|
||||||
|
"minecraft:black_stained_glass_pane",
|
||||||
|
"minecraft:vine",
|
||||||
|
"minecraft:lily_pad"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue