Skip to content

Commit

Permalink
Wards to fend off evil
Browse files Browse the repository at this point in the history
  • Loading branch information
StellarWitch7 committed Jul 6, 2024
1 parent e528da4 commit 63c9abf
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public class ModEntityCumponents implements EntityComponentInitializer {
public static final ComponentKey<ManaComponent> MANA =
ComponentRegistry.getOrCreate(Trickster.id("mana"), ManaComponent.class);

public static final ComponentKey<WardComponent> WARD =
ComponentRegistry.getOrCreate(Trickster.id("ward"), WardComponent.class);

public static final ComponentKey<DisguiseCumponent> DISGUISE =
ComponentRegistry.getOrCreate(Trickster.id("disguise"), DisguiseCumponent.class);

Expand All @@ -21,6 +24,7 @@ public class ModEntityCumponents implements EntityComponentInitializer {
@Override
public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) {
registry.registerFor(LivingEntity.class, MANA, ManaComponent::new);
registry.registerForPlayers(WARD, WardComponent::new, RespawnCopyStrategy.CHARACTER);
registry.registerForPlayers(DISGUISE, DisguiseCumponent::new, RespawnCopyStrategy.LOSSLESS_ONLY);
registry.registerForPlayers(IS_EDITING_SCROLL, IsEditingScrollComponent::new, RespawnCopyStrategy.NEVER_COPY);
}
Expand Down
111 changes: 111 additions & 0 deletions src/main/java/dev/enjarai/trickster/cca/WardComponent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package dev.enjarai.trickster.cca;

import dev.enjarai.trickster.spell.*;
import dev.enjarai.trickster.spell.fragment.EntityFragment;
import dev.enjarai.trickster.spell.fragment.FragmentType;
import dev.enjarai.trickster.spell.fragment.ListFragment;
import dev.enjarai.trickster.spell.tricks.Trick;
import dev.enjarai.trickster.spell.tricks.blunder.BlunderException;
import dev.enjarai.trickster.spell.tricks.blunder.WardModifiedSelfBlunder;
import dev.enjarai.trickster.spell.tricks.blunder.WardReturnBlunder;
import io.wispforest.endec.impl.KeyedEndec;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
import org.ladysnake.cca.api.v3.component.Component;

import java.util.List;

public class WardComponent implements Component {
private static final KeyedEndec<SpellPart> SPELL = SpellPart.ENDEC.keyed("handler", () -> null);

private final PlayerEntity player;
@Nullable
private SpellPart spell;

public WardComponent(PlayerEntity player) {
this.player = player;
}

@Override
public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
if (spell != null)
tag.put(SPELL, spell);
}

@Override
public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
spell = tag.get(SPELL);
}

public void register(SpellPart spell) {
this.spell = spell;
}

