some bugfixes, very untested

This commit is contained in:
gamma-delta 2021-12-30 18:22:21 -06:00
parent 11042f3008
commit 9da0470090
21 changed files with 202 additions and 148 deletions

View file

@ -1,21 +1,12 @@
package at.petrak.hex;
import at.petrak.hex.api.PatternRegistry;
import at.petrak.hex.api.SpellOperator;
import at.petrak.hex.common.casting.SpellDatum;
import at.petrak.hex.common.casting.SpellWidget;
import at.petrak.hex.common.casting.operators.*;
import at.petrak.hex.common.casting.operators.math.*;
import at.petrak.hex.common.casting.operators.spells.*;
import at.petrak.hex.common.casting.RegisterSpells;
import at.petrak.hex.common.items.HexItems;
import at.petrak.hex.common.network.HexMessages;
import at.petrak.hex.server.TickScheduler;
import com.mojang.datafixers.util.Pair;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -44,97 +35,7 @@ public class HexMod {
HexItems.ITEMS.register(evbus);
HexMessages.register();
MinecraftForge.EVENT_BUS.register(TickScheduler.INSTANCE);
}
// I guess this means the client will have a big empty map for patterns
@SubscribeEvent
public static void registerSpellPatterns(FMLCommonSetupEvent evt) {
int count = 0;
try {
for (Pair<String, SpellOperator> p : new Pair[]{
// == Getters ==
new Pair<>("qaq", OpGetCaster.INSTANCE),
new Pair<>("ede", OpGetCaster.INSTANCE),
new Pair<>("aa", OpEntityPos.INSTANCE),
new Pair<>("dd", OpEntityPos.INSTANCE),
new Pair<>("wa", OpEntityLook.INSTANCE),
new Pair<>("wd", OpEntityLook.INSTANCE),
new Pair<>("wqaawdd", OpBlockRaycast.INSTANCE),
new Pair<>("weddwaa", OpBlockAxisRaycast.INSTANCE),
new Pair<>("weaqa", OpEntityRaycast.INSTANCE),
// == Modify Stack ==
new Pair<>("a", OpUndo.INSTANCE),
new Pair<>("d", SpellWidget.NULL),
new Pair<>("aadaa", OpDuplicate.INSTANCE),
new Pair<>("aawdd", OpSwap.INSTANCE),
// == Math ==
new Pair<>("waaw", OpAdd.INSTANCE),
new Pair<>("wddw", OpSub.INSTANCE),
new Pair<>("waqaw", OpMulDot.INSTANCE),
new Pair<>("wdedw", OpDivCross.INSTANCE),
new Pair<>("wqaqw", OpAbsLen.INSTANCE),
new Pair<>("wedew", OpPowProj.INSTANCE),
// == Spells ==
new Pair<>("de", OpPrint.INSTANCE),
new Pair<>("aq", OpPrint.INSTANCE),
new Pair<>("aawaawaa", OpExplode.INSTANCE),
new Pair<>("weeewdq", OpAddMotion.INSTANCE),
new Pair<>("qaqqqqq", OpPlaceBlock.INSTANCE),
new Pair<>("eeeeede", OpBreakBlock.INSTANCE),
new Pair<>("waadwawdaaweewq", OpLightning.INSTANCE),
// == Meta stuff ==
new Pair<>("qqq", SpellWidget.OPEN_PAREN),
new Pair<>("eee", SpellWidget.CLOSE_PAREN),
new Pair<>("qqqaw", SpellWidget.ESCAPE),
// http://www.toroidalsnark.net/mkss3-pix/CalderheadJMM2014.pdf
// eval being a space filling curve feels apt doesn't it
new Pair<>("deaqq", OpEval.INSTANCE),
new Pair<>("aqqqqq", OpRead.INSTANCE),
new Pair<>("deeeee", OpWrite.INSTANCE),
}) {
PatternRegistry.addRegularPattern(p.getFirst(), p.getSecond());
count++;
}
} catch (PatternRegistry.RegisterPatternException exn) {
exn.printStackTrace();
}
// Add zilde->number
PatternRegistry.addSpecialHandler(pat -> {
var sig = pat.anglesSignature();
if (sig.startsWith("aqaa") || sig.startsWith("dedd")) {
var negate = sig.startsWith("dedd");
var accumulator = 0.0;
for (char ch : sig.substring(4).toCharArray()) {
if (ch == 'w') {
accumulator += 1;
} else if (ch == 'q') {
accumulator += 5;
} else if (ch == 'e') {
accumulator += 10;
} else if (ch == 'a') {
accumulator *= 2;
} else if (ch == 'd') {
accumulator /= 2;
}
}
if (negate) {
accumulator = -accumulator;
}
return SpellOperator.makeConstantOp(SpellDatum.make(accumulator));
} else {
return null;
}
});
HexMod.LOGGER.info("Registered {} patterns", count);
evbus.register(RegisterSpells.class);
}
}

