diff --git a/src/main/java/com/minelittlepony/unicopia/Race.java b/src/main/java/com/minelittlepony/unicopia/Race.java index c12377e5..61277735 100644 --- a/src/main/java/com/minelittlepony/unicopia/Race.java +++ b/src/main/java/com/minelittlepony/unicopia/Race.java @@ -115,6 +115,11 @@ public final class Race implements Affine { return String.format("%s.race.%s", id.getNamespace(), id.getPath().toLowerCase()); } + public Identifier getIcon() { + Identifier id = REGISTRY.getId(this); + return new Identifier(id.getNamespace(), "textures/gui/race/" + id.getPath() + ".png"); + } + public boolean isPermitted(@Nullable PlayerEntity sender) { if (isOp() && (sender == null || !sender.getAbilities().creativeMode)) { return false; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java index 45737ed2..703965ac 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java @@ -64,6 +64,8 @@ public interface SpellContainer { Stream stream(boolean update); + Stream stream(@Nullable SpellPredicate type, boolean update); + /** * Removes all effects currently active in this slot. */ diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java index b9f8c2ee..84864883 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java @@ -168,6 +168,10 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS return getWorld(source).map(castEntity::get); } + public Optional getPosition() { + return castEntity.getPosition(); + } + public Optional getParticleEffectAttachment(Caster source) { return particlEffect.update(getUuid(), source, spawner -> { source.getOriginVector().add(0, 5, 0); diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java b/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java index 25b96666..c2dc992d 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/DismissSpellScreen.java @@ -11,11 +11,8 @@ import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.MsgRemoveSpell; - import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.Drawable; -import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.*; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.client.util.math.MatrixStack; @@ -24,7 +21,7 @@ import net.minecraft.sound.SoundEvents; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.StringHelper; -import net.minecraft.util.math.Vector4f; +import net.minecraft.util.math.*; public class DismissSpellScreen extends GameGui { private final Pony pony = Pony.of(MinecraftClient.getInstance().player); @@ -41,11 +38,35 @@ public class DismissSpellScreen extends GameGui { double azimuth = 0; double ring = 2; + List placeableSpells = new ArrayList<>(); + for (Spell spell : pony.getSpellSlot().stream(true).toList()) { - addDrawableChild(new Entry(spell, 75 * ring - 25, azimuth)); + + if (spell instanceof PlaceableSpell placeable) { + if (placeable.getPosition().isPresent()) { + placeableSpells.add(placeable); + continue; + } + } + + addDrawableChild(new Entry(spell).ofRadial(75 * ring - 25, azimuth)); ring *= 1 + 0.03 / ring; azimuth += Math.PI / (8 * ring); } + + double minimalDistance = 75 * (ring - 1) - 25; + Vec3d origin = pony.getOriginVector(); + + placeableSpells.forEach(placeable -> { + placeable.getPosition().ifPresent(position -> { + Vec3d relativePos = position.subtract(origin); + Vec3d cartesian = relativePos + .normalize() + .multiply(minimalDistance + relativePos.length()) + .rotateY((pony.getEntity().getYaw() - 180) * MathHelper.RADIANS_PER_DEGREE); + addDrawableChild(new Entry(placeable).ofCartesian(cartesian)); + }); + }); } @Override @@ -63,8 +84,7 @@ public class DismissSpellScreen extends GameGui { DrawableUtil.drawArc(matrices, 160, 1600, 0, DrawableUtil.TAU, 0x00000020, false); super.render(matrices, mouseX, mouseY, delta); - - DrawableUtil.drawCircle(matrices, 2, 0, DrawableUtil.TAU, 0xFFAAFF99, false); + DrawableUtil.renderRaceIcon(matrices, pony.getSpecies(), 0, 0, 16); matrices.pop(); DrawableUtil.drawLine(matrices, mouseX, mouseY - 4, mouseX, mouseY + 4, 0xFFAAFF99); @@ -96,12 +116,20 @@ public class DismissSpellScreen extends GameGui { private final Vector4f copy = new Vector4f(); - public Entry(Spell spell, double radius, double azimuth) { + public Entry(Spell spell) { this.spell = spell; this.actualSpell = getActualSpell(); + } + public Entry ofRadial(double radius, double azimuth) { SphereModel.convertToCartesianCoord(this, radius, azimuth, azimuth); add(0, -(float)radius / 2F, 0, 0); + return this; + } + + public Entry ofCartesian(Vec3d pos) { + add((float)pos.x, (float)pos.z, (float)pos.y, 1); + return this; } private Spell getActualSpell() { @@ -135,17 +163,18 @@ public class DismissSpellScreen extends GameGui { var type = actualSpell.getType().withTraits(actualSpell.getTraits()); + DrawableUtil.drawLine(matrices, 0, 0, (int)getX(), (int)getY(), 0xFFAAFF99); DrawableUtil.renderItemIcon(actualSpell.isDead() ? UItems.BOTCHED_GEM.getDefaultStack() : type.getDefaultStack(), - copy.getX() - 8 + (copy.getX() - mouseX - 5) / 60D, - copy.getY() - 8 + (copy.getY() - mouseY - 5) / 60D, + copy.getX() - 8 + copy.getZ() / 20F, + copy.getY() - 8 + copy.getZ() / 20F, 1 ); + int color = actualSpell.getType().getColor() << 2; + matrices.push(); matrices.translate(getX(), getY(), 0); - int color = actualSpell.getType().getColor() << 2; - DrawableUtil.drawArc(matrices, 7, 8, 0, DrawableUtil.TAU, color | 0x00000088, false); if (isMouseOver(relativeMouseX, relativeMouseY)) { diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/DrawableUtil.java b/src/main/java/com/minelittlepony/unicopia/client/gui/DrawableUtil.java index 5552e902..edb7b19f 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/DrawableUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/DrawableUtil.java @@ -1,8 +1,10 @@ package com.minelittlepony.unicopia.client.gui; +import com.minelittlepony.unicopia.Race; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.BufferRenderer; import net.minecraft.client.render.GameRenderer; @@ -44,6 +46,11 @@ public interface DrawableUtil { RenderSystem.applyModelViewMatrix(); } + static void renderRaceIcon(MatrixStack matrices, Race race, int x, int y, int size) { + RenderSystem.setShaderTexture(0, race.getIcon()); + DrawableHelper.drawTexture(matrices, x - size / 2, y - size / 2, 0, 0, 0, size, size, size, size); + } + static void drawLine(MatrixStack matrices, int x1, int y1, int x2, int y2, int color) { RenderSystem.enableBlend(); RenderSystem.disableTexture(); @@ -64,7 +71,7 @@ public interface DrawableUtil { 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(); - BufferRenderer.drawWithoutShader(bufferBuilder.end()); + BufferRenderer.drawWithShader(bufferBuilder.end()); RenderSystem.enableTexture(); RenderSystem.disableBlend(); } diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/LanSettingsScreen.java b/src/main/java/com/minelittlepony/unicopia/client/gui/LanSettingsScreen.java index 2ae15f2a..6fa16e87 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/LanSettingsScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/LanSettingsScreen.java @@ -146,14 +146,7 @@ public class LanSettingsScreen extends GameGui { } public static Style createStyle(Race race) { - int ordinal = Race.REGISTRY.getRawId(race); - return new Style() - .setIcon(new TextureSprite() - .setPosition(2, 2) - .setSize(16, 16) - .setTexture(TribeSelectionScreen.ICONS) - .setTextureOffset((16 * ordinal) % 256, (ordinal / 256) * 16) - ) + return new Style().setIcon(TribeButton.createSprite(race, 2, 2, 15)) .setTooltip(race.getTranslationKey(), 0, 10); } diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/TribeButton.java b/src/main/java/com/minelittlepony/unicopia/client/gui/TribeButton.java index 3cd4d45f..7fe3a956 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/TribeButton.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/TribeButton.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia.client.gui; import com.minelittlepony.common.client.gui.element.Button; +import com.minelittlepony.common.client.gui.sprite.ISprite; import com.minelittlepony.common.client.gui.sprite.TextureSprite; import com.minelittlepony.unicopia.Race; import com.mojang.blaze3d.platform.GlStateManager; @@ -22,19 +23,8 @@ public class TribeButton extends Button { super(x, y, 70, 70); this.screenWidth = screenWidth; this.race = race; - int size = 32; - int textureSize = 512; - int ordinal = Race.REGISTRY.getRawId(race); - getStyle() - .setIcon(new TextureSprite() - .setPosition((70 - size) / 2, 0) - .setSize(size, size) - .setTextureSize(textureSize, textureSize) - .setTexture(TribeSelectionScreen.ICONS) - .setTextureOffset((size * ordinal) % textureSize, (ordinal / textureSize) * size) - ) - .setText(race.getTranslationKey()); + getStyle().setIcon(createSprite(race, (70 - 32) / 2, 0, 32)).setText(race.getTranslationKey()); } @Override @@ -77,4 +67,12 @@ public class TribeButton extends Button { renderForground(matrices, mc, mouseX, mouseY, foreColor | MathHelper.ceil(alpha * 255.0F) << 24); } + + public static ISprite createSprite(Race race, int x, int y, int size) { + return new TextureSprite() + .setPosition(x, y) + .setSize(size, size) + .setTextureSize(size, size) + .setTexture(race.getIcon()); + } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/TribeSelectionScreen.java b/src/main/java/com/minelittlepony/unicopia/client/gui/TribeSelectionScreen.java index 48a9ece2..0d12cee8 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/TribeSelectionScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/TribeSelectionScreen.java @@ -17,7 +17,6 @@ import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; public class TribeSelectionScreen extends GameGui implements HidesHud { - static final Identifier ICONS = Unicopia.id("textures/gui/icons.png"); static final Identifier TEXTURE = Unicopia.id("textures/gui/tribe_selection.png"); final Set allowedRaces; diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java index 02bac686..4415ae95 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java @@ -156,29 +156,40 @@ public class UHud extends DrawableHelper { } public void renderSpell(CustomisedSpellType spell, double x, double y) { - if (!spell.isEmpty()) { - Pony pony = Pony.of(client.player); + if (spell.isEmpty()) { + return; + } - if (spell.isOn(pony)) { - MatrixStack modelStack = new MatrixStack(); + Pony pony = Pony.of(client.player); + if (spell.isOn(pony)) { + MatrixStack modelStack = new MatrixStack(); + + modelStack.push(); + modelStack.translate(x + 5.5, y + 5.5, 0); + + int color = spell.type().getColor() | 0x000000FF; + double radius = 2 + Math.sin(client.player.age / 9D) / 4; + + DrawableUtil.drawArc(modelStack, radius, radius + 3, 0, DrawableUtil.TAU, color & 0xFFFFFF2F, false); + DrawableUtil.drawArc(modelStack, radius + 3, radius + 4, 0, DrawableUtil.TAU, color & 0xFFFFFFAF, false); + pony.getSpellSlot().get(spell.and(SpellPredicate.IS_TIMED), false).map(TimedSpell::getTimer).ifPresent(timer -> { + DrawableUtil.drawArc(modelStack, radius, radius + 3, 0, DrawableUtil.TAU * timer.getPercentTimeRemaining(client.getTickDelta()), 0xFFFFFFFF, false); + }); + + long count = pony.getSpellSlot().stream(spell, false).count(); + if (count > 1) { modelStack.push(); - modelStack.translate(x + 5.5, y + 5.5, 0); - - int color = spell.type().getColor() | 0x000000FF; - double radius = 2 + Math.sin(client.player.age / 9D) / 4; - - DrawableUtil.drawArc(modelStack, radius, radius + 3, 0, DrawableUtil.TAU, color & 0xFFFFFF2F, false); - DrawableUtil.drawArc(modelStack, radius + 3, radius + 4, 0, DrawableUtil.TAU, color & 0xFFFFFFAF, false); - pony.getSpellSlot().get(spell.and(SpellPredicate.IS_TIMED), false).map(TimedSpell::getTimer).ifPresent(timer -> { - DrawableUtil.drawArc(modelStack, radius, radius + 3, 0, DrawableUtil.TAU * timer.getPercentTimeRemaining(client.getTickDelta()), 0xFFFFFFFF, false); - }); - + modelStack.translate(1, 1, 900); + modelStack.scale(0.8F, 0.8F, 0.8F); + font.drawWithShadow(modelStack, count > 64 ? "64+" : String.valueOf(count), 0, 0, 0xFFFFFFFF); modelStack.pop(); } - DrawableUtil.renderItemIcon(spell.getDefaultStack(), x, y, EQUIPPED_GEMSTONE_SCALE); + modelStack.pop(); } + + DrawableUtil.renderItemIcon(spell.getDefaultStack(), x, y, EQUIPPED_GEMSTONE_SCALE); } private void renderMessage(MatrixStack matrices, float tickDelta) { diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java index 1bfa4543..a1372462 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java @@ -2,9 +2,6 @@ package com.minelittlepony.unicopia.client.gui.spellbook; import com.minelittlepony.common.client.gui.IViewRoot; import com.minelittlepony.common.client.gui.dimension.Bounds; -import com.minelittlepony.common.client.gui.sprite.TextureSprite; -import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.client.gui.*; import com.minelittlepony.unicopia.entity.player.*; @@ -31,25 +28,15 @@ public class SpellbookProfilePageContent extends DrawableHelper implements Spell @Override public void init(SpellbookScreen screen, Identifier pageId) { - Bounds bounds = screen.getFrameBounds(); - Race race = pony.getSpecies(); int size = 32; - int textureSize = 512; - int ordinal = Race.REGISTRY.getRawId(race); - int x = screen.getX() + bounds.left + bounds.width / 4 - size + 10; int y = screen.getY() + bounds.top + bounds.height / 2; + screen.addDrawable(new SpellbookScreen.ImageButton(x, y, size, size)) .getStyle() - .setIcon(new TextureSprite() - .setPosition(0, 0) - .setSize(size, size) - .setTextureSize(textureSize, textureSize) - .setTexture(Unicopia.id("textures/gui/icons.png")) - .setTextureOffset((size * ordinal) % textureSize, (ordinal / textureSize) * size) - ) + .setIcon(TribeButton.createSprite(pony.getSpecies(), 0, 0, size)) .setTooltip(ProfileTooltip.get(pony)); diff --git a/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java b/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java index e02942fd..8fdec87b 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java +++ b/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java @@ -91,7 +91,12 @@ public class EffectSync implements SpellContainer { @Override public Stream stream(boolean update) { - return read(null, update, true); + return stream(null, update); + } + + @Override + public Stream stream(@Nullable SpellPredicate type, boolean update) { + return read(type, update, true); } @Override diff --git a/src/main/resources/assets/unicopia/textures/gui/icons.png b/src/main/resources/assets/unicopia/textures/gui/icons.png deleted file mode 100644 index 7739ff90..00000000 Binary files a/src/main/resources/assets/unicopia/textures/gui/icons.png and /dev/null differ diff --git a/src/main/resources/assets/unicopia/textures/gui/race/alicorn.png b/src/main/resources/assets/unicopia/textures/gui/race/alicorn.png new file mode 100644 index 00000000..33be65ec Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/gui/race/alicorn.png differ diff --git a/src/main/resources/assets/unicopia/textures/gui/race/bat.png b/src/main/resources/assets/unicopia/textures/gui/race/bat.png new file mode 100644 index 00000000..6a836e88 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/gui/race/bat.png differ diff --git a/src/main/resources/assets/unicopia/textures/gui/race/changeling.png b/src/main/resources/assets/unicopia/textures/gui/race/changeling.png new file mode 100644 index 00000000..43f62a8c Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/gui/race/changeling.png differ diff --git a/src/main/resources/assets/unicopia/textures/gui/race/earth.png b/src/main/resources/assets/unicopia/textures/gui/race/earth.png new file mode 100644 index 00000000..5385e98a Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/gui/race/earth.png differ diff --git a/src/main/resources/assets/unicopia/textures/gui/race/human.png b/src/main/resources/assets/unicopia/textures/gui/race/human.png new file mode 100644 index 00000000..f70d42b8 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/gui/race/human.png differ diff --git a/src/main/resources/assets/unicopia/textures/gui/race/pegasus.png b/src/main/resources/assets/unicopia/textures/gui/race/pegasus.png new file mode 100644 index 00000000..66bdcfdc Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/gui/race/pegasus.png differ diff --git a/src/main/resources/assets/unicopia/textures/gui/race/unicorn.png b/src/main/resources/assets/unicopia/textures/gui/race/unicorn.png new file mode 100644 index 00000000..1b4c23f4 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/gui/race/unicorn.png differ