mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 06:26:43 +01:00
wip gui for dismissing spells remotely
This commit is contained in:
parent
c84fda37c4
commit
1a3eb9f0f6
12 changed files with 441 additions and 115 deletions
|
@ -21,6 +21,8 @@ public class InteractionManager {
|
||||||
public static final int SOUND_MINECART = 3;
|
public static final int SOUND_MINECART = 3;
|
||||||
public static final int SOUND_GLIDING = 4;
|
public static final int SOUND_GLIDING = 4;
|
||||||
|
|
||||||
|
public static final int SCREEN_DISPELL_ABILITY = 0;
|
||||||
|
|
||||||
public static InteractionManager INSTANCE = new InteractionManager();
|
public static InteractionManager INSTANCE = new InteractionManager();
|
||||||
|
|
||||||
public static InteractionManager instance() {
|
public static InteractionManager instance() {
|
||||||
|
@ -64,6 +66,9 @@ public class InteractionManager {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openScreen(int type) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Side-independent method to create a new player.
|
* Side-independent method to create a new player.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.EquinePredicates;
|
import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
|
import com.minelittlepony.unicopia.InteractionManager;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.ability.data.Pos;
|
import com.minelittlepony.unicopia.ability.data.Pos;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
@ -11,6 +12,8 @@ import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.util.RayTraceHelper;
|
import com.minelittlepony.unicopia.util.RayTraceHelper;
|
||||||
import com.minelittlepony.unicopia.util.VecHelper;
|
import com.minelittlepony.unicopia.util.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispells an active spell
|
* Dispells an active spell
|
||||||
*/
|
*/
|
||||||
|
@ -40,11 +43,17 @@ public class UnicornDispellAbility implements Ability<Pos> {
|
||||||
public boolean onQuickAction(Pony player, ActivationType type) {
|
public boolean onQuickAction(Pony player, ActivationType type) {
|
||||||
|
|
||||||
if (type.getTapCount() > 1) {
|
if (type.getTapCount() > 1) {
|
||||||
player.getSpellSlot().clear();
|
if (player.getSpellSlot().clear()) {
|
||||||
|
player.getMaster().sendMessage(new TranslatableText("gui.unicopia.action.spells_cleared"), true);
|
||||||
|
} else {
|
||||||
|
player.getMaster().sendMessage(new TranslatableText("gui.unicopia.action.no_spells_cleared"), true);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (type == ActivationType.TAP) {
|
|
||||||
// TODO: gui to remove spells
|
if (type == ActivationType.TAP && player.isClient()) {
|
||||||
|
InteractionManager.instance().openScreen(InteractionManager.SCREEN_DISPELL_ABILITY);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
|
@ -20,7 +20,9 @@ public interface SpellContainer {
|
||||||
public void put(Spell effect) { }
|
public void put(Spell effect) { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() { }
|
public boolean clear() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeIf(Predicate<Spell> effect, boolean update) {
|
public boolean removeIf(Predicate<Spell> effect, boolean update) {
|
||||||
|
@ -36,6 +38,11 @@ public interface SpellContainer {
|
||||||
public boolean contains(UUID id) {
|
public boolean contains(UUID id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<Spell> stream(boolean update) {
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,10 +88,12 @@ public interface SpellContainer {
|
||||||
*/
|
*/
|
||||||
boolean forEach(Function<Spell, Operation> action, boolean update);
|
boolean forEach(Function<Spell, Operation> action, boolean update);
|
||||||
|
|
||||||
|
Stream<Spell> stream(boolean update);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all effects currently active in this slot.
|
* Removes all effects currently active in this slot.
|
||||||
*/
|
*/
|
||||||
void clear();
|
boolean clear();
|
||||||
|
|
||||||
interface Delegate extends SpellContainer {
|
interface Delegate extends SpellContainer {
|
||||||
|
|
||||||
|
@ -121,8 +130,13 @@ public interface SpellContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void clear() {
|
default boolean clear() {
|
||||||
delegate().clear();
|
return delegate().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Stream<Spell> stream(boolean update) {
|
||||||
|
return delegate().stream(update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import com.minelittlepony.unicopia.FlightType;
|
import com.minelittlepony.unicopia.FlightType;
|
||||||
import com.minelittlepony.unicopia.InteractionManager;
|
import com.minelittlepony.unicopia.InteractionManager;
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
|
import com.minelittlepony.unicopia.client.gui.DismissSpellScreen;
|
||||||
import com.minelittlepony.unicopia.client.sound.LoopingSoundInstance;
|
import com.minelittlepony.unicopia.client.sound.LoopingSoundInstance;
|
||||||
import com.minelittlepony.unicopia.client.sound.MotionBasedSoundInstance;
|
import com.minelittlepony.unicopia.client.sound.MotionBasedSoundInstance;
|
||||||
import com.minelittlepony.unicopia.entity.effect.UEffects;
|
import com.minelittlepony.unicopia.entity.effect.UEffects;
|
||||||
|
@ -73,6 +74,15 @@ public class ClientInteractionManager extends InteractionManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openScreen(int type) {
|
||||||
|
client.execute(() -> {
|
||||||
|
if (type == SCREEN_DISPELL_ABILITY) {
|
||||||
|
client.setScreen(new DismissSpellScreen());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public PlayerEntity createPlayer(World world, GameProfile profile) {
|
public PlayerEntity createPlayer(World world, GameProfile profile) {
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
package com.minelittlepony.unicopia.client.gui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.minelittlepony.common.client.gui.GameGui;
|
||||||
|
import com.minelittlepony.unicopia.USounds;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
|
import com.minelittlepony.unicopia.client.FlowingText;
|
||||||
|
import com.minelittlepony.unicopia.client.particle.SphereModel;
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.sound.PositionedSoundInstance;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.text.MutableText;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
import net.minecraft.util.math.Vector4f;
|
||||||
|
|
||||||
|
public class DismissSpellScreen extends GameGui {
|
||||||
|
private final Pony pony = Pony.of(MinecraftClient.getInstance().player);
|
||||||
|
|
||||||
|
private final List<Spell> spells;
|
||||||
|
|
||||||
|
private final List<Entry> entries = new ArrayList<>();
|
||||||
|
|
||||||
|
private double lastMouseX;
|
||||||
|
private double lastMouseY;
|
||||||
|
|
||||||
|
public DismissSpellScreen() {
|
||||||
|
super(new TranslatableText("gui.unicopia.dismiss_spell"));
|
||||||
|
|
||||||
|
spells = pony.getSpellSlot().stream(true).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
entries.clear();
|
||||||
|
|
||||||
|
double azimuth = 0;
|
||||||
|
int ring = 1;
|
||||||
|
|
||||||
|
for (Spell spell : spells) {
|
||||||
|
|
||||||
|
double increment = Math.PI / (8 * ring);
|
||||||
|
|
||||||
|
azimuth += increment;
|
||||||
|
if (azimuth > Math.PI) {
|
||||||
|
azimuth = 0;
|
||||||
|
ring++;
|
||||||
|
}
|
||||||
|
|
||||||
|
double radius = 75 * ring - 25;
|
||||||
|
|
||||||
|
Vector4f pos = SphereModel.convertToCartesianCoord(radius, azimuth, azimuth);
|
||||||
|
pos.add(0, -(float)radius / 2F, 0, 0);
|
||||||
|
|
||||||
|
entries.add(new Entry(spell, pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
|
fillGradient(matrices, 0, 0, width, height / 2, 0xF0101010, 0x80101010);
|
||||||
|
fillGradient(matrices, 0, height / 2, width, height, 0x80101010, 0xF0101010);
|
||||||
|
|
||||||
|
super.render(matrices, mouseX, mouseY, delta);
|
||||||
|
|
||||||
|
matrices.push();
|
||||||
|
matrices.translate(width - mouseX, height - mouseY, 0);
|
||||||
|
|
||||||
|
mouseX = -width + mouseX * 2;
|
||||||
|
mouseY = -height + mouseY * 2;
|
||||||
|
|
||||||
|
DrawableUtil.drawLine(matrices, 0, 0, mouseX, mouseY, 0xFFFFFF88);
|
||||||
|
DrawableUtil.drawArc(matrices, 40, 80, 0, Math.PI * 2, 0x00000010, false);
|
||||||
|
DrawableUtil.drawArc(matrices, 160, 1600, 0, Math.PI * 2, 0x00000020, false);
|
||||||
|
|
||||||
|
for (Entry entry : entries) {
|
||||||
|
entry.render(this, matrices, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
matrices.push();
|
||||||
|
DrawableUtil.drawCircle(matrices, 2, 0, Math.PI * 2, 0xFFAAFF99, false);
|
||||||
|
matrices.translate(mouseX, mouseY, 0);
|
||||||
|
DrawableUtil.drawLine(matrices, 0, -4, 0, 4, 0xFFAAFF99);
|
||||||
|
DrawableUtil.drawLine(matrices, -4, 0, 4, 0, 0xFFAAFF99);
|
||||||
|
matrices.pop();
|
||||||
|
|
||||||
|
matrices.pop();
|
||||||
|
|
||||||
|
matrices.push();
|
||||||
|
matrices.translate(0, 0, 300);
|
||||||
|
Text cancel = new LiteralText("Press ESC to cancel");
|
||||||
|
getFont().drawWithShadow(matrices, cancel, (width - getFont().getWidth(cancel)) / 2, height - 30, 0xFFFFFFFF);
|
||||||
|
matrices.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPauseScreen() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldCloseOnEsc() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Entry {
|
||||||
|
|
||||||
|
private final List<Text> tooltip = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Spell spell;
|
||||||
|
private final Vector4f pos;
|
||||||
|
|
||||||
|
private boolean lastMouseOver;
|
||||||
|
|
||||||
|
public Entry(Spell spell, Vector4f pos) {
|
||||||
|
this.spell = spell;
|
||||||
|
this.pos = pos;
|
||||||
|
|
||||||
|
MutableText name = spell.getType().getName().shallowCopy();
|
||||||
|
name.setStyle(name.getStyle().withColor(spell.getType().getColor()));
|
||||||
|
|
||||||
|
tooltip.add(new TranslatableText("Spell Type: %s", name));
|
||||||
|
spell.getType().getTraits().appendTooltip(tooltip);
|
||||||
|
tooltip.add(LiteralText.EMPTY);
|
||||||
|
tooltip.add(new TranslatableText("Affinity: %s", spell.getAffinity().name()).formatted(spell.getAffinity().getColor()));
|
||||||
|
tooltip.add(LiteralText.EMPTY);
|
||||||
|
tooltip.addAll(FlowingText.wrap(new TranslatableText(spell.getType().getTranslationKey() + ".lore").formatted(spell.getAffinity().getColor()), 180).toList());
|
||||||
|
tooltip.add(LiteralText.EMPTY);
|
||||||
|
tooltip.add(new TranslatableText("[Click to Discard]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMouseOver(int mouseX, int mouseY) {
|
||||||
|
return squareDistance(mouseX, mouseY, pos.getX(), pos.getY()) < 75;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(DismissSpellScreen screen, MatrixStack matrices, int mouseX, int mouseY) {
|
||||||
|
Vector4f copy = new Vector4f(pos.getX(), pos.getY(), pos.getZ(), pos.getW());
|
||||||
|
copy.transform(matrices.peek().getPositionMatrix());
|
||||||
|
|
||||||
|
boolean hovered = isMouseOver(mouseX, mouseY);
|
||||||
|
|
||||||
|
MatrixStack modelStack = RenderSystem.getModelViewStack();
|
||||||
|
modelStack.push();
|
||||||
|
float scale = 1.1F;
|
||||||
|
modelStack.translate(-21, -14, 0);
|
||||||
|
modelStack.scale(scale, scale, 1);
|
||||||
|
RenderSystem.applyModelViewMatrix();
|
||||||
|
|
||||||
|
screen.client.getItemRenderer().renderGuiItemIcon(spell.getType().getDefualtStack(), (int)copy.getX() - 8, (int)copy.getY() - 8);
|
||||||
|
|
||||||
|
modelStack.pop();
|
||||||
|
RenderSystem.applyModelViewMatrix();
|
||||||
|
|
||||||
|
matrices.push();
|
||||||
|
matrices.translate(pos.getX(), pos.getY(), 0);
|
||||||
|
|
||||||
|
int color = spell.getType().getColor() << 2;
|
||||||
|
|
||||||
|
DrawableUtil.drawArc(matrices, 7, 8, 0, Math.PI * 2, color | 0x00000088, false);
|
||||||
|
|
||||||
|
if (hovered) {
|
||||||
|
DrawableUtil.drawArc(matrices, 0, 8, 0, Math.PI * 2, color | 0x000000FF, false);
|
||||||
|
screen.renderTooltip(matrices, tooltip, 0, 0);
|
||||||
|
|
||||||
|
if (!lastMouseOver) {
|
||||||
|
lastMouseOver = true;
|
||||||
|
playClickEffect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastMouseOver = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
matrices.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void playClickEffect() {
|
||||||
|
MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 6, 0.3F));
|
||||||
|
}
|
||||||
|
|
||||||
|
static double squareDistance(double x1, double y1, double x2, double y2) {
|
||||||
|
double dx = x2 - x1;
|
||||||
|
double dy = y2 - y1;
|
||||||
|
return (dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
package com.minelittlepony.unicopia.client.gui;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
|
import net.minecraft.client.render.BufferRenderer;
|
||||||
|
import net.minecraft.client.render.GameRenderer;
|
||||||
|
import net.minecraft.client.render.Tessellator;
|
||||||
|
import net.minecraft.client.render.VertexFormat;
|
||||||
|
import net.minecraft.client.render.VertexFormats;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Matrix4f;
|
||||||
|
|
||||||
|
public class DrawableUtil {
|
||||||
|
public static final double TWO_PI = Math.PI * 2;
|
||||||
|
private static final double NUM_RINGS = 300;
|
||||||
|
private static final double INCREMENT = TWO_PI / NUM_RINGS;
|
||||||
|
|
||||||
|
public static void drawLine(MatrixStack matrices, int x1, int y1, int x2, int y2, int color) {
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.disableTexture();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||||
|
|
||||||
|
Matrix4f matrix = matrices.peek().getPositionMatrix();
|
||||||
|
|
||||||
|
float r = (color >> 24 & 255) / 255F;
|
||||||
|
float g = (color >> 16 & 255) / 255F;
|
||||||
|
float b = (color >> 8 & 255) / 255F;
|
||||||
|
float k = (color & 255) / 255F;
|
||||||
|
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.disableTexture();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||||
|
bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
|
||||||
|
bufferBuilder.vertex(matrix, x1, y1, 0).color(r, g, b, k).next();
|
||||||
|
bufferBuilder.vertex(matrix, x2, y2, 0).color(r, g, b, k).next();
|
||||||
|
bufferBuilder.end();
|
||||||
|
BufferRenderer.draw(bufferBuilder);
|
||||||
|
RenderSystem.enableTexture();
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a colored arc.
|
||||||
|
*
|
||||||
|
* @param mirrorHorizontally Whether or not the arc must be mirrored across the horizontal plane. Will produce a bar that grows from the middle filling both sides.
|
||||||
|
*/
|
||||||
|
public static void drawArc(MatrixStack matrices, double innerRadius, double outerRadius, double startAngle, double arcAngle, int color, boolean mirrorHorizontally) {
|
||||||
|
float r = (color >> 24 & 255) / 255F;
|
||||||
|
float g = (color >> 16 & 255) / 255F;
|
||||||
|
float b = (color >> 8 & 255) / 255F;
|
||||||
|
float k = (color & 255) / 255F;
|
||||||
|
|
||||||
|
if (arcAngle < INCREMENT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TWO_PI - INCREMENT);
|
||||||
|
|
||||||
|
if (!mirrorHorizontally) {
|
||||||
|
startAngle = -startAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.disableTexture();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
|
||||||
|
Matrix4f model = matrices.peek().getPositionMatrix();
|
||||||
|
|
||||||
|
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||||
|
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
for (double angle = startAngle; angle >= -maxAngle; angle -= INCREMENT) {
|
||||||
|
// center
|
||||||
|
cylendricalVertex(bufferBuilder, model, innerRadius, angle, r, g, b, k);
|
||||||
|
// point one
|
||||||
|
cylendricalVertex(bufferBuilder, model, outerRadius, angle, r, g, b, k);
|
||||||
|
// point two
|
||||||
|
cylendricalVertex(bufferBuilder, model, outerRadius, angle + INCREMENT, r, g, b, k);
|
||||||
|
// back to center
|
||||||
|
cylendricalVertex(bufferBuilder, model, innerRadius, angle + INCREMENT, r, g, b, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferBuilder.end();
|
||||||
|
BufferRenderer.draw(bufferBuilder);
|
||||||
|
RenderSystem.enableTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders hollow circle
|
||||||
|
*
|
||||||
|
* @param mirrorHorizontally Whether or not the arc must be mirrored across the horizontal plane. Will produce a bar that grows from the middle filling both sides.
|
||||||
|
*/
|
||||||
|
public static void drawArc(MatrixStack matrices, double radius, double startAngle, double arcAngle, int color, boolean mirrorHorizontally) {
|
||||||
|
drawCircle(matrices, radius, startAngle, arcAngle, color, mirrorHorizontally, VertexFormat.DrawMode.DEBUG_LINES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a filled circle.
|
||||||
|
*
|
||||||
|
* @param mirrorHorizontally Whether or not the arc must be mirrored across the horizontal plane. Will produce a bar that grows from the middle filling both sides.
|
||||||
|
*/
|
||||||
|
public static void drawCircle(MatrixStack matrices, double radius, double startAngle, double arcAngle, int color, boolean mirrorHorizontally) {
|
||||||
|
drawCircle(matrices, radius, startAngle, arcAngle, color, mirrorHorizontally, VertexFormat.DrawMode.QUADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void drawCircle(MatrixStack matrices, double radius, double startAngle, double arcAngle, int color, boolean mirrorHorizontally, VertexFormat.DrawMode mode) {
|
||||||
|
float r = (color >> 24 & 255) / 255F;
|
||||||
|
float g = (color >> 16 & 255) / 255F;
|
||||||
|
float b = (color >> 8 & 255) / 255F;
|
||||||
|
float k = (color & 255) / 255F;
|
||||||
|
|
||||||
|
if (arcAngle < INCREMENT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TWO_PI - INCREMENT);
|
||||||
|
|
||||||
|
if (!mirrorHorizontally) {
|
||||||
|
startAngle = -startAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.disableTexture();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
|
||||||
|
Matrix4f model = matrices.peek().getPositionMatrix();
|
||||||
|
|
||||||
|
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||||
|
bufferBuilder.begin(mode, VertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
boolean joinEnds = mode == VertexFormat.DrawMode.QUADS;
|
||||||
|
|
||||||
|
// center
|
||||||
|
|
||||||
|
for (double angle = startAngle; angle >= -maxAngle; angle -= INCREMENT) {
|
||||||
|
if (joinEnds) {
|
||||||
|
bufferBuilder.vertex(model, 0, 0, 0).color(r, g, b, k).next();
|
||||||
|
}
|
||||||
|
// point one
|
||||||
|
cylendricalVertex(bufferBuilder, model, radius, angle, r, g, b, k);
|
||||||
|
// point two
|
||||||
|
cylendricalVertex(bufferBuilder, model, radius, angle + INCREMENT, r, g, b, k);
|
||||||
|
if (joinEnds) {
|
||||||
|
bufferBuilder.vertex(model, 0, 0, 0).color(r, g, b, k).next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferBuilder.end();
|
||||||
|
BufferRenderer.draw(bufferBuilder);
|
||||||
|
RenderSystem.enableTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void cylendricalVertex(BufferBuilder bufferBuilder, Matrix4f model, double radius, double angle, float r, float g, float b, float k) {
|
||||||
|
bufferBuilder.vertex(model,
|
||||||
|
(float)(radius * Math.sin(angle)),
|
||||||
|
(float)(radius * Math.cos(angle)), 0).color(r, g, b, k).normal(2, 2, 2).next();
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,20 +6,10 @@ import com.minelittlepony.unicopia.client.KeyBindingsHandler;
|
||||||
import com.minelittlepony.unicopia.entity.player.MagicReserves;
|
import com.minelittlepony.unicopia.entity.player.MagicReserves;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
|
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
import net.minecraft.client.render.BufferBuilder;
|
|
||||||
import net.minecraft.client.render.BufferRenderer;
|
|
||||||
import net.minecraft.client.render.GameRenderer;
|
|
||||||
import net.minecraft.client.render.Tessellator;
|
|
||||||
import net.minecraft.client.render.VertexFormat;
|
|
||||||
import net.minecraft.client.render.VertexFormats;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.Matrix4f;
|
|
||||||
|
|
||||||
class ManaRingSlot extends Slot {
|
class ManaRingSlot extends Slot {
|
||||||
private static final double TWO_PI = Math.PI * 2;
|
|
||||||
|
|
||||||
public ManaRingSlot(UHud uHud, AbilitySlot normalSlot, AbilitySlot backupSlot, int x, int y) {
|
public ManaRingSlot(UHud uHud, AbilitySlot normalSlot, AbilitySlot backupSlot, int x, int y) {
|
||||||
super(uHud, normalSlot, backupSlot, x, y, 8, UHud.PRIMARY_SLOT_SIZE, 33, 43, 42);
|
super(uHud, normalSlot, backupSlot, x, y, 8, UHud.PRIMARY_SLOT_SIZE, 33, 43, 42);
|
||||||
|
@ -60,7 +50,7 @@ class ManaRingSlot extends Slot {
|
||||||
|
|
||||||
double angle = cost * Math.PI * 2;
|
double angle = cost * Math.PI * 2;
|
||||||
|
|
||||||
renderArc(matrices, 13, 17, arcBegin - angle, angle, color, false);
|
DrawableUtil.drawArc(matrices, 13, 17, arcBegin - angle, angle, color, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,83 +62,17 @@ class ManaRingSlot extends Slot {
|
||||||
}
|
}
|
||||||
|
|
||||||
private double renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double offsetAngle, Bar bar, int color, float tickDelta) {
|
private double renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double offsetAngle, Bar bar, int color, float tickDelta) {
|
||||||
double fill = bar.getPercentFill() * TWO_PI;
|
double fill = bar.getPercentFill() * DrawableUtil.TWO_PI;
|
||||||
double shadow = bar.getShadowFill() * TWO_PI;
|
double shadow = bar.getShadowFill() * DrawableUtil.TWO_PI;
|
||||||
|
|
||||||
renderArc(matrices, innerRadius, outerRadius, offsetAngle, fill, color, true);
|
DrawableUtil.drawArc(matrices, innerRadius, outerRadius, offsetAngle, fill, color, true);
|
||||||
|
|
||||||
if (shadow > fill) {
|
if (shadow > fill) {
|
||||||
color = (color & 0xFFFFFF00)
|
color = (color & 0xFFFFFF00)
|
||||||
| ((color & 0x000000FF) / 2);
|
| ((color & 0x000000FF) / 2);
|
||||||
|
|
||||||
renderArc(matrices, innerRadius, outerRadius, offsetAngle + fill, shadow - fill, color, false);
|
DrawableUtil.drawArc(matrices, innerRadius, outerRadius, offsetAngle + fill, shadow - fill, color, false);
|
||||||
}
|
}
|
||||||
return offsetAngle + fill;
|
return offsetAngle + fill;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders a colored arc.
|
|
||||||
*
|
|
||||||
* @param mirrorHorizontally Whether or not the arc must be mirrored across the horizontal plane. Will produce a bar that grows from the middle filling both sides.
|
|
||||||
*/
|
|
||||||
static void renderArc(MatrixStack matrices, double innerRadius, double outerRadius, double startAngle, double arcAngle, int color, boolean mirrorHorizontally) {
|
|
||||||
float r = (color >> 24 & 255) / 255F;
|
|
||||||
float g = (color >> 16 & 255) / 255F;
|
|
||||||
float b = (color >> 8 & 255) / 255F;
|
|
||||||
float k = (color & 255) / 255F;
|
|
||||||
|
|
||||||
final double num_rings = 300;
|
|
||||||
|
|
||||||
final double increment = TWO_PI / num_rings;
|
|
||||||
|
|
||||||
if (arcAngle < increment) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TWO_PI - increment);
|
|
||||||
|
|
||||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
|
||||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
|
||||||
RenderSystem.enableBlend();
|
|
||||||
RenderSystem.disableTexture();
|
|
||||||
RenderSystem.defaultBlendFunc();
|
|
||||||
|
|
||||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
|
||||||
|
|
||||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
|
|
||||||
|
|
||||||
Matrix4f model = matrices.peek().getPositionMatrix();
|
|
||||||
|
|
||||||
if (!mirrorHorizontally) {
|
|
||||||
startAngle = -startAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (double angle = startAngle; angle >= -maxAngle; angle -= increment) {
|
|
||||||
// center
|
|
||||||
bufferBuilder.vertex(model,
|
|
||||||
(float)(innerRadius * Math.sin(angle)),
|
|
||||||
(float)(innerRadius * Math.cos(angle)), 0).color(r, g, b, k).next();
|
|
||||||
|
|
||||||
// point one
|
|
||||||
bufferBuilder.vertex(model,
|
|
||||||
(float)(outerRadius * Math.sin(angle)),
|
|
||||||
(float)(outerRadius * Math.cos(angle)), 0).color(r, g, b, k).next();
|
|
||||||
|
|
||||||
// point two
|
|
||||||
bufferBuilder.vertex(model,
|
|
||||||
(float)(outerRadius * Math.sin(angle + increment)),
|
|
||||||
(float)(outerRadius * Math.cos(angle + increment)), 0).color(r, g, b, k).next();
|
|
||||||
|
|
||||||
// back to center
|
|
||||||
bufferBuilder.vertex(model,
|
|
||||||
(float)(innerRadius * Math.sin(angle + increment)),
|
|
||||||
(float)(innerRadius * Math.cos(angle + increment)), 0).color(r, g, b, k).next();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bufferBuilder.end();
|
|
||||||
BufferRenderer.draw(bufferBuilder);
|
|
||||||
|
|
||||||
RenderSystem.enableTexture();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class UHud extends DrawableHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderSpell(CustomisedSpellType<?> spell, int x, int y) {
|
public void renderSpell(CustomisedSpellType<?> spell, double x, double y) {
|
||||||
if (!spell.isEmpty()) {
|
if (!spell.isEmpty()) {
|
||||||
MatrixStack modelStack = RenderSystem.getModelViewStack();
|
MatrixStack modelStack = RenderSystem.getModelViewStack();
|
||||||
|
|
||||||
|
@ -171,9 +171,8 @@ public class UHud extends DrawableHelper {
|
||||||
Pony pony = Pony.of(client.player);
|
Pony pony = Pony.of(client.player);
|
||||||
|
|
||||||
if (spell.isOn(pony)) {
|
if (spell.isOn(pony)) {
|
||||||
ManaRingSlot.renderArc(modelStack, 5, 7, 0, Math.PI * 2,
|
DrawableUtil.drawArc(modelStack, 5, 7, 0, Math.PI * 2, (spell.type().getColor() | 0x000000FF) & 0xFFFFFFAF, false);
|
||||||
(spell.type().getColor() | 0x000000FF) & 0xFFFFFFAF, false);
|
DrawableUtil.drawArc(modelStack, 7, 8, 0, Math.PI * 2, 0xAAAAFFFF, false);
|
||||||
ManaRingSlot.renderArc(modelStack, 7, 8, 0, Math.PI * 2, 0xAAAAFFFF, false);
|
|
||||||
}
|
}
|
||||||
modelStack.pop();
|
modelStack.pop();
|
||||||
RenderSystem.applyModelViewMatrix();
|
RenderSystem.applyModelViewMatrix();
|
||||||
|
|
|
@ -6,27 +6,22 @@ import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.util.math.Vector4f;
|
import net.minecraft.util.math.Vector4f;
|
||||||
|
|
||||||
public class SphereModel {
|
public class SphereModel {
|
||||||
protected static final double pi = Math.PI;
|
protected static final double PI = Math.PI;
|
||||||
protected static final double two_pi = pi * 2F;
|
protected static final double TWO_PI = PI * 2F;
|
||||||
|
|
||||||
public static final SphereModel SPHERE = new SphereModel(40, 40, two_pi);
|
public static final SphereModel SPHERE = new SphereModel(40, 40, TWO_PI);
|
||||||
public static final SphereModel DISK = new SphereModel(40, 2, pi);
|
public static final SphereModel DISK = new SphereModel(40, 2, PI);
|
||||||
|
|
||||||
private final double num_rings;
|
|
||||||
private final double num_sectors;
|
|
||||||
|
|
||||||
private final double azimuthRange;
|
private final double azimuthRange;
|
||||||
|
|
||||||
final double zenithIncrement;
|
private final double zenithIncrement;
|
||||||
final double azimuthIncrement;
|
private final double azimuthIncrement;
|
||||||
|
|
||||||
public SphereModel(double rings, double sectors, double azimuthRange) {
|
public SphereModel(double rings, double sectors, double azimuthRange) {
|
||||||
this.num_rings = rings;
|
|
||||||
this.num_sectors = sectors;
|
|
||||||
this.azimuthRange = azimuthRange;
|
this.azimuthRange = azimuthRange;
|
||||||
|
|
||||||
zenithIncrement = pi / num_rings;
|
zenithIncrement = PI / rings;
|
||||||
azimuthIncrement = two_pi / num_sectors;
|
azimuthIncrement = TWO_PI / sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void render(MatrixStack matrices, VertexConsumer vertexWriter, int light, int overlay, float radius, float r, float g, float b, float a) {
|
public final void render(MatrixStack matrices, VertexConsumer vertexWriter, int light, int overlay, float radius, float r, float g, float b, float a) {
|
||||||
|
@ -36,7 +31,7 @@ public class SphereModel {
|
||||||
|
|
||||||
Matrix4f position = matrices.peek().getPositionMatrix();
|
Matrix4f position = matrices.peek().getPositionMatrix();
|
||||||
|
|
||||||
for (double zenith = -pi; zenith < pi; zenith += zenithIncrement) {
|
for (double zenith = -PI; zenith < PI; zenith += zenithIncrement) {
|
||||||
for (double azimuth = -azimuthRange; azimuth < azimuthRange; azimuth += azimuthIncrement) {
|
for (double azimuth = -azimuthRange; azimuth < azimuthRange; azimuth += azimuthIncrement) {
|
||||||
drawQuad(position, vertexWriter, radius, zenith, azimuth, light, overlay, r, g, b, a);
|
drawQuad(position, vertexWriter, radius, zenith, azimuth, light, overlay, r, g, b, a);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +52,7 @@ public class SphereModel {
|
||||||
vertexWriter.vertex(position.getX(), position.getY(), position.getZ(), r, g, b, a, 0, 0, overlay, light, 0, 0, 0);
|
vertexWriter.vertex(position.getX(), position.getY(), position.getZ(), r, g, b, a, 0, 0, overlay, light, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector4f convertToCartesianCoord(double r, double theta, double phi) {
|
public static Vector4f convertToCartesianCoord(double r, double theta, double phi) {
|
||||||
double x = r * Math.sin(theta) * Math.cos(phi);
|
double x = r * Math.sin(theta) * Math.cos(phi);
|
||||||
double y = r * Math.sin(theta) * Math.sin(phi);
|
double y = r * Math.sin(theta) * Math.sin(phi);
|
||||||
double z = r * Math.cos(theta);
|
double z = r * Math.cos(theta);
|
||||||
|
|
|
@ -46,10 +46,10 @@ public class CastSpellEntity extends Entity implements Caster<LivingEntity>, Lig
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public boolean clear() {
|
||||||
getDataTracker().get(SPELL).ifPresent(id -> {
|
return getDataTracker().get(SPELL).map(id -> {
|
||||||
delegate().removeIf(spell -> spell.getUuid().equals(id), true);
|
return delegate().removeIf(spell -> spell.getUuid().equals(id), true);
|
||||||
});
|
}).orElse(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -90,13 +90,20 @@ public class EffectSync implements SpellContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public Stream<Spell> stream(boolean update) {
|
||||||
|
return read(null, update, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clear() {
|
||||||
if (spells.clear()) {
|
if (spells.clear()) {
|
||||||
write();
|
write();
|
||||||
if (owner instanceof UpdateCallback) {
|
if (owner instanceof UpdateCallback) {
|
||||||
((UpdateCallback)owner).onSpellSet(null);
|
((UpdateCallback)owner).onSpellSet(null);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<Spell> read(@Nullable SpellPredicate<?> type, boolean synchronize, boolean sendUpdate) {
|
private Stream<Spell> read(@Nullable SpellPredicate<?> type, boolean synchronize, boolean sendUpdate) {
|
||||||
|
|
|
@ -214,8 +214,9 @@
|
||||||
"toxicity.severe.name": "Toxic",
|
"toxicity.severe.name": "Toxic",
|
||||||
"toxicity.lethal.name": "Lethal",
|
"toxicity.lethal.name": "Lethal",
|
||||||
|
|
||||||
"ability.unicopia.shoot": "Magic Missle",
|
"ability.unicopia.shoot": "Throw Magic",
|
||||||
"ability.unicopia.cast": "Counterspell",
|
"ability.unicopia.cast": "Cast Spell",
|
||||||
|
"ability.unicopia.dispell": "Dispell Magic",
|
||||||
"ability.unicopia.teleport": "Teleport",
|
"ability.unicopia.teleport": "Teleport",
|
||||||
"ability.unicopia.teleport_group": "Teleport (Group)",
|
"ability.unicopia.teleport_group": "Teleport (Group)",
|
||||||
"ability.unicopia.grow": "Earthly Nourishment",
|
"ability.unicopia.grow": "Earthly Nourishment",
|
||||||
|
@ -298,6 +299,9 @@
|
||||||
"gui.unicopia.spellbook.page.discoveries": "Discoveries",
|
"gui.unicopia.spellbook.page.discoveries": "Discoveries",
|
||||||
"gui.unicopia.spellbook.page.recipes": "Recipes",
|
"gui.unicopia.spellbook.page.recipes": "Recipes",
|
||||||
|
|
||||||
|
"gui.unicopia.action.spells_cleared": "Removed all spells",
|
||||||
|
"gui.unicopia.action.no_spells_cleared": "You have no active spells",
|
||||||
|
|
||||||
"unicopia.category.name": "Pony Abilities",
|
"unicopia.category.name": "Pony Abilities",
|
||||||
|
|
||||||
"key.unicopia.primary": "Primary Ability",
|
"key.unicopia.primary": "Primary Ability",
|
||||||
|
|
Loading…
Reference in a new issue