View file

@ -16,9 +16,12 @@ public class RegisterClientStuff {
public static void init(final FMLClientSetupEvent evt) {
evt.enqueueWork(() -> ItemProperties.register(HexItems.FOCUS.get(), ItemFocus.PREDICATE,
(stack, level, holder, holderID) -> {
var tag = stack.getOrCreateTag();
var isSealed = tag.getBoolean(ItemFocus.TAG_SEALED);
var baseNum = isSealed ? 100f : 0f;
if (stack.hasTag()) {
var tagname = stack.getTag().getCompound(ItemFocus.TAG_DATA).getAllKeys().iterator().next();
return switch (tagname) {
var typename = tag.getCompound(ItemFocus.TAG_DATA).getAllKeys().iterator().next();
return baseNum + switch (typename) {
case SpellDatum.TAG_ENTITY -> 1f;
case SpellDatum.TAG_DOUBLE -> 2f;
case SpellDatum.TAG_VEC3 -> 3f;
@ -29,7 +32,7 @@ public class RegisterClientStuff {
default -> 0f; // uh oh
};
} else {
return 0f;
return baseNum;
}
}));
}

View file

@ -0,0 +1,120 @@
package at.petrak.hex.common.casting;
import at.petrak.hex.HexMod;
import at.petrak.hex.api.PatternRegistry;
import at.petrak.hex.api.SpellOperator;
import at.petrak.hex.common.casting.operators.*;
import at.petrak.hex.common.casting.operators.math.*;
import at.petrak.hex.common.casting.operators.spells.*;
import com.mojang.datafixers.util.Pair;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
public class RegisterSpells {
// I guess this means the client will have a big empty map for patterns
@SubscribeEvent
public static void registerSpellPatterns(FMLCommonSetupEvent evt) {
int count = 0;
try {
// In general:
// - CCW is the normal or construction version
// - CW is the special or destruction version
for (Pair<String, SpellOperator> p : new Pair[]{
// == Getters ==
new Pair<>("qaq", OpGetCaster.INSTANCE),
new Pair<>("ede", OpGetCaster.INSTANCE),
new Pair<>("aa", OpEntityPos.INSTANCE),
new Pair<>("dd", OpEntityPos.INSTANCE),
new Pair<>("wa", OpEntityLook.INSTANCE),
new Pair<>("wd", OpEntityLook.INSTANCE),
new Pair<>("wqaawdd", OpBlockRaycast.INSTANCE),
new Pair<>("weddwaa", OpBlockAxisRaycast.INSTANCE),
new Pair<>("weaqa", OpEntityRaycast.INSTANCE),
// == Modify Stack ==
new Pair<>("a", OpUndo.INSTANCE),
new Pair<>("d", SpellWidget.NULL),
new Pair<>("aadaa", OpDuplicate.INSTANCE),
new Pair<>("aawdd", OpSwap.INSTANCE),
// == Math ==
new Pair<>("waaw", OpAdd.INSTANCE),
new Pair<>("wddw", OpSub.INSTANCE),
new Pair<>("waqaw", OpMulDot.INSTANCE),
new Pair<>("wdedw", OpDivCross.INSTANCE),
new Pair<>("wqaqw", OpAbsLen.INSTANCE),
new Pair<>("wedew", OpPowProj.INSTANCE),
new Pair<>("eqqqqq", OpConstructVec.INSTANCE),
new Pair<>("qeeeee", OpDeconstructVec.INSTANCE),
// == Spells ==
new Pair<>("de", OpPrint.INSTANCE),
new Pair<>("aq", OpPrint.INSTANCE),
new Pair<>("aawaawaa", OpExplode.INSTANCE),
new Pair<>("weeewdq", OpAddMotion.INSTANCE),
new Pair<>("qaqqqqq", OpPlaceBlock.INSTANCE),
new Pair<>("eeeeede", OpBreakBlock.INSTANCE),
new Pair<>("waadwawdaaweewq", OpLightning.INSTANCE),
// == Meta stuff ==
new Pair<>("qqq", SpellWidget.OPEN_PAREN),
new Pair<>("eee", SpellWidget.CLOSE_PAREN),
new Pair<>("qqqaw", SpellWidget.ESCAPE),
// http://www.toroidalsnark.net/mkss3-pix/CalderheadJMM2014.pdf
// eval being a space filling curve feels apt doesn't it
new Pair<>("deaqq", OpEval.INSTANCE),
new Pair<>("aqqqqq", OpRead.INSTANCE),
new Pair<>("deeeee", OpWrite.INSTANCE),
// == Consts ==
new Pair<>("qqqqqqea", SpellOperator.makeConstantOp(SpellDatum.make(new Vec3(1.0, 0.0, 0.0)))),
new Pair<>("qqqqqqew", SpellOperator.makeConstantOp(SpellDatum.make(new Vec3(1.0, 1.0, 0.0)))),
new Pair<>("qqqqqqed", SpellOperator.makeConstantOp(SpellDatum.make(new Vec3(1.0, 0.0, 1.0)))),
new Pair<>("eeeeeeqa", SpellOperator.makeConstantOp(SpellDatum.make(new Vec3(-1.0, 0.0, 0.0)))),
new Pair<>("eeeeeeqw", SpellOperator.makeConstantOp(SpellDatum.make(new Vec3(1.0, -1.0, 0.0)))),
new Pair<>("eeeeeeqd", SpellOperator.makeConstantOp(SpellDatum.make(new Vec3(1.0, 0.0, -1.0)))),
}) {
PatternRegistry.addRegularPattern(p.getFirst(), p.getSecond());
count++;
}
} catch (PatternRegistry.RegisterPatternException exn) {
exn.printStackTrace();
}
// Add zilde->number
PatternRegistry.addSpecialHandler(pat -> {
var sig = pat.anglesSignature();
if (sig.startsWith("aqaa") || sig.startsWith("dedd")) {
var negate = sig.startsWith("dedd");
var accumulator = 0.0;
for (char ch : sig.substring(4).toCharArray()) {
if (ch == 'w') {
accumulator += 1;
} else if (ch == 'q') {
accumulator += 5;
} else if (ch == 'e') {
accumulator += 10;
} else if (ch == 'a') {
accumulator *= 2;
} else if (ch == 'd') {
accumulator /= 2;
}
}
if (negate) {
accumulator = -accumulator;
}
return SpellOperator.makeConstantOp(SpellDatum.make(accumulator));
} else {
return null;
}
});
HexMod.LOGGER.info("Registered {} patterns", count);
}
}

View file

@ -169,11 +169,12 @@ class SpellDatum<T : Any> private constructor(val payload: T) {
const val TAG_VEC3 = "vec3"
const val TAG_LIST = "list"
const val TAG_SPELL = "spell"
const val TAG_SPELL_NAME = "impler"
const val TAG_SPELL_ARGS = "args"
const val TAG_WIDGET = "widget"
const val TAG_PATTERN = "pattern"
const val TAG_SPELL_NAME = "impler"
const val TAG_SPELL_ARGS = "args"
fun <T : Any> IsValidType(checkee: T): Boolean =
if (checkee is List<*>) {
// note it should be impossible to pass a spell datum that doesn't contain a valid type,

View file

@ -29,7 +29,14 @@ object OpBlockRaycast : ConstManaOperator {
return SpellOperator.spellListOf(
if (blockHitResult.type == HitResult.Type.BLOCK) {
blockHitResult.location
// the position on the bhr is the position of the specific *hit point*, which is actually on the outside of the block
// this is weird (for example, casting OpBreakBlock at this position will not break the block we're looking at)
// so we return the block pos instead
Vec3(
blockHitResult.blockPos.x.toDouble(),
blockHitResult.blockPos.y.toDouble(),
blockHitResult.blockPos.z.toDouble()
)
} else {
SpellWidget.NULL
}

View file

@ -0,0 +1,18 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.ConstManaOperator
import at.petrak.hex.api.SpellOperator.Companion.getChecked
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import net.minecraft.world.phys.Vec3
object OpConstructVec : ConstManaOperator {
override val argc = 3
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
val x = args.getChecked<Double>(0)
val y = args.getChecked<Double>(1)
val z = args.getChecked<Double>(2)
return spellListOf(Vec3(x, y, z))
}
}

View file

@ -0,0 +1,16 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.ConstManaOperator
import at.petrak.hex.api.SpellOperator.Companion.getChecked
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import net.minecraft.world.phys.Vec3
object OpDeconstructVec : ConstManaOperator {
override val argc = 1
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
val v = args.getChecked<Vec3>(0)
return spellListOf(v.x, v.y, v.z)
}
}

View file

@ -8,6 +8,9 @@ import at.petrak.hex.common.casting.RenderedSpell
import at.petrak.hex.common.casting.RenderedSpellImpl
import at.petrak.hex.common.casting.SpellDatum
import net.minecraft.core.BlockPos
import net.minecraft.core.particles.BlockParticleOption
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.sounds.SoundSource
import net.minecraft.world.InteractionResult
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.context.UseOnContext
@ -63,6 +66,14 @@ object OpPlaceBlock : SimpleOperator, RenderedSpellImpl {
ctx.caster.setItemInHand(ctx.wandHand, oldStack)
if (res != InteractionResult.FAIL) {
ctx.withdrawItem(placee, 1, true)
ctx.world.playSound(
ctx.caster,
vec.x, vec.y, vec.z, bstate.soundType.placeSound, SoundSource.BLOCKS, 1.0f,
1.0f + (Math.random() * 0.5 - 0.25).toFloat()
)
val particle = BlockParticleOption(ParticleTypes.BLOCK, bstate)
ctx.world.sendParticles(particle, vec.x, vec.y, vec.z, 4, 0.1, 0.2, 0.1, 0.1)
}
}
}

View file

@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable;
public class ItemFocus extends ItemDataHolder {
public static final ResourceLocation PREDICATE = new ResourceLocation(HexMod.MOD_ID, "datatype");
public static final String TAG_DATA = "data";
public static final String TAG_SEALED = "sealed";
public ItemFocus(Properties pProperties) {
super(pProperties);

View file

@ -20,47 +20,23 @@ public class ItemModels extends ItemModelProvider {
simpleItem(HexItems.WAND.get());
simpleItem(HexItems.SPELLBOOK.get());
simpleItem(modLoc("focus_empty"));
simpleItem(modLoc("focus_entity"));
simpleItem(modLoc("focus_double"));
simpleItem(modLoc("focus_vec3"));
simpleItem(modLoc("focus_spell"));
simpleItem(modLoc("focus_widget"));
simpleItem(modLoc("focus_list"));
simpleItem(modLoc("focus_patterns"));
getBuilder(HexItems.FOCUS.get().getRegistryName().getPath())
.override()
.predicate(ItemFocus.PREDICATE, -0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_empty")))
.end()
.override()
.predicate(ItemFocus.PREDICATE, 1 - 0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_entity")))
.end()
.override()
.predicate(ItemFocus.PREDICATE, 2 - 0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_double")))
.end()
.override()
.predicate(ItemFocus.PREDICATE, 3 - 0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_vec3")))
.end()
.override()
.predicate(ItemFocus.PREDICATE, 4 - 0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_spell")))
.end()
.override()
.predicate(ItemFocus.PREDICATE, 5 - 0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_widget")))
.end()
.override()
.predicate(ItemFocus.PREDICATE, 6 - 0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_list")))
.end()
.override()
.predicate(ItemFocus.PREDICATE, 7 - 0.01f)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_patterns")))
.end();
String[] focusTypes = new String[]{
"empty", "entity", "double", "vec3", "spell", "widget", "list", "pattern"
};
for (int i = 0, stringsLength = focusTypes.length; i < stringsLength; i++) {
String type = focusTypes[i];
simpleItem(modLoc("focus_" + type));
getBuilder(HexItems.FOCUS.get().getRegistryName().getPath())
.override()
.predicate(ItemFocus.PREDICATE, -0.01f + i)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_" + type)))
.end()
.override()
.predicate(ItemFocus.PREDICATE, -0.01f + 100 + i)
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_" + type + "_sealed")))
.end();
}
}
public void simpleItem(Item item) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

View file

Before

Width:  |  Height:  |  Size: 416 B

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B