diff --git a/src/main/java/errorcraft/entitymodifiers/entity/modifier/Deserialisers.java b/src/main/java/errorcraft/entitymodifiers/entity/modifier/Deserialisers.java index fd6a697..feb09b2 100644 --- a/src/main/java/errorcraft/entitymodifiers/entity/modifier/Deserialisers.java +++ b/src/main/java/errorcraft/entitymodifiers/entity/modifier/Deserialisers.java @@ -4,6 +4,7 @@ import errorcraft.entitymodifiers.util.RelativeNumberProvider; import errorcraft.entitymodifiers.world.position.provider.PositionProvider; import errorcraft.entitymodifiers.world.position.provider.PositionProviderTypes; +import errorcraft.entitymodifiers.world.rotation.RotationProvider; import net.minecraft.loot.context.LootContext; import net.minecraft.loot.provider.number.LootNumberProvider; import net.minecraft.loot.provider.number.LootNumberProviderTypes; @@ -20,6 +21,7 @@ public static GsonBuilder createEntityModifierSerialiser() { .registerTypeHierarchyAdapter(LootScoreProvider.class, LootScoreProviderTypes.createGsonSerializer()) .registerTypeHierarchyAdapter(LootContext.EntityTarget.class, new LootContext.EntityTarget.Serializer()) .registerTypeHierarchyAdapter(PositionProvider.class, PositionProviderTypes.createGsonAdapter()) + .registerTypeHierarchyAdapter(RotationProvider.class, new RotationProvider.Serialiser()) .registerTypeHierarchyAdapter(RelativeNumberProvider.class, new RelativeNumberProvider.Serialiser()); } } diff --git a/src/main/java/errorcraft/entitymodifiers/entity/modifier/EntityModifierTypes.java b/src/main/java/errorcraft/entitymodifiers/entity/modifier/EntityModifierTypes.java index 1808584..ce00eb1 100644 --- a/src/main/java/errorcraft/entitymodifiers/entity/modifier/EntityModifierTypes.java +++ b/src/main/java/errorcraft/entitymodifiers/entity/modifier/EntityModifierTypes.java @@ -20,6 +20,7 @@ public class EntityModifierTypes { public static final EntityModifierType SET_ABSORPTION = register("set_absorption", new SetAbsorptionEntityModifier.Serialiser()); public static final EntityModifierType SET_SATURATION = register("set_saturation", new SetSaturationEntityModifier.Serialiser()); public static final EntityModifierType SET_POSITION = register("set_position", new SetPositionEntityModifier.Serialiser()); + public static final EntityModifierType SET_ROTATION = register("set_rotation", new SetRotationEntityModifier.Serialiser()); public static Object createGsonAdapter() { return JsonSerializing.createSerializerBuilder(ENTITY_MODIFIER_TYPE, "function", "function", EntityModifier::getType).build(); diff --git a/src/main/java/errorcraft/entitymodifiers/entity/modifier/modifiers/SetRotationEntityModifier.java b/src/main/java/errorcraft/entitymodifiers/entity/modifier/modifiers/SetRotationEntityModifier.java new file mode 100644 index 0000000..9490d03 --- /dev/null +++ b/src/main/java/errorcraft/entitymodifiers/entity/modifier/modifiers/SetRotationEntityModifier.java @@ -0,0 +1,55 @@ +package errorcraft.entitymodifiers.entity.modifier.modifiers; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import errorcraft.entitymodifiers.entity.modifier.EntityModifier; +import errorcraft.entitymodifiers.entity.modifier.EntityModifierType; +import errorcraft.entitymodifiers.entity.modifier.EntityModifierTypes; +import errorcraft.entitymodifiers.world.rotation.RotationProvider; +import net.minecraft.entity.Entity; +import net.minecraft.loot.context.LootContext; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.JsonHelper; +import net.minecraft.util.math.Vec2f; + +public class SetRotationEntityModifier implements EntityModifier { + private final RotationProvider rotation; + + public SetRotationEntityModifier(RotationProvider rotation) { + this.rotation = rotation; + } + + @Override + public EntityModifierType getType() { + return EntityModifierTypes.SET_ROTATION; + } + + @Override + public Entity apply(Entity entity, LootContext lootContext) { + Vec2f newRotation = this.rotation.getRotation(entity.getRotationClient(), lootContext); + entity.refreshPositionAndAngles(entity.getX(), entity.getY(), entity.getZ(), newRotation.y, newRotation.x); + entity.setHeadYaw(newRotation.y); + if (entity instanceof ServerPlayerEntity player) { + setPlayerRotation(player, newRotation); + } + return entity; + } + + private static void setPlayerRotation(ServerPlayerEntity player, Vec2f rotation) { + player.networkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), rotation.y, rotation.x); + } + + public static class Serialiser implements EntityModifier.Serialiser { + @Override + public void toJson(JsonObject json, SetRotationEntityModifier object, JsonSerializationContext context) { + json.add("rotation", context.serialize(object.rotation)); + } + + @Override + public SetRotationEntityModifier fromJson(JsonObject json, JsonDeserializationContext context) { + RotationProvider rotation = JsonHelper.deserialize(json, "rotation", context, RotationProvider.class); + return new SetRotationEntityModifier(rotation); + } + } +} diff --git a/src/main/java/errorcraft/entitymodifiers/world/rotation/RotationProvider.java b/src/main/java/errorcraft/entitymodifiers/world/rotation/RotationProvider.java new file mode 100644 index 0000000..08bac7c --- /dev/null +++ b/src/main/java/errorcraft/entitymodifiers/world/rotation/RotationProvider.java @@ -0,0 +1,43 @@ +package errorcraft.entitymodifiers.world.rotation; + +import com.google.gson.*; +import errorcraft.entitymodifiers.util.RelativeNumberProvider; +import net.minecraft.loot.context.LootContext; +import net.minecraft.util.JsonHelper; +import net.minecraft.util.math.Vec2f; + +import java.lang.reflect.Type; + +public class RotationProvider { + private final RelativeNumberProvider x; + private final RelativeNumberProvider y; + + public RotationProvider(RelativeNumberProvider x, RelativeNumberProvider y) { + this.x = x; + this.y = y; + } + + public Vec2f getRotation(Vec2f currentRotation, LootContext lootContext) { + float newX = this.x.getFloat(currentRotation.x, lootContext); + float newY = this.y.getFloat(currentRotation.y, lootContext); + return new Vec2f(newX, newY); + } + + public static class Serialiser implements JsonDeserializer, JsonSerializer { + @Override + public RotationProvider deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { + JsonObject jsonObject = JsonHelper.asObject(json, "value"); + RelativeNumberProvider x = JsonHelper.deserialize(jsonObject, "x", context, RelativeNumberProvider.class); + RelativeNumberProvider y = JsonHelper.deserialize(jsonObject, "y", context, RelativeNumberProvider.class); + return new RotationProvider(x, y); + } + + @Override + public JsonElement serialize(RotationProvider object, Type type, JsonSerializationContext context) { + JsonObject json = new JsonObject(); + json.add("x", context.serialize(object.x)); + json.add("y", context.serialize(object.y)); + return json; + } + } +}