public List<Fragment> run(SpellContext triggerCtx, Trick source, SpellPart triggerSpell, List<Fragment> inputs) throws BlunderException {
if (spell == null)
return inputs;

var manaPool = ModEntityCumponents.MANA.get(player);
var finalResult = inputs;
boolean isModified = false;
boolean applyBacklashIfModified = true;

try {
var ctx = new PlayerSpellContext((ServerPlayerEntity)this.player, EquipmentSlot.MAINHAND);
ctx.pushPartGlyph(List.of(triggerSpell, new ListFragment(inputs)));

var result = spell.run(ctx);
ctx.popPartGlyph();

if (result.type() == FragmentType.LIST) {
var newInputs = ((ListFragment)result).fragments();
int index = 0;

if (newInputs.size() != inputs.size())
throw new WardReturnBlunder();

for (var input : inputs) {
var inputType = input.type();
var newInput = newInputs.get(index);

if (!isModified && !newInput.equals(input)) {
isModified = true;
}

if (newInput.type() != inputType)
throw new WardReturnBlunder();

if (inputType == FragmentType.ENTITY) {
var entity = (EntityFragment)input;
var newEntity = (EntityFragment)newInput;

if (entity.uuid() == player.getUuid() && newEntity.uuid() != entity.uuid())
throw new WardModifiedSelfBlunder();
}

index++;
}

finalResult = newInputs;
} else throw new WardReturnBlunder();
} catch (BlunderException e) {
isModified = true;
applyBacklashIfModified = false;
player.sendMessage(Text.literal("Ward failure: ").append(e.createMessage()));
}

if (isModified) {
manaPool.decrease(14);

if (applyBacklashIfModified)
triggerCtx.useMana(source, 9);
}

return finalResult;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand han
if (!world.isClient()) {
var spell = stack.get(ModComponents.SPELL);
if (spell != null) {
var singleUseManaPool = SimpleManaPool.getSingleUse(500);
var singleUseManaPool = SimpleManaPool.getSingleUse(meta.mana());
spell.spell().runSafely(new PlayerSpellContext((ServerPlayerEntity) user, singleUseManaPool, slot));
((ServerPlayerEntity) user).getServerWorld().playSoundFromEntity(
null, user, ModSounds.CAST, SoundCategory.PLAYERS, 1f, ModSounds.randomPitch(0.8f, 0.2f));
Expand Down Expand Up @@ -94,7 +94,7 @@ public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> to
tooltip.add(Text.translatable("book.generation." + meta.generation()).formatted(Formatting.GRAY));

if (meta.executable()) {
tooltip.add(Text.translatable("trickster.scroll_executable").formatted(Formatting.GRAY));
tooltip.add(Text.translatable("trickster.scroll_executable").append(": " + meta.mana()).formatted(Formatting.GRAY));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,33 @@
import net.minecraft.network.codec.PacketCodecs;
import org.jetbrains.annotations.Nullable;

public record WrittenScrollMetaComponent(String title, String author, int generation, boolean executable) {
public record WrittenScrollMetaComponent(String title, String author, int generation, boolean executable, float mana) {
public static final Codec<WrittenScrollMetaComponent> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.STRING.fieldOf("title").forGetter(WrittenScrollMetaComponent::title),
Codec.STRING.fieldOf("author").forGetter(WrittenScrollMetaComponent::author),
Codec.INT.fieldOf("generation").forGetter(WrittenScrollMetaComponent::generation),
Codec.BOOL.fieldOf("executable").forGetter(WrittenScrollMetaComponent::executable)
Codec.BOOL.fieldOf("executable").forGetter(WrittenScrollMetaComponent::executable),
Codec.FLOAT.fieldOf("mana").forGetter(WrittenScrollMetaComponent::mana)
).apply(instance, WrittenScrollMetaComponent::new));
public static final PacketCodec<RegistryByteBuf, WrittenScrollMetaComponent> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.STRING, WrittenScrollMetaComponent::title,
PacketCodecs.STRING, WrittenScrollMetaComponent::author,
PacketCodecs.INTEGER, WrittenScrollMetaComponent::generation,
PacketCodecs.BOOL, WrittenScrollMetaComponent::executable,
PacketCodecs.FLOAT, WrittenScrollMetaComponent::mana,
WrittenScrollMetaComponent::new
);

public WrittenScrollMetaComponent(String title, String author, int generation) {
this(title, author, generation, false);
this(title, author, generation, false, 0);
}

@Nullable
public WrittenScrollMetaComponent copy() {
return this.generation >= 2 ? null : new WrittenScrollMetaComponent(title, author, generation + 1, false);
return this.generation >= 2 ? null : new WrittenScrollMetaComponent(title, author, generation + 1);
}

public WrittenScrollMetaComponent withExecutable() {
return new WrittenScrollMetaComponent(title, author, generation, true);
public WrittenScrollMetaComponent withExecutable(float manaBufferSize) {
return new WrittenScrollMetaComponent(title, author, generation, true, manaBufferSize);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public ItemStack craft(CraftingRecipeInput craftingRecipeInput, RegistryWrapper.
var meta = itemStack.get(ModComponents.WRITTEN_SCROLL_META);
var spell = itemStack.get(ModComponents.SPELL);
if (!itemStack.isEmpty() && i >= 1 && meta != null && spell != null) {
var newMeta = meta.withExecutable();
var newMeta = meta.withExecutable(500);
ItemStack itemStack3 = itemStack.copyWithCount(1);
itemStack3.set(ModComponents.WRITTEN_SCROLL_META, newMeta);
itemStack3.set(ModComponents.SPELL, spell);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dev.enjarai.trickster.spell.tricks.blunder;

import net.minecraft.text.MutableText;
import net.minecraft.text.Text;

public class WardModifiedSelfBlunder extends BlunderException {
@Override
public MutableText createMessage() {
return Text.literal("Ward handler replaced owner reference");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dev.enjarai.trickster.spell.tricks.blunder;

import net.minecraft.text.MutableText;
import net.minecraft.text.Text;

public class WardReturnBlunder extends BlunderException {
@Override
public MutableText createMessage() {
return Text.literal("Ward handler return invalid");
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package dev.enjarai.trickster.spell.tricks.entity;

import dev.enjarai.trickster.spell.Fragment;
import dev.enjarai.trickster.spell.Pattern;
import dev.enjarai.trickster.spell.SpellContext;
import dev.enjarai.trickster.cca.ModEntityCumponents;
import dev.enjarai.trickster.spell.*;
import dev.enjarai.trickster.spell.fragment.FragmentType;
import dev.enjarai.trickster.spell.fragment.VoidFragment;
import dev.enjarai.trickster.spell.tricks.Trick;
import dev.enjarai.trickster.spell.tricks.Tricks;
import dev.enjarai.trickster.spell.tricks.blunder.BlunderException;
import dev.enjarai.trickster.spell.tricks.blunder.UnknownEntityBlunder;
import net.minecraft.entity.player.PlayerEntity;

import java.util.ArrayList;
import java.util.List;

public class AddVelocityTrick extends Trick {
Expand All @@ -21,12 +23,17 @@ public Fragment activate(SpellContext ctx, List<Fragment> fragments) throws Blun
var entity = expectInput(fragments, FragmentType.ENTITY, 0);
var velocity = expectInput(fragments, FragmentType.VECTOR, 1);

var player = entity.getEntity(ctx).orElseThrow(() -> new UnknownEntityBlunder(this));
var target = entity.getEntity(ctx).orElseThrow(() -> new UnknownEntityBlunder(this));

ctx.useMana(this, (float)velocity.vector().length() * 4);
if (target instanceof PlayerEntity player) {
fragments = ModEntityCumponents.WARD.get(player)
.run(ctx, this, new SpellPart(new PatternGlyph(4, 6, 0, 1, 2, 8, 4), new ArrayList<>()), fragments);
velocity = expectInput(fragments, FragmentType.VECTOR, 1);
}

player.addVelocity(velocity.vector().x(), velocity.vector().y(), velocity.vector().z());
player.velocityModified = true;
ctx.useMana(this, (float)velocity.vector().length() * 4);
target.addVelocity(velocity.vector().x(), velocity.vector().y(), velocity.vector().z());
target.velocityModified = true;

return VoidFragment.INSTANCE;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.enjarai.trickster.spell.tricks.event;

import dev.enjarai.trickster.cca.ModEntityCumponents;
import dev.enjarai.trickster.spell.Fragment;
import dev.enjarai.trickster.spell.Pattern;
import dev.enjarai.trickster.spell.SpellContext;
Expand All @@ -21,8 +22,10 @@ public Fragment activate(SpellContext ctx, List<Fragment> fragments) throws Blun
if (ctx.getPlayer().isEmpty())
throw new NoPlayerBlunder(this);

var ward = expectInput(fragments, FragmentType.SPELL_PART, 0);
var player = ctx.getPlayer().get();
var wardHandler = expectInput(fragments, FragmentType.SPELL_PART, 0);

ModEntityCumponents.WARD.get(player).register(wardHandler.deepClone());
return VoidFragment.INSTANCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ and you have 250 kilogandalfs of blood mana.
;;;;;

Mana regenerates over time at 0.5%/s. Maximum mana is always equivalent to maximum health times 24.
Current blood mana is always equivalent to current health times 24.
Current blood mana is always equivalent to current health times 25.

;;;;;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
```

Wards are defensive spells that are cast when you are target by a ploy.
Wards are defensive spells that are cast when you are the target of a ploy.
Your warding handler receives the glyph that is targeting you and a list containing the inputs the caster is passing to the glyph.
The expected signature for a warding handler is the following:

Expand Down
1 change: 1 addition & 0 deletions src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"cardinal-components": [
"trickster:shadow_disguise_map",
"trickster:mana",
"trickster:ward",
"trickster:disguise",
"trickster:is_editing_scroll"
]
Expand Down

0 comments on commit 63c9abf

Please sign in to comment.