trying to make a better api, pushing for help with subscribe events

This commit is contained in:
gamma-delta 2021-12-29 17:12:00 -06:00
parent db850be39f
commit d2ddf6861d
30 changed files with 350 additions and 196 deletions

View file

@ -1,7 +1,9 @@
package at.petrak.hex;
import at.petrak.hex.client.RegisterClientStuff;
import at.petrak.hex.common.items.HexItems;
import at.petrak.hex.common.network.HexMessages;
import at.petrak.hex.server.RegisterServerStuff;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@ -21,5 +23,9 @@ public class HexMod {
MinecraftForge.EVENT_BUS.register(this);
HexItems.ITEMS.register(evbus);
HexMessages.register();
// Init the client and server to make the subscribe events work
new RegisterServerStuff();
new RegisterClientStuff();
}
}

View file

@ -0,0 +1,94 @@
package at.petrak.hex.api
import at.petrak.hex.common.casting.CastException
import at.petrak.hex.hexmath.HexPattern
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedDeque
import java.util.concurrent.ConcurrentMap
/**
* Register your patterns and associate them with spells here.
*
* Most patterns are matches to their operators solely by their *angle signature*.
* This is a record of all the angles in the pattern, independent of the direction the player started drawing in.
* It's written in shorthand, where `w` is straight ahead, `q` is left, `a` is left-back, `d` is right-back,
* and `e` is right.
*
* For example, the signature for a straight line of 3 segments is `"ww"`. The signatures for the "get caster"
* operator (the diamond) are `"qaq"` and `"ede"`.
*/
object PatternRegistry {
private val regularPatterns: ConcurrentMap<String, SpellOperator> = ConcurrentHashMap()
private val specialHandlers: ConcurrentLinkedDeque<SpecialHandler> = ConcurrentLinkedDeque()
/**
* Associate a given angle signature with a SpellOperator.
*/
@JvmStatic
@Throws(RegisterPatternException::class)
fun addRegularPattern(signature: String, operator: SpellOperator) {
if (this.regularPatterns.containsKey(signature))
throw RegisterPatternException("The signature `$signature` already exists")
this.regularPatterns[signature] = operator
}
/**
* Associate a given angle signature and its mirror image with a SpellOperator.
*/
@JvmStatic
@Throws(RegisterPatternException::class)
fun addRegularPatternAndMirror(signature: String, operator: SpellOperator) {
this.addRegularPattern(signature, operator)
val flipped = mirrorSig(signature)
if (flipped != signature) {
this.addRegularPattern(signature, operator)
}
}
/**
* Add a special handler, to take an arbitrary pattern and return whatever kind of operator you like.
*/
@JvmStatic
fun addSpecialHandler(handler: SpecialHandler) {
this.specialHandlers.add(handler)
}
fun lookupPattern(pat: HexPattern): SpellOperator {
for (handler in specialHandlers) {
val op = handler.handlePattern(pat)
if (op != null) return op
}
val sig = pat.anglesSignature()
return this.regularPatterns.getOrElse(sig) {
throw CastException(CastException.Reason.INVALID_PATTERN, pat)
}
}
/**
* Special handling of a pattern. Before checking any of the normal angle-signature based patterns,
* a given pattern is run by all of these special handlers patterns. If none of them return non-null,
* then its signature is checked.
*
* In the base mod, this is used for number patterns.
*/
fun interface SpecialHandler {
fun handlePattern(pattern: HexPattern): SpellOperator?
}
private fun mirrorSig(sig: String): String = buildString {
for (c in sig.chars()) {
append(
when (c.toChar()) {
'q' -> 'e'
'a' -> 'd'
'e' -> 'q'
'd' -> 'a'
else -> c
}
)
}
}
class RegisterPatternException(msg: String) : java.lang.Exception(msg)
}

View file

@ -1,9 +1,8 @@
package at.petrak.hex.common.casting.operators
package at.petrak.hex.api
import at.petrak.hex.common.casting.CastException
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator
/**
* An operator that acts in the expected method of popping some arguments

View file

@ -0,0 +1,72 @@
package at.petrak.hex.api
import at.petrak.hex.common.casting.CastException
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import net.minecraft.world.phys.Vec3
/**
* Manipulates the stack in some way, usually by popping some number of values off the stack
* and pushing one new value.
* For a more "traditional" pop arguments, push return experience, see
* [SimpleOperator][at.petrak.hex.common.casting.operators.SimpleOperator]
*
* Implementors MUST NOT mutate the context.
*/
interface SpellOperator {
val manaCost: Int
get() = 0
fun modifyStack(stack: MutableList<SpellDatum<*>>, ctx: CastingContext)
companion object {
// I see why vzakii did this: you can't raycast out to infinity!
const val MAX_DISTANCE: Double = 32.0
@JvmStatic
fun raycastEnd(origin: Vec3, look: Vec3): Vec3 =
origin.add(look.normalize().scale(MAX_DISTANCE))
/**
* Try to get a value of the given type.
*/
@JvmStatic
inline fun <reified T : Any> List<SpellDatum<*>>.getChecked(idx: Int): T =
this[idx].tryGet()
/**
* Check if the value at the given index is OK. Will throw an error otherwise.
*/
@JvmStatic
inline fun <reified T : Any> List<SpellDatum<*>>.assertChecked(idx: Int) {
this.getChecked<T>(idx)
}
/**
* Make sure the vector is in range of the player.
*/
@JvmStatic
fun assertVecInRange(vec: Vec3, ctx: CastingContext) {
if (vec.distanceToSqr(ctx.caster.position()) > MAX_DISTANCE * MAX_DISTANCE)
throw CastException(CastException.Reason.TOO_FAR, vec)
}
@JvmStatic
fun spellListOf(vararg vs: Any): List<SpellDatum<*>> {
val out = ArrayList<SpellDatum<*>>(vs.size)
for (v in vs) {
out.add(SpellDatum.make(v))
}
return out
}
@JvmStatic
fun makeConstantOp(x: SpellDatum<*>): SpellOperator = object : SimpleOperator {
override val argc: Int
get() = 0
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> =
spellListOf(x)
}
}
}

View file

@ -1,6 +1,7 @@
package at.petrak.hex.common.casting
import at.petrak.hex.HexMod
import at.petrak.hex.api.PatternRegistry
import at.petrak.hex.hexmath.HexPattern
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
@ -27,7 +28,7 @@ class CastingHarness private constructor(
return try {
var exn: CastException? = null
val operator = try {
SpellOperator.fromPattern(newPat)
PatternRegistry.lookupPattern(newPat)
} catch (e: CastException) {
exn = e
null
@ -64,24 +65,7 @@ class CastingHarness private constructor(
this.stack.add(SpellDatum.make(newPat))
} else {
// Plain ol operator
val sig = newPat.anglesSignature()
if (sig.startsWith("aqaa") || sig.startsWith("dedd")) {
val negate = sig.startsWith("dedd")
var accumulator = 0.0
for (chr in sig.substring(4)) {
when (chr) {
'w' -> accumulator += 1
'q' -> accumulator += 5
'e' -> accumulator += 10
'a' -> accumulator *= 2
'd' -> accumulator /= 2
}
}
if (negate) {
accumulator = -accumulator
}
this.stack.add(SpellDatum.make(accumulator))
} else if (exn != null) {
if (exn != null) {
// there was a problem finding the pattern and it was NOT due to numbers
throw exn
} else if (operator == SpellWidget.OPEN_PAREN) {

View file

@ -87,6 +87,7 @@ class SpellDatum<T : Any> private constructor(val payload: T) {
}
companion object {
@JvmStatic
fun make(payload: Any): SpellDatum<*> =
if (!IsValidType(payload)) {
// Check to see if it's a java boxed double

View file

@ -1,134 +0,0 @@
package at.petrak.hex.common.casting
import at.petrak.hex.common.casting.operators.*
import at.petrak.hex.common.casting.operators.math.*
import at.petrak.hex.common.casting.operators.spells.OpAddMotion
import at.petrak.hex.common.casting.operators.spells.OpExplode
import at.petrak.hex.common.casting.operators.spells.OpPrint
import at.petrak.hex.hexmath.HexPattern
import net.minecraft.world.phys.Vec3
/**
* Manipulates the stack in some way, usually by popping some number of values off the stack
* and pushing one new value.
* For a more "traditional" pop arguments, push return experience, see
* [SimpleOperator][at.petrak.hex.common.casting.operators.SimpleOperator]
*
* Implementors MUST NOT mutate the context.
*/
interface SpellOperator {
val manaCost: Int
get() = 0
fun modifyStack(stack: MutableList<SpellDatum<*>>, ctx: CastingContext)
companion object {
val PatternMap: Map<String, SpellOperator> = mapOf(
// == Getters ==
// diamond shape to get the caster
"qaq" to OpGetCaster,
"ede" to OpGetCaster,
// small triangle to get the entity pos
"aa" to OpEntityPos,
"dd" to OpEntityPos,
// Arrow to get the look vector
"wa" to OpEntityLook,
"wd" to OpEntityLook,
// CCW battleaxe for block raycast
"wqaawdd" to OpBlockRaycast,
// and CW for axis raycast
"weddwaa" to OpBlockAxisRaycast,
// CCW diamond mace thing for entity raycast
"weaqa" to OpEntityRaycast,
// == Modify Stack ==
// CCW hook for undo
"a" to OpUndo,
// and CW for null
"d" to SpellWidget.NULL,
// Two triangles holding hands to duplicate
"aadaa" to OpDuplicate,
// Two opposing triangles to swap
"aawdd" to OpSwap,
// == Math ==
"waaw" to OpAdd,
"wddw" to OpSub,
"waqaw" to OpMulDot,
"wdedw" to OpDivCross,
"wqaqw" to OpAbsLen,
"wedew" to OpPowProj,
// == Spells ==
// hook for debug
"de" to OpPrint,
"aq" to OpPrint,
// nuclear sign for explosion
"aawaawaa" to OpExplode,
"weeewdq" to OpAddMotion,
// == Meta stuff ==
"qqq" to SpellWidget.OPEN_PAREN,
"eee" to SpellWidget.CLOSE_PAREN,
"qqqaw" to SpellWidget.ESCAPE,
// http://www.toroidalsnark.net/mkss3-pix/CalderheadJMM2014.pdf
// eval being a space filling curve feels apt doesn't it
"deaqq" to OpEval,
"aqqqqq" to OpReadFromSpellbook,
"deeeee" to OpWriteToSpellbook,
)
/**
* May throw CastException
*/
fun fromPattern(pattern: HexPattern): SpellOperator =
PatternMap.getOrElse(pattern.anglesSignature()) {
throw CastException(CastException.Reason.INVALID_PATTERN, pattern)
}
// I see why vzakii did this: you can't raycast out to infinity!
const val MAX_DISTANCE: Double = 32.0
@JvmStatic
fun raycastEnd(origin: Vec3, look: Vec3): Vec3 =
origin.add(look.normalize().scale(MAX_DISTANCE))
/**
* Try to get a value of the given type.
*/
@JvmStatic
inline fun <reified T : Any> List<SpellDatum<*>>.getChecked(idx: Int): T =
this[idx].tryGet()
/**
* Check if the value at the given index is OK. Will throw an error otherwise.
*/
@JvmStatic
inline fun <reified T : Any> List<SpellDatum<*>>.assertChecked(idx: Int) {
this.getChecked<T>(idx)
}
/**
* Make sure the vector is in range of the player.
*/
@JvmStatic
fun assertVecInRange(vec: Vec3, ctx: CastingContext) {
if (vec.distanceToSqr(ctx.caster.position()) > MAX_DISTANCE * MAX_DISTANCE)
throw CastException(CastException.Reason.TOO_FAR, vec)
}
@JvmStatic
fun spellListOf(vararg vs: Any): List<SpellDatum<*>> {
val out = ArrayList<SpellDatum<*>>(vs.size)
for (v in vs) {
out.add(SpellDatum.make(v))
}
return out
}
}
}

View file

@ -1,7 +1,7 @@
package at.petrak.hex.common.casting
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
/**
* Miscellaneous spell datums used as markers, etc.

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator
import at.petrak.hex.api.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator
import at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellWidget
import net.minecraft.world.level.ClipContext
import net.minecraft.world.phys.HitResult

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator
import at.petrak.hex.api.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator
import at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellWidget
import net.minecraft.world.level.ClipContext
import net.minecraft.world.phys.HitResult

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
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 at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
object OpDuplicate : SimpleOperator {
override val argc: Int

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
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 at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import net.minecraft.world.entity.Entity
object OpEntityLook : SimpleOperator {

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
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 at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.player.Player

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator
import at.petrak.hex.api.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator
import at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellWidget
import net.minecraft.world.entity.projectile.ProjectileUtil
import net.minecraft.world.phys.AABB

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.CastingHarness
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
object OpEval : SimpleOperator {
override val argc: Int

View file

@ -1,8 +1,9 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator
import net.minecraft.world.entity.Entity
object OpGetCaster : SimpleOperator {

View file

@ -1,5 +1,6 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellWidget

View file

@ -1,9 +1,10 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
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 at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
object OpSwap : SimpleOperator {
override val argc: Int

View file

@ -1,5 +1,6 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum

View file

@ -1,8 +1,9 @@
package at.petrak.hex.common.casting.operators
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.items.ItemSpellbook
object OpWriteToSpellbook : SimpleOperator {

View file

@ -1,9 +1,9 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import kotlin.math.absoluteValue
object OpAbsLen : SimpleOperator {

View file

@ -1,9 +1,9 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
object OpAdd : SimpleOperator {
override val argc: Int

View file

@ -1,9 +1,9 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import net.minecraft.world.phys.Vec3
object OpDivCross : SimpleOperator {

View file

@ -1,9 +1,9 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
object OpMulDot : SimpleOperator {
override val argc: Int

View file

@ -1,9 +1,9 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import net.minecraft.world.phys.Vec3
import kotlin.math.pow

View file

@ -1,9 +1,9 @@
package at.petrak.hex.common.casting.operators.math
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.CastingContext
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import net.minecraft.world.phys.Vec3
object OpSub : SimpleOperator {

View file

@ -1,12 +1,12 @@
package at.petrak.hex.common.casting.operators.spells
import at.petrak.hex.api.SimpleOperator
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.RenderedSpell
import at.petrak.hex.common.casting.RenderedSpellImpl
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import at.petrak.hex.common.network.HexMessages
import at.petrak.hex.common.network.MsgAddMotionAck
import net.minecraft.server.level.ServerPlayer

View file

@ -1,13 +1,13 @@
package at.petrak.hex.common.casting.operators.spells
import at.petrak.hex.api.SimpleOperator
import at.petrak.hex.api.SpellOperator.Companion.assertVecInRange
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.RenderedSpell
import at.petrak.hex.common.casting.RenderedSpellImpl
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.assertVecInRange
import at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import net.minecraft.world.level.Explosion
import net.minecraft.world.phys.Vec3

View file

@ -1,12 +1,12 @@
package at.petrak.hex.common.casting.operators.spells
import at.petrak.hex.api.SimpleOperator
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.RenderedSpell
import at.petrak.hex.common.casting.RenderedSpellImpl
import at.petrak.hex.common.casting.SpellDatum
import at.petrak.hex.common.casting.SpellOperator.Companion.getChecked
import at.petrak.hex.common.casting.SpellOperator.Companion.spellListOf
import at.petrak.hex.common.casting.operators.SimpleOperator
import net.minecraft.Util
import net.minecraft.network.chat.TextComponent

View file

@ -0,0 +1,120 @@
package at.petrak.hex.server;
import at.petrak.hex.HexMod;
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.OpAddMotion;
import at.petrak.hex.common.casting.operators.spells.OpExplode;
import at.petrak.hex.common.casting.operators.spells.OpPrint;
import com.mojang.datafixers.util.Pair;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent;
@Mod.EventBusSubscriber(modid = HexMod.MOD_ID, value = Dist.DEDICATED_SERVER, bus = Mod.EventBusSubscriber.Bus.MOD)
public class RegisterServerStuff {
@SubscribeEvent
public static void registerSpellPatterns(FMLDedicatedServerSetupEvent evt) {
int count = 0;
try {
for (Pair<String, SpellOperator> p : new Pair[]{
// == Getters ==
// diamond shape to get the caster
new Pair<>("qaq", OpGetCaster.INSTANCE),
new Pair<>("ede", OpGetCaster.INSTANCE),
// small triangle to get the entity pos
new Pair<>("aa", OpEntityPos.INSTANCE),
new Pair<>("dd", OpEntityPos.INSTANCE),
// Arrow to get the look vector
new Pair<>("wa", OpEntityLook.INSTANCE),
new Pair<>("wd", OpEntityLook.INSTANCE),
// CCW battleaxe for block raycast
new Pair<>("wqaawdd", OpBlockRaycast.INSTANCE),
// and CW for axis raycast
new Pair<>("weddwaa", OpBlockAxisRaycast.INSTANCE),
// CCW diamond mace thing for entity raycast
new Pair<>("weaqa", OpEntityRaycast.INSTANCE),
// == Modify Stack ==
// CCW hook for undo
new Pair<>("a", OpUndo.INSTANCE),
// and CW for null
new Pair<>("d", SpellWidget.NULL),
// Two triangles holding hands to duplicate
new Pair<>("aadaa", OpDuplicate.INSTANCE),
// Two opposing triangles to swap
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 ==
// hook for debug
new Pair<>("de", OpPrint.INSTANCE),
new Pair<>("aq", OpPrint.INSTANCE),
// nuclear sign for explosion
new Pair<>("aawaawaa", OpExplode.INSTANCE),
new Pair<>("weeewdq", OpAddMotion.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", OpReadFromSpellbook.INSTANCE),
new Pair<>("deeeee", OpWriteToSpellbook.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);
}
}