Spells can now be hidden

This commit is contained in:
Sollace 2023-08-29 15:18:42 +01:00
parent 8385232c5b
commit 0d4b9c0db0
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
12 changed files with 141 additions and 53 deletions

View file

@ -17,6 +17,7 @@ public interface SpellPredicate<T extends Spell> extends Predicate<Spell> {
SpellPredicate<TimedSpell> IS_TIMED = spell -> spell instanceof TimedSpell;
SpellPredicate<?> IS_NOT_PLACED = IS_PLACED.negate();
SpellPredicate<?> IS_VISIBLE = spell -> spell != null && !spell.isHidden();
default <Q extends Spell> SpellPredicate<Q> and(SpellPredicate<Q> predicate) {
SpellPredicate<T> self = this;

View file

@ -21,6 +21,7 @@ public abstract class AbstractDelegatingSpell implements Spell,
ProjectileDelegate.ConfigurationListener, ProjectileDelegate.BlockHitListener, ProjectileDelegate.EntityHitListener {
private boolean isDirty;
private boolean hidden;
private UUID uuid = UUID.randomUUID();
@ -82,6 +83,16 @@ public abstract class AbstractDelegatingSpell implements Spell,
isDirty = true;
}
@Override
public boolean isHidden() {
return hidden || getDelegates().stream().allMatch(Spell::isHidden);
}
@Override
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
@Override
public void onDestroyed(Caster<?> caster) {
getDelegates().forEach(a -> a.onDestroyed(caster));
@ -110,12 +121,14 @@ public abstract class AbstractDelegatingSpell implements Spell,
@Override
public void toNBT(NbtCompound compound) {
compound.putUuid("uuid", uuid);
compound.putBoolean("hidden", hidden);
saveDelegates(compound);
}
@Override
public void fromNBT(NbtCompound compound) {
isDirty = false;
hidden = compound.getBoolean("hidden");
if (compound.contains("uuid")) {
uuid = compound.getUuid("uuid");
}

View file

@ -92,4 +92,13 @@ public class DispersableDisguiseSpell extends AbstractDisguiseSpell implements I
public Optional<EntityAppearance> getAppearance() {
return isSuppressed() ? Optional.empty() : super.getAppearance();
}
@Override
public boolean isHidden() {
return true;
}
@Override
public void setHidden(boolean hidden) {
}
}

View file

@ -93,4 +93,13 @@ public class RainboomAbilitySpell extends AbstractSpell {
super.fromNBT(compound);
age = compound.getInt("age");
}
@Override
public boolean isHidden() {
return false;
}
@Override
public void setHidden(boolean hidden) {
}
}

View file

@ -94,6 +94,10 @@ public interface Spell extends NbtSerialisable, Affine {
*/
void setDirty();
boolean isHidden();
void setHidden(boolean hidden);
/**
* Called when a gem is destroyed.
*/

View file

@ -90,4 +90,13 @@ public final class ThrowableSpell extends AbstractDelegatingSpell {
public ThrowableSpell toThrowable() {
return this;
}
@Override
public boolean isHidden() {
return true;
}
@Override
public void setHidden(boolean hidden) {
}
}

View file

@ -66,4 +66,14 @@ public class TimeControlAbilitySpell extends AbstractSpell {
public void fromNBT(NbtCompound compound) {
super.fromNBT(compound);
}
@Override
public boolean isHidden() {
return true;
}
@Override
public void setHidden(boolean hidden) {
}
}

View file

@ -11,8 +11,9 @@ import net.minecraft.nbt.NbtCompound;
public abstract class AbstractSpell implements Spell {
private boolean isDead;
private boolean isDirty;
private boolean dead;
private boolean dirty;
private boolean hidden;
private CustomisedSpellType<?> type;
@ -43,23 +44,33 @@ public abstract class AbstractSpell implements Spell {
@Override
public void setDead() {
isDead = true;
dead = true;
setDirty();
}
@Override
public boolean isDead() {
return isDead;
return dead;
}
@Override
public boolean isDirty() {
return isDirty;
return dirty;
}
@Override
public void setDirty() {
isDirty = true;
dirty = true;
}
@Override
public boolean isHidden() {
return hidden;
}
@Override
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
@Override
@ -73,18 +84,20 @@ public abstract class AbstractSpell implements Spell {
@Override
public void toNBT(NbtCompound compound) {
compound.putBoolean("dead", isDead);
compound.putBoolean("dead", dead);
compound.putBoolean("hidden", hidden);
compound.putUuid("uuid", uuid);
compound.put("traits", getTraits().toNbt());
}
@Override
public void fromNBT(NbtCompound compound) {
isDirty = false;
dirty = false;
if (compound.contains("uuid")) {
uuid = compound.getUuid("uuid");
}
isDead = compound.getBoolean("dead");
dead = compound.getBoolean("dead");
hidden = compound.getBoolean("hidden");
if (compound.contains("traits")) {
type = type.type().withTraits(SpellTraits.fromNbt(compound.getCompound("traits")).orElse(SpellTraits.EMPTY));
}
@ -92,6 +105,6 @@ public abstract class AbstractSpell implements Spell {
@Override
public final String toString() {
return "Spell[uuid=" + uuid + ", dead=" + isDead + ", type=" + getType() + "]";
return "Spell{" + getTypeAndTraits() + "}[uuid=" + uuid + ", dead=" + dead + ", hidden=" + hidden + "]";
}
}

View file

@ -86,7 +86,9 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
setDisguise(e);
Caster<?> other = Caster.of(e).get();
SpellType.MIMIC.withTraits().apply(other, CastingMethod.INDIRECT).setDisguise(master);
MimicSpell mimic = SpellType.MIMIC.withTraits().apply(other, CastingMethod.INDIRECT);
mimic.setHidden(true);
mimic.setDisguise(master);
if (master instanceof ServerPlayerEntity sMaster && e instanceof ServerPlayerEntity sE) {
swapPlayerData(sMaster, sE);

View file

@ -7,6 +7,7 @@ import org.joml.Vector4f;
import com.minelittlepony.common.client.gui.GameGui;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.ability.magic.spell.*;
import com.minelittlepony.unicopia.client.FlowingText;
import com.minelittlepony.unicopia.client.render.model.SphereModel;
@ -42,7 +43,7 @@ public class DismissSpellScreen extends GameGui {
List<PlaceableSpell> placeableSpells = new ArrayList<>();
for (Spell spell : pony.getSpellSlot().stream(true).toList()) {
for (Spell spell : pony.getSpellSlot().stream(true).filter(SpellPredicate.IS_VISIBLE).toList()) {
if (spell instanceof PlaceableSpell placeable) {
if (placeable.getPosition().isPresent()) {

View file

@ -0,0 +1,56 @@
package com.minelittlepony.unicopia.client.gui;
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.ability.magic.spell.TimedSpell;
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.util.math.MatrixStack;
public interface SpellIconRenderer {
static void renderSpell(DrawContext context, CustomisedSpellType<?> spell, double x, double y) {
renderSpell(context, spell, x, y, 1);
}
static void renderSpell(DrawContext context, CustomisedSpellType<?> spell, double x, double y, float scale) {
if (spell.isEmpty()) {
return;
}
MinecraftClient client = MinecraftClient.getInstance();
Pony pony = Pony.of(client.player);
if (pony.getSpellSlot().contains(spell.and(SpellPredicate.IS_VISIBLE))) {
MatrixStack modelStack = context.getMatrices();
float ringScale = (0.7F + scale);
modelStack.push();
modelStack.translate(x + 8 * scale, y + 8 * scale, 0);
int color = spell.type().getColor() | 0x000000FF;
double radius = (1.5F + Math.sin(client.player.age / 9D) / 4) * ringScale;
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(1, 1, 900);
modelStack.scale(0.8F, 0.8F, 0.8F);
context.drawText(client.textRenderer, count > 64 ? "64+" : String.valueOf(count), 0, 0, 0xFFFFFFFF, true);
modelStack.pop();
}
modelStack.pop();
}
DrawableUtil.renderItemIcon(context, spell.getDefaultStack(), x, y, scale);
}
}

View file

@ -5,8 +5,6 @@ import java.util.List;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.ability.*;
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.ability.magic.spell.TimedSpell;
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.client.sound.*;
@ -171,50 +169,13 @@ public class UHud {
matrices.pop();
if (canCast) {
renderSpell(context, pony.getCharms().getEquippedSpell(Hand.MAIN_HAND), hudX + 10 - xDirection * 13, hudY + 2);
renderSpell(context, pony.getCharms().getEquippedSpell(Hand.OFF_HAND), hudX + 8 - xDirection * 2, hudY - 6);
SpellIconRenderer.renderSpell(context, pony.getCharms().getEquippedSpell(Hand.MAIN_HAND), hudX + 10 - xDirection * 13, hudY + 2, EQUIPPED_GEMSTONE_SCALE);
SpellIconRenderer.renderSpell(context, pony.getCharms().getEquippedSpell(Hand.OFF_HAND), hudX + 8 - xDirection * 2, hudY - 6, EQUIPPED_GEMSTONE_SCALE);
}
RenderSystem.disableBlend();
}
public void renderSpell(DrawContext context, CustomisedSpellType<?> spell, double x, double y) {
if (spell.isEmpty()) {
return;
}
Pony pony = Pony.of(client.player);
if (spell.isOn(pony)) {
MatrixStack modelStack = context.getMatrices();
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(1, 1, 900);
modelStack.scale(0.8F, 0.8F, 0.8F);
context.drawText(font, count > 64 ? "64+" : String.valueOf(count), 0, 0, 0xFFFFFFFF, true);
modelStack.pop();
}
modelStack.pop();
}
DrawableUtil.renderItemIcon(context, spell.getDefaultStack(), x, y, EQUIPPED_GEMSTONE_SCALE);
}
private void renderMessage(DrawContext context, float tickDelta) {
float time = messageTime - tickDelta;
int progress = Math.min(255, (int)(time * 255F / 20F));