probably fix #327?
This commit is contained in:
parent
3a8dfa6cc8
commit
725aa894d4
5 changed files with 56 additions and 40 deletions
|
@ -34,7 +34,7 @@ public class PatternRegistry {
|
||||||
new ConcurrentHashMap<>();
|
new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static void mapPattern(HexPattern pattern, ResourceLocation id,
|
public static void mapPattern(HexPattern pattern, ResourceLocation id,
|
||||||
Action action) throws RegisterPatternException {
|
Action action) throws RegisterPatternException {
|
||||||
mapPattern(pattern, id, action, false);
|
mapPattern(pattern, id, action, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class PatternRegistry {
|
||||||
* Associate a given angle signature with a SpellOperator.
|
* Associate a given angle signature with a SpellOperator.
|
||||||
*/
|
*/
|
||||||
public static void mapPattern(HexPattern pattern, ResourceLocation id, Action action,
|
public static void mapPattern(HexPattern pattern, ResourceLocation id, Action action,
|
||||||
boolean isPerWorld) throws RegisterPatternException {
|
boolean isPerWorld) throws RegisterPatternException {
|
||||||
if (actionLookup.containsKey(id)) {
|
if (actionLookup.containsKey(id)) {
|
||||||
throw new RegisterPatternException("The operator with id `%s` was already registered to: %s", id,
|
throw new RegisterPatternException("The operator with id `%s` was already registered to: %s", id,
|
||||||
actionLookup.get(id));
|
actionLookup.get(id));
|
||||||
|
@ -83,7 +83,7 @@ public class PatternRegistry {
|
||||||
* Internal use only.
|
* Internal use only.
|
||||||
*/
|
*/
|
||||||
public static Pair<Action, ResourceLocation> matchPatternAndID(HexPattern pat,
|
public static Pair<Action, ResourceLocation> matchPatternAndID(HexPattern pat,
|
||||||
ServerLevel overworld) throws MishapInvalidPattern {
|
ServerLevel overworld) throws MishapInvalidPattern {
|
||||||
// Pipeline:
|
// Pipeline:
|
||||||
// patterns are registered here every time the game boots
|
// patterns are registered here every time the game boots
|
||||||
// when we try to look
|
// when we try to look
|
||||||
|
@ -143,7 +143,8 @@ public class PatternRegistry {
|
||||||
return actionLookup.get(it.opId);
|
return actionLookup.get(it.opId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently, there's no way to look up the name of a Great Spell, as the client is unaware of the correct mapping.
|
// Currently, there's no way to look up the name of a Great Spell, as the client is unaware of the correct
|
||||||
|
// mapping.
|
||||||
// TODO: add code to match any pattern in the shape of a Great Spell to its operator.
|
// TODO: add code to match any pattern in the shape of a Great Spell to its operator.
|
||||||
|
|
||||||
// var ds = overworld.getDataStorage();
|
// var ds = overworld.getDataStorage();
|
||||||
|
@ -160,6 +161,8 @@ public class PatternRegistry {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal use only.
|
* Internal use only.
|
||||||
|
* <p>
|
||||||
|
* Map of signatures to (op id, canonical start dir)
|
||||||
*/
|
*/
|
||||||
public static Map<String, Pair<ResourceLocation, HexDir>> getPerWorldPatterns(ServerLevel overworld) {
|
public static Map<String, Pair<ResourceLocation, HexDir>> getPerWorldPatterns(ServerLevel overworld) {
|
||||||
var ds = overworld.getDataStorage();
|
var ds = overworld.getDataStorage();
|
||||||
|
@ -301,7 +304,8 @@ public class PatternRegistry {
|
||||||
return new Save(map, missingEntries);
|
return new Save(map, missingEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void scrungle(Map<String, Pair<ResourceLocation, HexDir>> lookup, HexPattern prototype, ResourceLocation opId, long seed) {
|
private static void scrungle(Map<String, Pair<ResourceLocation, HexDir>> lookup, HexPattern prototype,
|
||||||
|
ResourceLocation opId, long seed) {
|
||||||
var scrungled = EulerPathFinder.findAltDrawing(prototype, seed, it -> {
|
var scrungled = EulerPathFinder.findAltDrawing(prototype, seed, it -> {
|
||||||
var sig = it.anglesSignature();
|
var sig = it.anglesSignature();
|
||||||
return !lookup.containsKey(sig) &&
|
return !lookup.containsKey(sig) &&
|
||||||
|
|
|
@ -47,7 +47,7 @@ object OpBlink : SpellAction {
|
||||||
private data class Spell(val target: Entity, val delta: Double) : RenderedSpell {
|
private data class Spell(val target: Entity, val delta: Double) : RenderedSpell {
|
||||||
override fun cast(ctx: CastingContext) {
|
override fun cast(ctx: CastingContext) {
|
||||||
val delta = target.lookAngle.scale(delta)
|
val delta = target.lookAngle.scale(delta)
|
||||||
OpTeleport.teleportRespectSticky(target, delta)
|
OpTeleport.teleportRespectSticky(target, delta, ctx.world)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,13 @@ import at.petrak.hexcasting.api.spell.mishaps.MishapLocationTooFarAway
|
||||||
import at.petrak.hexcasting.common.lib.HexEntityTags
|
import at.petrak.hexcasting.common.lib.HexEntityTags
|
||||||
import at.petrak.hexcasting.common.network.MsgBlinkAck
|
import at.petrak.hexcasting.common.network.MsgBlinkAck
|
||||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraft.server.level.TicketType
|
||||||
import net.minecraft.world.entity.Entity
|
import net.minecraft.world.entity.Entity
|
||||||
import net.minecraft.world.item.enchantment.EnchantmentHelper
|
import net.minecraft.world.item.enchantment.EnchantmentHelper
|
||||||
|
import net.minecraft.world.level.ChunkPos
|
||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
|
|
||||||
// TODO while we're making breaking changes I *really* want to have the vector in the entity's local space
|
// TODO while we're making breaking changes I *really* want to have the vector in the entity's local space
|
||||||
|
@ -51,7 +55,7 @@ object OpTeleport : SpellAction {
|
||||||
|
|
||||||
// TODO make this not a magic number (config?)
|
// TODO make this not a magic number (config?)
|
||||||
if (distance < 32768.0) {
|
if (distance < 32768.0) {
|
||||||
teleportRespectSticky(teleportee, delta)
|
teleportRespectSticky(teleportee, delta, ctx.world)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (teleportee is ServerPlayer && teleportee == ctx.caster) {
|
if (teleportee is ServerPlayer && teleportee == ctx.caster) {
|
||||||
|
@ -87,8 +91,9 @@ object OpTeleport : SpellAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun teleportRespectSticky(teleportee: Entity, delta: Vec3) {
|
fun teleportRespectSticky(teleportee: Entity, delta: Vec3, world: ServerLevel) {
|
||||||
val base = teleportee.rootVehicle
|
val base = teleportee.rootVehicle
|
||||||
|
val target = base.position().add(delta)
|
||||||
|
|
||||||
val playersToUpdate = mutableListOf<ServerPlayer>()
|
val playersToUpdate = mutableListOf<ServerPlayer>()
|
||||||
val indirect = base.indirectPassengers
|
val indirect = base.indirectPassengers
|
||||||
|
@ -100,7 +105,6 @@ object OpTeleport : SpellAction {
|
||||||
|
|
||||||
if (sticky) {
|
if (sticky) {
|
||||||
// this handles teleporting the passengers
|
// this handles teleporting the passengers
|
||||||
val target = base.position().add(delta)
|
|
||||||
base.teleportTo(target.x, target.y, target.z)
|
base.teleportTo(target.x, target.y, target.z)
|
||||||
indirect
|
indirect
|
||||||
.filterIsInstance<ServerPlayer>()
|
.filterIsInstance<ServerPlayer>()
|
||||||
|
@ -109,14 +113,21 @@ object OpTeleport : SpellAction {
|
||||||
// Break it into two stacks
|
// Break it into two stacks
|
||||||
teleportee.stopRiding()
|
teleportee.stopRiding()
|
||||||
teleportee.passengers.forEach(Entity::stopRiding)
|
teleportee.passengers.forEach(Entity::stopRiding)
|
||||||
teleportee.setPos(teleportee.position().add(delta))
|
|
||||||
if (teleportee is ServerPlayer) {
|
if (teleportee is ServerPlayer) {
|
||||||
playersToUpdate.add(teleportee)
|
playersToUpdate.add(teleportee)
|
||||||
|
} else {
|
||||||
|
teleportee.setPos(teleportee.position().add(delta))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (player in playersToUpdate) {
|
for (player in playersToUpdate) {
|
||||||
|
// See TeleportCommand
|
||||||
|
val chunkPos = ChunkPos(BlockPos(delta))
|
||||||
|
// the `1` is apparently for "distance." i'm not sure what it does but this is what
|
||||||
|
// /tp does
|
||||||
|
world.chunkSource.addRegionTicket(TicketType.POST_TELEPORT, chunkPos, 1, player.id)
|
||||||
player.connection.resetPosition()
|
player.connection.resetPosition()
|
||||||
|
player.setPos(target)
|
||||||
IXplatAbstractions.INSTANCE.sendPacketToPlayer(player, MsgBlinkAck(delta))
|
IXplatAbstractions.INSTANCE.sendPacketToPlayer(player, MsgBlinkAck(delta))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,32 +22,33 @@ import java.util.List;
|
||||||
public class ListPatternsCommand {
|
public class ListPatternsCommand {
|
||||||
public static void add(LiteralArgumentBuilder<CommandSourceStack> cmd) {
|
public static void add(LiteralArgumentBuilder<CommandSourceStack> cmd) {
|
||||||
cmd.then(Commands.literal("patterns")
|
cmd.then(Commands.literal("patterns")
|
||||||
.requires(dp -> dp.hasPermission(Commands.LEVEL_GAMEMASTERS))
|
.requires(dp -> dp.hasPermission(Commands.LEVEL_GAMEMASTERS))
|
||||||
.then(Commands.literal("list")
|
.then(Commands.literal("list")
|
||||||
.executes(ctx -> list(ctx.getSource())))
|
.executes(ctx -> list(ctx.getSource())))
|
||||||
.then(Commands.literal("give")
|
.then(Commands.literal("give")
|
||||||
.then(Commands.argument("patternName", PatternResLocArgument.id())
|
.then(Commands.argument("patternName", PatternResLocArgument.id())
|
||||||
.executes(ctx ->
|
|
||||||
giveOne(ctx.getSource(),
|
|
||||||
getDefaultTarget(ctx.getSource()),
|
|
||||||
ResourceLocationArgument.getId(ctx, "patternName"),
|
|
||||||
PatternResLocArgument.getPattern(ctx, "patternName")))
|
|
||||||
.then(Commands.argument("targets", EntityArgument.players())
|
|
||||||
.executes(ctx ->
|
|
||||||
giveOne(ctx.getSource(),
|
|
||||||
EntityArgument.getPlayers(ctx, "targets"),
|
|
||||||
ResourceLocationArgument.getId(ctx, "patternName"),
|
|
||||||
PatternResLocArgument.getPattern(ctx, "patternName"))))))
|
|
||||||
.then(Commands.literal("giveAll")
|
|
||||||
.executes(ctx ->
|
.executes(ctx ->
|
||||||
giveAll(ctx.getSource(),
|
giveOne(ctx.getSource(),
|
||||||
getDefaultTarget(ctx.getSource())))
|
getDefaultTarget(ctx.getSource()),
|
||||||
|
ResourceLocationArgument.getId(ctx, "patternName"),
|
||||||
|
PatternResLocArgument.getPattern(ctx, "patternName")))
|
||||||
.then(Commands.argument("targets", EntityArgument.players())
|
.then(Commands.argument("targets", EntityArgument.players())
|
||||||
.executes(ctx ->
|
.executes(ctx ->
|
||||||
giveAll(ctx.getSource(),
|
giveOne(ctx.getSource(),
|
||||||
EntityArgument.getPlayers(ctx, "targets")))))
|
EntityArgument.getPlayers(ctx, "targets"),
|
||||||
);
|
ResourceLocationArgument.getId(ctx, "patternName"),
|
||||||
|
PatternResLocArgument.getPattern(ctx, "patternName"))))))
|
||||||
|
.then(Commands.literal("giveAll")
|
||||||
|
.executes(ctx ->
|
||||||
|
giveAll(ctx.getSource(),
|
||||||
|
getDefaultTarget(ctx.getSource())))
|
||||||
|
.then(Commands.argument("targets", EntityArgument.players())
|
||||||
|
.executes(ctx ->
|
||||||
|
giveAll(ctx.getSource(),
|
||||||
|
EntityArgument.getPlayers(ctx, "targets")))))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Collection<ServerPlayer> getDefaultTarget(CommandSourceStack source) {
|
private static Collection<ServerPlayer> getDefaultTarget(CommandSourceStack source) {
|
||||||
if (source.getEntity() instanceof ServerPlayer player) {
|
if (source.getEntity() instanceof ServerPlayer player) {
|
||||||
return List.of(player);
|
return List.of(player);
|
||||||
|
@ -78,14 +79,14 @@ public class ListPatternsCommand {
|
||||||
if (!targets.isEmpty()) {
|
if (!targets.isEmpty()) {
|
||||||
var lookup = PatternRegistry.getPerWorldPatterns(source.getLevel());
|
var lookup = PatternRegistry.getPerWorldPatterns(source.getLevel());
|
||||||
|
|
||||||
lookup.forEach((pattern, entry) -> {
|
lookup.forEach((sig, entry) -> {
|
||||||
var opId = entry.getFirst();
|
var opId = entry.getFirst();
|
||||||
var startDir = entry.getSecond();
|
var startDir = entry.getSecond();
|
||||||
|
|
||||||
var tag = new CompoundTag();
|
var tag = new CompoundTag();
|
||||||
tag.putString(ItemScroll.TAG_OP_ID, opId.toString());
|
tag.putString(ItemScroll.TAG_OP_ID, opId.toString());
|
||||||
tag.put(ItemScroll.TAG_PATTERN,
|
tag.put(ItemScroll.TAG_PATTERN,
|
||||||
HexPattern.fromAngles(pattern, startDir).serializeToNBT());
|
HexPattern.fromAngles(sig, startDir).serializeToNBT());
|
||||||
|
|
||||||
var stack = new ItemStack(HexItems.SCROLL_LARGE);
|
var stack = new ItemStack(HexItems.SCROLL_LARGE);
|
||||||
stack.setTag(tag);
|
stack.setTag(tag);
|
||||||
|
@ -110,12 +111,12 @@ public class ListPatternsCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int giveOne(CommandSourceStack source, Collection<ServerPlayer> targets, ResourceLocation patternName, HexPattern pat) {
|
private static int giveOne(CommandSourceStack source, Collection<ServerPlayer> targets,
|
||||||
|
ResourceLocation patternName, HexPattern pat) {
|
||||||
if (!targets.isEmpty()) {
|
if (!targets.isEmpty()) {
|
||||||
var tag = new CompoundTag();
|
var tag = new CompoundTag();
|
||||||
tag.putString(ItemScroll.TAG_OP_ID, patternName.toString());
|
tag.putString(ItemScroll.TAG_OP_ID, patternName.toString());
|
||||||
tag.put(ItemScroll.TAG_PATTERN,
|
tag.put(ItemScroll.TAG_PATTERN, pat.serializeToNBT());
|
||||||
pat.serializeToNBT());
|
|
||||||
|
|
||||||
var stack = new ItemStack(HexItems.SCROLL_LARGE);
|
var stack = new ItemStack(HexItems.SCROLL_LARGE);
|
||||||
stack.setTag(tag);
|
stack.setTag(tag);
|
||||||
|
|
|
@ -36,10 +36,10 @@ public class PatternResLocArgument extends ResourceLocationArgument {
|
||||||
var targetId = ctx.getArgument(pName, ResourceLocation.class);
|
var targetId = ctx.getArgument(pName, ResourceLocation.class);
|
||||||
var lookup = PatternRegistry.getPerWorldPatterns(ctx.getSource().getLevel());
|
var lookup = PatternRegistry.getPerWorldPatterns(ctx.getSource().getLevel());
|
||||||
HexPattern foundPat = null;
|
HexPattern foundPat = null;
|
||||||
for (var key : lookup.keySet()) {
|
for (var sig : lookup.keySet()) {
|
||||||
var rhs = lookup.get(key);
|
var rhs = lookup.get(sig);
|
||||||
if (rhs.getFirst().equals(targetId)) {
|
if (rhs.getFirst().equals(targetId)) {
|
||||||
foundPat = HexPattern.fromAngles(key, rhs.getSecond());
|
foundPat = HexPattern.fromAngles(sig, rhs.getSecond());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue