diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/CameraAnimationSet.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/CameraAnimationSet.java index 784b53d..52ec108 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/CameraAnimationSet.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/CameraAnimationSet.java @@ -3,42 +3,24 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class CameraAnimationSet { - public CameraAnimationSet( - @NotNull CameraAnimation authentic, - @Nullable CameraAnimation gentle, - @Nullable CameraAnimation minimal +public record CameraAnimationSet( + @NotNull CameraAnimation authentic, + @Nullable CameraAnimation gentle, + @Nullable CameraAnimation minimal +) { + public record CameraAnimation( + boolean looping, + float durationSeconds, + CameraAnimation.rotationalOffsetCalculator calculator ) { - this.AUTHENTIC_ANIMATION = authentic; - this.GENTLE_ANIMATION = gentle == null ? authentic : gentle; - this.MINIMAL_ANIMATION = minimal; - } - - public static class CameraAnimation { @FunctionalInterface public interface rotationalOffsetCalculator { - void setRotationalOffsets(float progress, float[] offsets); + void setRotationalOffsets(float progress, CameraOffsets offsets); } - public CameraAnimation( - boolean looping, - float durationSeconds, - CameraAnimation.rotationalOffsetCalculator calculator - ) { - this.SHOULD_LOOP = looping; - this.DURATION_TICKS = durationSeconds * 20; - this.CALCULATOR = calculator; + public static class CameraOffsets { + public float pitch, yaw, roll; + public float x, y, z; } - - public final boolean SHOULD_LOOP; - public final float DURATION_TICKS; - public final CameraAnimation.rotationalOffsetCalculator CALCULATOR; } - - @NotNull - public final CameraAnimation AUTHENTIC_ANIMATION; - @NotNull - public final CameraAnimation GENTLE_ANIMATION; - @Nullable - public final CameraAnimation MINIMAL_ANIMATION; } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorContext.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorEnvironment.java similarity index 73% rename from api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorContext.java rename to api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorEnvironment.java index 6ccf1b6..711f032 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorContext.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorEnvironment.java @@ -1,6 +1,6 @@ package com.fqf.mario_qua_mario.definitions.actions.util; -public enum EvaluatorContext { +public enum EvaluatorEnvironment { CLIENT_ONLY, SERVER_ONLY, COMMON diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java index 089a5c7..de22007 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java @@ -15,14 +15,14 @@ */ public record TransitionDefinition( @NotNull Identifier targetID, - @NotNull Evaluator evaluator, @NotNull EvaluatorContext context, + @NotNull Evaluator evaluator, @NotNull EvaluatorEnvironment environment, @Nullable TravelExecutor travelExecutor, @Nullable ClientsExecutor clientsExecutor ) { /** * Alternate constructor provided for convenience */ - public TransitionDefinition(@NotNull Identifier targetID, @NotNull Evaluator evaluator, @NotNull EvaluatorContext context) { + public TransitionDefinition(@NotNull Identifier targetID, @NotNull Evaluator evaluator, @NotNull EvaluatorEnvironment context) { this(targetID, evaluator, context, null, null); } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioAuthoritativeData.java b/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioAuthoritativeData.java index fba0106..6d1aaec 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioAuthoritativeData.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioAuthoritativeData.java @@ -7,17 +7,17 @@ public interface IMarioAuthoritativeData extends IMarioData { @Override ServerPlayerEntity getMario(); - boolean setEnabled(boolean enable); + void setEnabled(boolean enable); boolean setAction(Identifier actionID); boolean setAction(String actionID); - boolean setActionTransitionless(Identifier actionID); - boolean setActionTransitionless(String actionID); + void setActionTransitionless(Identifier actionID); + void setActionTransitionless(String actionID); - boolean setPowerUp(Identifier powerUpID); - boolean setPowerUp(String powerUpID); + void setPowerUp(Identifier powerUpID); + void setPowerUp(String powerUpID); - boolean setCharacter(Identifier characterID); - boolean setCharacter(String characterID); + void setCharacter(Identifier characterID); + void setCharacter(String characterID); } diff --git a/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java index 683d425..7bb8d73 100644 --- a/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java @@ -60,7 +60,7 @@ public class Debug implements GenericActionDefinition { return List.of( new TransitionDefinition( MarioQuaMarioContent.makeID("debug_sprint"), - data -> data.getMario().isSprinting(), EvaluatorContext.CLIENT_ONLY, + data -> data.getMario().isSprinting(), EvaluatorEnvironment.CLIENT_ONLY, null, (data, isSelf, seed) -> data.playSound(SoundEvents.ENTITY_VEX_CHARGE, seed) ) diff --git a/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java index 59c1bad..aa65cef 100644 --- a/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java @@ -26,7 +26,7 @@ public class DebugSprint extends Debug { return List.of( new TransitionDefinition( MarioQuaMarioContent.makeID("debug"), - data -> !data.getMario().isSprinting(), EvaluatorContext.CLIENT_ONLY, + data -> !data.getMario().isSprinting(), EvaluatorEnvironment.CLIENT_ONLY, null, (data, isSelf, seed) -> data.playSound(SoundEvents.ENTITY_ALLAY_AMBIENT_WITH_ITEM, seed) ) diff --git a/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java b/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java index 88598e9..0efb9fc 100644 --- a/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java @@ -1,14 +1,11 @@ package com.fqf.mario_qua_mario.actions.grounded; import com.fqf.mario_qua_mario.MarioQuaMarioContent; -import com.fqf.mario_qua_mario.definitions.actions.AirborneActionDefinition; -import com.fqf.mario_qua_mario.definitions.actions.GenericActionDefinition; import com.fqf.mario_qua_mario.definitions.actions.GroundedActionDefinition; import com.fqf.mario_qua_mario.definitions.actions.util.*; import com.fqf.mario_qua_mario.mariodata.IMarioAuthoritativeData; import com.fqf.mario_qua_mario.mariodata.IMarioClientData; import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; -import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java b/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java index 8614914..6fb1dc7 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java @@ -2,6 +2,10 @@ import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.network.OtherClientPlayerEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerEntity; public class MarioQuaMarioClient implements ClientModInitializer { // This is in the client sources diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java index e4a8dd2..6caf311 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java @@ -7,19 +7,10 @@ import org.jetbrains.annotations.Nullable; public class MarioMainClientData extends MarioMoveableData implements IMarioClientDataImpl { - private static MarioMainClientData instance; - public static @Nullable MarioMainClientData getInstance() { - return instance; - } - public static void clearInstance() { - instance = null; - } - private ClientPlayerEntity mario; public MarioMainClientData(ClientPlayerEntity mario) { super(); this.mario = mario; - instance = this; } @Override public ClientPlayerEntity getMario() { return mario; @@ -36,9 +27,14 @@ public void tick() { @Override public boolean travelHook(double forwardInput, double strafeInput) { this.INPUTS.updateAnalog(forwardInput, strafeInput); + this.getAction().travelHook(this); + + this.applyModifiedVelocity(); this.getMario().move(MovementType.SELF, this.getMario().getVelocity()); + + this.getMario().updateLimbs(false); return true; } diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java index ef6142e..03ab6ee 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java @@ -4,5 +4,8 @@ import org.jetbrains.annotations.NotNull; public interface MarioMainClientDataHolder extends MarioDataHolder { - @Override @NotNull MarioMainClientData mqm$getMarioData(); + @SuppressWarnings("DataFlowIssue") @Override + default @NotNull MarioMainClientData mqm$getMarioData() { + return null; + } } diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java index 7c5ef3e..134ab62 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java @@ -4,5 +4,8 @@ import org.jetbrains.annotations.NotNull; public interface MarioOtherClientDataHolder extends MarioDataHolder { - @Override @NotNull MarioOtherClientData mqm$getMarioData(); + @SuppressWarnings("DataFlowIssue") @Override + default @NotNull MarioOtherClientData mqm$getMarioData() { + return null; + } } diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMarioDataMixin.java b/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMarioDataMixin.java index 8fbc66b..87e1098 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMarioDataMixin.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMarioDataMixin.java @@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ClientPlayerEntity.class) -public class ClientPlayerEntityMarioDataMixin extends PlayerEntityMarioDataMixin implements MarioMainClientDataHolder { +public class ClientPlayerEntityMarioDataMixin implements MarioMainClientDataHolder { @Unique private MarioMainClientData marioData; @Inject(method = "", at = @At("RETURN")) @@ -34,5 +34,6 @@ private void constructorHook(MinecraftClient client, ClientWorld world, ClientPl @Override public void mqm$setMarioData(MarioPlayerData replacementData) { this.marioData = (MarioMainClientData) replacementData; + replacementData.setMario((ClientPlayerEntity) (Object) this); } } diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/OtherClientPlayerEntityMarioDataMixin.java b/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/OtherClientPlayerEntityMarioDataMixin.java index 4107dd1..bbee18d 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/OtherClientPlayerEntityMarioDataMixin.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/OtherClientPlayerEntityMarioDataMixin.java @@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(OtherClientPlayerEntity.class) -public class OtherClientPlayerEntityMarioDataMixin extends PlayerEntityMarioDataMixin implements MarioOtherClientDataHolder { +public class OtherClientPlayerEntityMarioDataMixin implements MarioOtherClientDataHolder { @Unique private MarioOtherClientData marioData; @Inject(method = "", at = @At("RETURN")) @@ -31,5 +31,6 @@ private void constructorHook(ClientWorld clientWorld, GameProfile gameProfile, C @Override public void mqm$setMarioData(MarioPlayerData replacementData) { this.marioData = (MarioOtherClientData) replacementData; + replacementData.setMario((OtherClientPlayerEntity) (Object) this); } } diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/packets/MarioClientPacketReceivers.java b/mod/src/client/java/com/fqf/mario_qua_mario/packets/MarioClientPacketReceivers.java new file mode 100644 index 0000000..78b1bd9 --- /dev/null +++ b/mod/src/client/java/com/fqf/mario_qua_mario/packets/MarioClientPacketReceivers.java @@ -0,0 +1,25 @@ +package com.fqf.mario_qua_mario.packets; + +import com.fqf.mario_qua_mario.mariodata.MarioPlayerData; +import com.fqf.mario_qua_mario.registries.RegistryManager; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.minecraft.entity.player.PlayerEntity; + +import java.util.Objects; + +public class MarioClientPacketReceivers { + public static void registerClientReceivers() { + // SetActionS2CPayload Receiver + ClientPlayNetworking.registerGlobalReceiver(MarioDataPackets.SetActionS2CPayload.ID, (payload, context) -> { + MarioPlayerData data = getMarioFromID(context, payload.marioID()).mqm$getMarioData(); + AbstractParsedAction action = RegistryManager.ACTIONS.get(payload.newAction()); + if(payload.doTransition()) data.setActionInternal(action, payload.seed(), true); + else data.setActionTransitionlessInternal(action); + }); + } + + public static PlayerEntity getMarioFromID(ClientPlayNetworking.Context context, int marioID) { + return (PlayerEntity) Objects.requireNonNull(context.player().getWorld().getEntityById(marioID)); + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java b/mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java index 56f30a4..7ab67e3 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java @@ -1,6 +1,5 @@ package com.fqf.mario_qua_mario; public abstract class MarioAbstractClientHelper { - public static MarioAbstractClientHelper instance = new MarioAbstractClientHelper() { - }; + public static MarioAbstractClientHelper instance = null; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java b/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java index 87425ff..706e8a5 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java @@ -1,6 +1,9 @@ package com.fqf.mario_qua_mario; +import com.fqf.mario_qua_mario.mariodata.MarioServerPlayerData; +import com.fqf.mario_qua_mario.packets.MarioDataPackets; import com.fqf.mario_qua_mario.registries.RegistryManager; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; import com.mojang.brigadier.arguments.BoolArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; @@ -10,6 +13,7 @@ import net.minecraft.command.argument.BlockPosArgumentType; import net.minecraft.command.argument.EntityArgumentType; import net.minecraft.command.argument.RegistryEntryReferenceArgumentType; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; @@ -102,60 +106,66 @@ private static ServerPlayerEntity getPlayerFromCmd(CommandContext context, boolean playerArgumentGiven) throws CommandSyntaxException { -// return sendFeedback(context, MarioDataPackets.setMarioEnabled( -// getPlayerFromCmd(context, playerArgumentGiven), -// BoolArgumentType.getBool(context, "enabled") +// return sendFeedback(environment, MarioDataPackets.setMarioEnabled( +// getPlayerFromCmd(environment, playerArgumentGiven), +// BoolArgumentType.getBool(environment, "enabled") // )); return 0; } private static int setAction(CommandContext context, boolean playerArgumentGiven) throws CommandSyntaxException { -// return sendFeedback(context, MarioDataPackets.forceSetMarioAction( -// getPlayerFromCmd(context, playerArgumentGiven), -// RegistryEntryReferenceArgumentType.getRegistryEntry(context, "action", RegistryManager.ACTIONS_KEY).value() +// return sendFeedback(environment, MarioDataPackets.forceSetMarioAction( +// getPlayerFromCmd(environment, playerArgumentGiven), +// RegistryEntryReferenceArgumentType.getRegistryEntry(environment, "action", RegistryManager.ACTIONS_KEY).value() // )); - return 0; + ServerPlayerEntity mario = getPlayerFromCmd(context, playerArgumentGiven); + RegistryEntry actionEntry = + RegistryEntryReferenceArgumentType.getRegistryEntry(context, "action", RegistryManager.ACTIONS_KEY); + mario.mqm$getMarioData().setActionTransitionlessInternal(actionEntry.value()); + MarioDataPackets.setActionS2C(mario, true, actionEntry.value(), false, 0); + + return sendFeedback(context, "Changed " + mario.getName().getString() + "'s action to " + actionEntry.value().ID + "."); } private static int setPowerUp(CommandContext context, boolean playerArgumentGiven) throws CommandSyntaxException { -// return sendFeedback(context, MarioDataPackets.setMarioPowerUp( -// getPlayerFromCmd(context, playerArgumentGiven), -// RegistryEntryReferenceArgumentType.getRegistryEntry(context, "power", RegistryManager.POWER_UPS_KEY).value() +// return sendFeedback(environment, MarioDataPackets.setMarioPowerUp( +// getPlayerFromCmd(environment, playerArgumentGiven), +// RegistryEntryReferenceArgumentType.getRegistryEntry(environment, "power", RegistryManager.POWER_UPS_KEY).value() // )); return 0; } private static int setCharacter(CommandContext context, boolean playerArgumentGiven) throws CommandSyntaxException { -// return sendFeedback(context, MarioDataPackets.setMarioCharacter( -// getPlayerFromCmd(context, playerArgumentGiven), -// RegistryEntryReferenceArgumentType.getRegistryEntry(context, "character", RegistryManager.CHARACTERS_KEY).value() +// return sendFeedback(environment, MarioDataPackets.setMarioCharacter( +// getPlayerFromCmd(environment, playerArgumentGiven), +// RegistryEntryReferenceArgumentType.getRegistryEntry(environment, "character", RegistryManager.CHARACTERS_KEY).value() // )); return 0; } private static int executeStomp(CommandContext context, boolean playerArgumentGiven) throws CommandSyntaxException { -// ServerPlayerEntity stomper = getPlayerFromCmd(context, playerArgumentGiven); -// Entity target = EntityArgumentType.getEntity(context, "goomba"); -// ParsedStomp stompType = RegistryEntryReferenceArgumentType.getRegistryEntry(context, "stomp", RegistryManager.STOMP_TYPES_KEY).value(); +// ServerPlayerEntity stomper = getPlayerFromCmd(environment, playerArgumentGiven); +// Entity target = EntityArgumentType.getEntity(environment, "goomba"); +// ParsedStomp stompType = RegistryEntryReferenceArgumentType.getRegistryEntry(environment, "stomp", RegistryManager.STOMP_TYPES_KEY).value(); // // stomper.teleport((ServerWorld) target.getWorld(), target.getX(), target.getY() + target.getHeight(), target.getZ(), target.getPitch(), target.getYaw()); // stompType.executeServer((MarioServerData) MarioDataManager.getMarioData(stomper), target, true, RandomSeed.getSeed()); // -// return sendFeedback(context, "Made " + stomper.getName().getString() + " perform a stomp of type " + stompType.ID + " on " + target.getName().getString()); +// return sendFeedback(environment, "Made " + stomper.getName().getString() + " perform a stomp of type " + stompType.ID + " on " + target.getName().getString()); return 0; } private static int executeBump(CommandContext context, boolean playerArgumentGiven, Direction direction, Integer strength) throws CommandSyntaxException { -// ServerPlayerEntity bumper = getPlayerFromCmd(context, playerArgumentGiven); -// if(strength == null) strength = IntegerArgumentType.getInteger(context, "strength"); -// BlockPos position = BlockPosArgumentType.getBlockPos(context, "position"); +// ServerPlayerEntity bumper = getPlayerFromCmd(environment, playerArgumentGiven); +// if(strength == null) strength = IntegerArgumentType.getInteger(environment, "strength"); +// BlockPos position = BlockPosArgumentType.getBlockPos(environment, "position"); // // MarioServerData data = (MarioServerData) MarioDataManager.getMarioData(bumper); //// BumpManager.bumpBlockServer(data, bumper.getServerWorld(), position, strength, strength, direction, true, true); //// BumpManager.bumpResponseCommon(data, data, bumper.getServerWorld(), bumper.getServerWorld().getBlockState(position), position, strength, strength, direction); // -// return sendFeedback(context, "Made " + bumper.getName().getString() + " bump block " + direction + " with a strength " + strength); +// return sendFeedback(environment, "Made " + bumper.getName().getString() + " bump block " + direction + " with a strength " + strength); return 0; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java b/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java index ee96b33..4eb9204 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java @@ -3,6 +3,8 @@ import com.fqf.mario_qua_mario.registries.RegistryManager; import net.fabricmc.api.ModInitializer; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java index 655961b..bd5ed14 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java @@ -3,6 +3,7 @@ import com.fqf.mario_qua_mario.MarioQuaMario; import com.fqf.mario_qua_mario.registries.RegistryManager; import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import com.fqf.mario_qua_mario.registries.actions.ParsedActionHelper; import com.fqf.mario_qua_mario.util.CharaStat; import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.player.PlayerEntity; @@ -16,7 +17,7 @@ protected MarioPlayerData() { this.enabled = false; this.setEnabledInternal(true); this.action = null; - this.setActionInternal(RegistryManager.ACTIONS.get(MarioQuaMario.makeID("debug"))); + this.setActionTransitionlessInternal(RegistryManager.ACTIONS.get(MarioQuaMario.makeID("debug"))); // this.powerUp = null; // this.character = null; } @@ -45,7 +46,13 @@ public void setEnabledInternal(boolean enabled) { public AbstractParsedAction getAction() { return this.action; } - public void setActionInternal(AbstractParsedAction action) { + + public boolean setActionInternal(AbstractParsedAction action, long seed, boolean forced) { + boolean transitionedNaturally = ParsedActionHelper.attemptTransitionTo(this, action, seed); + if(!transitionedNaturally && forced) this.setActionTransitionlessInternal(action); + return transitionedNaturally || forced; + } + public void setActionTransitionlessInternal(AbstractParsedAction action) { this.action = action; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java index 7744776..6cc77d3 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java @@ -1,5 +1,6 @@ package com.fqf.mario_qua_mario.mariodata; +import com.fqf.mario_qua_mario.MarioQuaMario; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; @@ -14,8 +15,8 @@ public MarioServerPlayerData(ServerPlayerEntity mario) { return this.mario; } - @Override public boolean setEnabled(boolean enable) { - return false; + @Override public void setEnabled(boolean enable) { + } @Override public boolean setAction(Identifier actionID) { @@ -26,28 +27,28 @@ public MarioServerPlayerData(ServerPlayerEntity mario) { return false; } - @Override public boolean setActionTransitionless(Identifier actionID) { - return false; + @Override public void setActionTransitionless(Identifier actionID) { + } - @Override public boolean setActionTransitionless(String actionID) { - return false; + @Override public void setActionTransitionless(String actionID) { + } - @Override public boolean setPowerUp(Identifier powerUpID) { - return false; + @Override public void setPowerUp(Identifier powerUpID) { + } - @Override public boolean setPowerUp(String powerUpID) { - return false; + @Override public void setPowerUp(String powerUpID) { + } - @Override public boolean setCharacter(Identifier characterID) { - return false; + @Override public void setCharacter(Identifier characterID) { + } - @Override public boolean setCharacter(String characterID) { - return false; + @Override public void setCharacter(String characterID) { + } @Override public void setMario(PlayerEntity mario) { @@ -66,6 +67,10 @@ public void tick() { @Override public boolean travelHook(double forwardInput, double strafeInput) { +// ServerPlayerEntity mario = this.getMario(); +// mario.mqm$getMarioData(); + + return false; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java index 783dd6b..2e1a383 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java @@ -4,6 +4,11 @@ import org.jetbrains.annotations.NotNull; public interface MarioDataHolder { - @NotNull MarioPlayerData mqm$getMarioData(); - void mqm$setMarioData(MarioPlayerData replacementData); + @SuppressWarnings("DataFlowIssue") + default @NotNull MarioPlayerData mqm$getMarioData() { + return null; + }; + default void mqm$setMarioData(MarioPlayerData replacementData) { + + }; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java index 2601fba..8189647 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java @@ -4,6 +4,8 @@ import org.jetbrains.annotations.NotNull; public interface MarioServerDataHolder extends MarioDataHolder { - @Override - @NotNull MarioServerPlayerData mqm$getMarioData(); + @SuppressWarnings("DataFlowIssue") @Override + default @NotNull MarioServerPlayerData mqm$getMarioData() { + return null; + }; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMarioDataMixin.java b/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMarioDataMixin.java index afc2e40..48a004b 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMarioDataMixin.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMarioDataMixin.java @@ -1,25 +1,9 @@ package com.fqf.mario_qua_mario.mixin; -import com.fqf.mario_qua_mario.MarioQuaMario; import com.fqf.mario_qua_mario.mariodata.injections.MarioDataHolder; -import com.fqf.mario_qua_mario.mariodata.MarioPlayerData; -import com.mojang.authlib.GameProfile; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(PlayerEntity.class) public abstract class PlayerEntityMarioDataMixin implements MarioDataHolder { - @Inject(method = "", at = @At("RETURN")) - private void constructorHook(World world, BlockPos pos, float yaw, GameProfile gameProfile, CallbackInfo ci) { - MarioQuaMario.LOGGER.info("Initialized a PlayerEntity with MarioData:\n{}\n{}\n{}", (PlayerEntity) (Object) this, this, this.mqm$getMarioData()); - } } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mixin/ServerPlayerMarioDataMixin.java b/mod/src/main/java/com/fqf/mario_qua_mario/mixin/ServerPlayerMarioDataMixin.java index 71bcdb0..16d5cfd 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mixin/ServerPlayerMarioDataMixin.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mixin/ServerPlayerMarioDataMixin.java @@ -4,13 +4,10 @@ import com.fqf.mario_qua_mario.mariodata.MarioServerPlayerData; import com.fqf.mario_qua_mario.mariodata.injections.MarioServerDataHolder; import com.mojang.authlib.GameProfile; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; import net.minecraft.network.packet.c2s.common.SyncedClientOptions; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.World; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; @@ -19,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ServerPlayerEntity.class) -public abstract class ServerPlayerMarioDataMixin extends PlayerEntityMarioDataMixin implements MarioServerDataHolder { +public class ServerPlayerMarioDataMixin implements MarioServerDataHolder { @Unique private MarioServerPlayerData marioServerData; @Inject(method = "", at = @At("RETURN")) @@ -27,11 +24,12 @@ private void constructorHook(MinecraftServer server, ServerWorld world, GameProf this.mqm$setMarioData(new MarioServerPlayerData((ServerPlayerEntity) (Object) this)); } - @Override public void mqm$setMarioData(MarioPlayerData replacementData) { - this.marioServerData = (MarioServerPlayerData) replacementData; - } - @Override public @NotNull MarioServerPlayerData mqm$getMarioData() { return this.marioServerData; } + + @Override public void mqm$setMarioData(MarioPlayerData replacementData) { + this.marioServerData = (MarioServerPlayerData) replacementData; + replacementData.setMario((ServerPlayerEntity) (Object) this); + } } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioDataPackets.java b/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioDataPackets.java new file mode 100644 index 0000000..6d78e0f --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioDataPackets.java @@ -0,0 +1,87 @@ +package com.fqf.mario_qua_mario.packets; + +import com.fqf.mario_qua_mario.MarioQuaMario; +import com.fqf.mario_qua_mario.mariodata.MarioServerPlayerData; +import com.fqf.mario_qua_mario.registries.RegistryManager; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.server.network.ServerPlayerEntity; + +public class MarioDataPackets { + public static void setActionS2C( + ServerPlayerEntity mario, boolean networkToMario, AbstractParsedAction newAction, + boolean doTransition, long seed) + { + ServerPlayNetworking.send(mario, new SetActionS2CPayload( + mario.getId(), RegistryManager.ACTIONS.getRawIdOrThrow(newAction), + doTransition, seed + )); +// MarioPackets.sendToTrackers( +// mario, new SetActionS2CPayload( +// mario.getId(), RegistryManager.ACTIONS.getEntry(newAction), +// doTransition, seed +// ), networkToMario +// ); + } + + protected record SetActionC2SPayload(int newAction, long seed) implements CustomPayload { + public static final Id ID = new Id<>(MarioQuaMario.makeID("set_action_c2s")); + public static final PacketCodec CODEC = PacketCodec.tuple( + PacketCodecs.INTEGER, SetActionC2SPayload::newAction, + PacketCodecs.VAR_LONG, SetActionC2SPayload::seed, + SetActionC2SPayload::new + ); + + public static void receive(SetActionC2SPayload payload, ServerPlayNetworking.Context context) { + AbstractParsedAction action = RegistryManager.ACTIONS.get(payload.newAction()); + if(context.player().mqm$getMarioData().setActionInternal(action, payload.seed, false)) { + MarioPackets.sendToTrackers(context.player(), new SetActionS2CPayload( + context.player().getId(), + payload.newAction, + true, + payload.seed + ), false); + } + else { + ServerPlayNetworking.send(context.player(), new SetActionS2CPayload( + context.player().getId(), + RegistryManager.ACTIONS.getRawIdOrThrow(context.player().mqm$getMarioData().getAction()), + false, + payload.seed + )); + } + } + + @Override public Id getId() { + return ID; + } + public static void register() { + PayloadTypeRegistry.playC2S().register(ID, CODEC); + ServerPlayNetworking.registerGlobalReceiver(ID, SetActionC2SPayload::receive); + } + } + + protected record SetActionS2CPayload(int marioID, int newAction, boolean doTransition, long seed) implements CustomPayload { + public static final Id ID = new Id<>(MarioQuaMario.makeID("set_action_s2c")); + public static final PacketCodec CODEC = PacketCodec.tuple( + PacketCodecs.INTEGER, SetActionS2CPayload::marioID, + PacketCodecs.INTEGER, SetActionS2CPayload::newAction, + PacketCodecs.BOOL, SetActionS2CPayload::doTransition, + PacketCodecs.VAR_LONG, SetActionS2CPayload::seed, + SetActionS2CPayload::new + ); + + @Override public Id getId() { + return ID; + } + public static void register() { + PayloadTypeRegistry.playS2C().register(ID, CODEC); + } + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioPackets.java b/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioPackets.java new file mode 100644 index 0000000..8f527ab --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioPackets.java @@ -0,0 +1,26 @@ +package com.fqf.mario_qua_mario.packets; + +import com.fqf.mario_qua_mario.mariodata.MarioPlayerData; +import com.fqf.mario_qua_mario.mariodata.MarioServerPlayerData; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import net.fabricmc.fabric.api.networking.v1.PlayerLookup; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.server.network.ServerPlayerEntity; + +import java.util.Collection; + +public class MarioPackets { + public static void register() { + MarioDataPackets.SetActionS2CPayload.register(); + + MarioDataPackets.SetActionC2SPayload.register(); + } + + public static void sendToTrackers(ServerPlayerEntity mario, CustomPayload packet, boolean includeMario) { + if(includeMario) ServerPlayNetworking.send(mario, packet); + for(ServerPlayerEntity player : PlayerLookup.tracking(mario)) { + if(!player.equals(mario)) ServerPlayNetworking.send(player, packet); + } + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java index b98e8d2..56e0620 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java @@ -109,8 +109,8 @@ private void addTransitionToLists( MarioQuaMario.LOGGER.warn("Action {} has multiple transitions into {}! This is likely to cause issues!", this.ID, transition.targetAction().ID); else this.TRANSITIONS_FROM_TARGETS.put(transition.targetAction(), transition); - if(definition.context() != EvaluatorContext.CLIENT_ONLY) server.add(transition); - if(definition.context() != EvaluatorContext.SERVER_ONLY) client.add(transition); + if(definition.environment() != EvaluatorEnvironment.CLIENT_ONLY) server.add(transition); + if(definition.environment() != EvaluatorEnvironment.SERVER_ONLY) client.add(transition); } abstract public void travelHook(MarioMoveableData data); diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/InitAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/InitAction.java deleted file mode 100644 index 980cf5c..0000000 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/InitAction.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.fqf.mario_qua_mario.registries.actions; - -import com.fqf.mario_qua_mario.MarioQuaMario; -import com.fqf.mario_qua_mario.definitions.actions.GenericActionDefinition; -import com.fqf.mario_qua_mario.definitions.actions.util.*; -import com.fqf.mario_qua_mario.mariodata.IMarioAuthoritativeData; -import com.fqf.mario_qua_mario.mariodata.IMarioClientData; -import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Set; - -public class InitAction implements GenericActionDefinition { - @Override public @NotNull Identifier getID() { - return MarioQuaMario.makeID("init"); - } - - @Override public @Nullable String getAnimationName() { - return null; - } - @Override public @Nullable CameraAnimationSet getCameraAnimations() { - return null; - } - @Override public @NotNull SlidingStatus getSlidingStatus() { - return SlidingStatus.NOT_SLIDING; - } - - @Override public @NotNull SneakingRule getSneakingRule() { - return SneakingRule.PROHIBIT; - } - @Override public @NotNull SprintingRule getSprintingRule() { - return SprintingRule.PROHIBIT; - } - - @Override public @Nullable BumpType getBumpType() { - return null; - } - @Override public @Nullable Identifier getStompTypeID() { - return null; - } - - @Override public void clientTick(IMarioClientData data, boolean isSelf) { - - } - @Override public void serverTick(IMarioAuthoritativeData data) { - - } - @Override public void travelHook(IMarioTravelData data) { - - } - - @Override public @NotNull List getBasicTransitions() { - return List.of( - new TransitionDefinition( - MarioQuaMario.makeID("init"), - data -> false - ) - ); - } - @Override public @NotNull List getInputTransitions() { - return List.of(); - } - @Override public @NotNull List getWorldCollisionTransitions() { - return List.of(); - } - - @Override public @NotNull Set getTransitionInjections() { - return Set.of(); - } - - @Override public @NotNull List getUnarmedAttackInterceptions() { - return List.of(); - } -} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java index 038ce68..5964d7e 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java @@ -1,5 +1,6 @@ package com.fqf.mario_qua_mario.registries.actions; +import com.fqf.mario_qua_mario.MarioAbstractClientHelper; import com.fqf.mario_qua_mario.MarioQuaMario; import com.fqf.mario_qua_mario.definitions.actions.*; import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; @@ -7,6 +8,7 @@ import com.fqf.mario_qua_mario.mariodata.IMarioClientData; import com.fqf.mario_qua_mario.mariodata.IMarioData; import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.mariodata.MarioPlayerData; import com.fqf.mario_qua_mario.registries.actions.parsed.*; import net.minecraft.util.Identifier; import net.minecraft.util.math.random.RandomSeed; @@ -39,25 +41,36 @@ public static void attemptTransitions(MarioMoveableData data, TransitionPhase ph if(!data.isClient()) { // Send S2C transition packet // If fullyNetworked(), then send the packet to Mario too +// MarioAbstractClientHelper.instance. } else if(transition.fullyNetworked()) { // Send C2S transition packet } + + return; } } } - public static void executeTransition(IMarioData data, ParsedTransition transition, long seed) { - MarioQuaMario.LOGGER.info("Executing transition for {} on {}:\n\t{} -> {}", - data.getMario().getName().getString(), - data.isClient() ? "CLIENT" : "SERVER", - data.getActionID(), - transition.targetAction().ID + public static boolean attemptTransitionTo(MarioPlayerData data, AbstractParsedAction action, long seed) { + ParsedTransition transition = data.getAction().TRANSITIONS_FROM_TARGETS.get(action); + if(transition == null) return false; + + executeTransition(data, transition, seed); + return true; + } + + public static void executeTransition(MarioPlayerData data, ParsedTransition transition, long seed) { + MarioQuaMario.LOGGER.info("Executing transition for {} on {}:\n\t{} -> {} (seed: {})", + data.getMario().getName().getString(), data.isClient() ? "CLIENT" : "SERVER", + data.getActionID(), transition.targetAction().ID, seed ); if(data instanceof MarioMoveableData moveableData && transition.travelExecutor() != null) transition.travelExecutor().execute(moveableData); if(data instanceof IMarioClientData clientData && transition.clientsExecutor() != null) transition.clientsExecutor().execute(clientData, data.getMario().isMainPlayer(), seed); + + data.setActionTransitionlessInternal(transition.targetAction()); } } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java index a3cd831..ec8b602 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java @@ -1,8 +1,10 @@ package com.fqf.mario_qua_mario.registries.actions; -import com.fqf.mario_qua_mario.definitions.actions.util.EvaluatorContext; +import com.fqf.mario_qua_mario.definitions.actions.util.EvaluatorEnvironment; import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; import com.fqf.mario_qua_mario.registries.RegistryManager; +import net.minecraft.util.crash.CrashException; +import net.minecraft.util.crash.CrashReport; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,11 +19,26 @@ public record ParsedTransition( ) { public ParsedTransition(TransitionDefinition definition) { this( - Objects.requireNonNull(RegistryManager.ACTIONS.get(definition.targetID())), + getTargetAction(definition), definition.evaluator(), - definition.context() != EvaluatorContext.COMMON, + definition.environment() != EvaluatorEnvironment.COMMON, definition.travelExecutor(), definition.clientsExecutor() ); } + + public static @NotNull AbstractParsedAction getTargetAction(TransitionDefinition definition) { + AbstractParsedAction targetAction = RegistryManager.ACTIONS.get(definition.targetID()); + if(targetAction == null) throw new CrashException(new CrashReport( + "Attempting to register a transition into action \"" + definition.targetID() + + "\", but that action isn't registered! Check your entrypoints!", + new InvalidTargetActionException("Transition to " + definition.targetID()))); + return targetAction; + } + + public static class InvalidTargetActionException extends RuntimeException { + public InvalidTargetActionException(String message) { + super(message); + } + } }