Skip to content

Commit cb83e6e

Browse files
authored
Merge pull request #5 from ErrorCraft/set_position
Add minecraft:set_position entity modifier (Closes #4)
2 parents 0d226c8 + 8dd6e27 commit cb83e6e

10 files changed

Lines changed: 292 additions & 5 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx1G
55
# check these on https://fabricmc.net/versions.html
66
minecraft_version=1.18.2
77
yarn_mappings=1.18.2+build.3
8-
loader_version=0.13.3
8+
loader_version=0.14.5
99

1010
# Mod Properties
1111
mod_version = 1.1.0
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package errorcraft.entitymodifiers.entity.modifier;
22

33
import com.google.gson.GsonBuilder;
4+
import errorcraft.entitymodifiers.util.RelativeNumberProvider;
5+
import errorcraft.entitymodifiers.world.position.provider.PositionProvider;
6+
import errorcraft.entitymodifiers.world.position.provider.PositionProviderTypes;
47
import net.minecraft.loot.context.LootContext;
58
import net.minecraft.loot.provider.number.LootNumberProvider;
69
import net.minecraft.loot.provider.number.LootNumberProviderTypes;
@@ -12,9 +15,11 @@ private Deserialisers() {}
1215

1316
public static GsonBuilder createEntityModifierSerialiser() {
1417
return new GsonBuilder()
15-
.registerTypeHierarchyAdapter(EntityModifier.class, EntityModifierTypes.createGsonAdapter())
16-
.registerTypeHierarchyAdapter(LootNumberProvider.class, LootNumberProviderTypes.createGsonSerializer())
17-
.registerTypeHierarchyAdapter(LootScoreProvider.class, LootScoreProviderTypes.createGsonSerializer())
18-
.registerTypeHierarchyAdapter(LootContext.EntityTarget.class, new LootContext.EntityTarget.Serializer());
18+
.registerTypeHierarchyAdapter(EntityModifier.class, EntityModifierTypes.createGsonAdapter())
19+
.registerTypeHierarchyAdapter(LootNumberProvider.class, LootNumberProviderTypes.createGsonSerializer())
20+
.registerTypeHierarchyAdapter(LootScoreProvider.class, LootScoreProviderTypes.createGsonSerializer())
21+
.registerTypeHierarchyAdapter(LootContext.EntityTarget.class, new LootContext.EntityTarget.Serializer())
22+
.registerTypeHierarchyAdapter(PositionProvider.class, PositionProviderTypes.createGsonAdapter())
23+
.registerTypeHierarchyAdapter(RelativeNumberProvider.class, new RelativeNumberProvider.Serialiser());
1924
}
2025
}

src/main/java/errorcraft/entitymodifiers/entity/modifier/EntityModifierTypes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class EntityModifierTypes {
1919
public static final EntityModifierType SET_CUSTOM_NAME = register("set_custom_name", new SetCustomNameEntityModifier.Serialiser());
2020
public static final EntityModifierType SET_ABSORPTION = register("set_absorption", new SetAbsorptionEntityModifier.Serialiser());
2121
public static final EntityModifierType SET_SATURATION = register("set_saturation", new SetSaturationEntityModifier.Serialiser());
22+
public static final EntityModifierType SET_POSITION = register("set_position", new SetPositionEntityModifier.Serialiser());
2223

2324
public static Object createGsonAdapter() {
2425
return JsonSerializing.createSerializerBuilder(ENTITY_MODIFIER_TYPE, "function", "function", EntityModifier::getType).build();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package errorcraft.entitymodifiers.entity.modifier.modifiers;
2+
3+
import com.google.gson.JsonDeserializationContext;
4+
import com.google.gson.JsonObject;
5+
import com.google.gson.JsonSerializationContext;
6+
import errorcraft.entitymodifiers.entity.modifier.EntityModifier;
7+
import errorcraft.entitymodifiers.entity.modifier.EntityModifierType;
8+
import errorcraft.entitymodifiers.entity.modifier.EntityModifierTypes;
9+
import errorcraft.entitymodifiers.world.position.provider.PositionProvider;
10+
import net.minecraft.entity.Entity;
11+
import net.minecraft.loot.context.LootContext;
12+
import net.minecraft.loot.provider.number.LootNumberProvider;
13+
import net.minecraft.server.network.ServerPlayerEntity;
14+
import net.minecraft.util.JsonHelper;
15+
import net.minecraft.util.math.Vec3d;
16+
17+
public class SetPositionEntityModifier implements EntityModifier {
18+
private final PositionProvider position;
19+
20+
public SetPositionEntityModifier(PositionProvider position) {
21+
this.position = position;
22+
}
23+
24+
@Override
25+
public EntityModifierType getType() {
26+
return EntityModifierTypes.SET_POSITION;
27+
}
28+
29+
@Override
30+
public Entity apply(Entity entity, LootContext lootContext) {
31+
Vec3d newPos = this.position.getPosition(entity.getPos(), entity.getRotationClient(), lootContext);
32+
entity.setPosition(newPos);
33+
if (entity instanceof ServerPlayerEntity player) {
34+
setPlayerPosition(player, newPos);
35+
}
36+
return entity;
37+
}
38+
39+
private static void setPlayerPosition(ServerPlayerEntity player, Vec3d pos) {
40+
if (player.isSleeping()) {
41+
player.wakeUp(true, true);
42+
}
43+
player.requestTeleportAndDismount(pos.getX(), pos.getY(), pos.getZ());
44+
}
45+
46+
public static class Serialiser implements EntityModifier.Serialiser<SetPositionEntityModifier> {
47+
@Override
48+
public void toJson(JsonObject json, SetPositionEntityModifier object, JsonSerializationContext context) {
49+
json.add("position", context.serialize(object.position));
50+
}
51+
52+
@Override
53+
public SetPositionEntityModifier fromJson(JsonObject json, JsonDeserializationContext context) {
54+
PositionProvider position = JsonHelper.deserialize(json, "position", context, PositionProvider.class);
55+
return new SetPositionEntityModifier(position);
56+
}
57+
}
58+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package errorcraft.entitymodifiers.util;
2+
3+
import com.google.gson.*;
4+
import net.minecraft.loot.context.LootContext;
5+
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
6+
import net.minecraft.loot.provider.number.LootNumberProvider;
7+
import net.minecraft.util.JsonHelper;
8+
9+
import java.lang.reflect.Type;
10+
11+
public class RelativeNumberProvider {
12+
private final LootNumberProvider value;
13+
private final boolean relative;
14+
15+
public RelativeNumberProvider(LootNumberProvider value, boolean relative) {
16+
this.value = value;
17+
this.relative = relative;
18+
}
19+
20+
public double getDouble(double currentValue, LootContext context) {
21+
if (this.relative) {
22+
return currentValue + this.value.nextFloat(context);
23+
}
24+
return this.value.nextFloat(context);
25+
}
26+
27+
public float getFloat(float currentValue, LootContext context) {
28+
if (this.relative) {
29+
return currentValue + this.value.nextFloat(context);
30+
}
31+
return this.value.nextFloat(context);
32+
}
33+
34+
public int getInt(int currentValue, LootContext context) {
35+
if (this.relative) {
36+
return currentValue + this.value.nextInt(context);
37+
}
38+
return this.value.nextInt(context);
39+
}
40+
41+
public static class Serialiser implements JsonDeserializer<RelativeNumberProvider>, JsonSerializer<RelativeNumberProvider> {
42+
@Override
43+
public RelativeNumberProvider deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
44+
if (json.isJsonPrimitive()) {
45+
return new RelativeNumberProvider(ConstantLootNumberProvider.create(json.getAsFloat()), false);
46+
}
47+
48+
JsonObject jsonObject = JsonHelper.asObject(json, "value");
49+
LootNumberProvider value = JsonHelper.deserialize(jsonObject, "value", context, LootNumberProvider.class);
50+
boolean relative = JsonHelper.getBoolean(jsonObject, "relative", false);
51+
return new RelativeNumberProvider(value, relative);
52+
}
53+
54+
@Override
55+
public JsonElement serialize(RelativeNumberProvider object, Type type, JsonSerializationContext context) {
56+
JsonObject json = new JsonObject();
57+
json.add("value", context.serialize(object.value));
58+
json.addProperty("relative", object.relative);
59+
return json;
60+
}
61+
}
62+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package errorcraft.entitymodifiers.world.position.provider;
2+
3+
import net.minecraft.loot.context.LootContext;
4+
import net.minecraft.util.JsonSerializer;
5+
import net.minecraft.util.math.Vec2f;
6+
import net.minecraft.util.math.Vec3d;
7+
8+
public interface PositionProvider {
9+
PositionProviderType getType();
10+
Vec3d getPosition(Vec3d currentPosition, Vec2f rotation, LootContext lootContext);
11+
12+
interface Serialiser<T extends PositionProvider> extends JsonSerializer<T> {}
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package errorcraft.entitymodifiers.world.position.provider;
2+
3+
import net.minecraft.util.JsonSerializableType;
4+
import net.minecraft.util.JsonSerializer;
5+
6+
public class PositionProviderType extends JsonSerializableType<PositionProvider> {
7+
public PositionProviderType(JsonSerializer<? extends PositionProvider> jsonSerializer) {
8+
super(jsonSerializer);
9+
}
10+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package errorcraft.entitymodifiers.world.position.provider;
2+
3+
import errorcraft.entitymodifiers.mixin.registry.RegistryAccessor;
4+
import errorcraft.entitymodifiers.world.position.provider.providers.LocalPositionProvider;
5+
import errorcraft.entitymodifiers.world.position.provider.providers.WorldPositionProvider;
6+
import net.minecraft.util.Identifier;
7+
import net.minecraft.util.JsonSerializing;
8+
import net.minecraft.util.registry.Registry;
9+
import net.minecraft.util.registry.RegistryKey;
10+
11+
public class PositionProviderTypes {
12+
public static final RegistryKey<Registry<PositionProviderType>> POSITION_PROVIDER_TYPE_KEY = RegistryAccessor.createRegistryKey("position_provider_type");
13+
public static final Registry<PositionProviderType> POSITION_PROVIDER_TYPE = RegistryAccessor.create(POSITION_PROVIDER_TYPE_KEY, registry -> PositionProviderTypes.WORLD);
14+
15+
public static final PositionProviderType WORLD = register("world", new WorldPositionProvider.Serialiser());
16+
public static final PositionProviderType LOCAL = register("local", new LocalPositionProvider.Serialiser());
17+
18+
public static Object createGsonAdapter() {
19+
return JsonSerializing.createSerializerBuilder(POSITION_PROVIDER_TYPE, "type", "type", PositionProvider::getType).build();
20+
}
21+
22+
private static PositionProviderType register(String id, PositionProvider.Serialiser<? extends PositionProvider> serialiser) {
23+
return Registry.register(POSITION_PROVIDER_TYPE, new Identifier(id), new PositionProviderType(serialiser));
24+
}
25+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package errorcraft.entitymodifiers.world.position.provider.providers;
2+
3+
import com.google.gson.JsonDeserializationContext;
4+
import com.google.gson.JsonObject;
5+
import com.google.gson.JsonSerializationContext;
6+
import errorcraft.entitymodifiers.world.position.provider.PositionProvider;
7+
import errorcraft.entitymodifiers.world.position.provider.PositionProviderType;
8+
import errorcraft.entitymodifiers.world.position.provider.PositionProviderTypes;
9+
import net.minecraft.command.argument.LookingPosArgument;
10+
import net.minecraft.loot.context.LootContext;
11+
import net.minecraft.loot.provider.number.LootNumberProvider;
12+
import net.minecraft.server.command.ServerCommandSource;
13+
import net.minecraft.util.JsonHelper;
14+
import net.minecraft.util.math.Vec2f;
15+
import net.minecraft.util.math.Vec3d;
16+
17+
public class LocalPositionProvider implements PositionProvider {
18+
private final LootNumberProvider left;
19+
private final LootNumberProvider up;
20+
private final LootNumberProvider forwards;
21+
22+
public LocalPositionProvider(LootNumberProvider left, LootNumberProvider up, LootNumberProvider forwards) {
23+
this.left = left;
24+
this.up = up;
25+
this.forwards = forwards;
26+
}
27+
28+
@Override
29+
public PositionProviderType getType() {
30+
return PositionProviderTypes.LOCAL;
31+
}
32+
33+
@Override
34+
public Vec3d getPosition(Vec3d currentPosition, Vec2f rotation, LootContext lootContext) {
35+
double leftOffset = this.left.nextFloat(lootContext);
36+
double upOffset = this.up.nextFloat(lootContext);
37+
double forwardsOffset = this.forwards.nextFloat(lootContext);
38+
LookingPosArgument argument = new LookingPosArgument(leftOffset, upOffset, forwardsOffset);
39+
ServerCommandSource commandSource = new ServerCommandSource(null, currentPosition, rotation, null, 0, null, null, null, null);
40+
return argument.toAbsolutePos(commandSource);
41+
}
42+
43+
public static class Serialiser implements PositionProvider.Serialiser<LocalPositionProvider> {
44+
@Override
45+
public void toJson(JsonObject json, LocalPositionProvider object, JsonSerializationContext context) {
46+
json.add("left", context.serialize(object.left));
47+
json.add("up", context.serialize(object.up));
48+
json.add("forwards", context.serialize(object.forwards));
49+
}
50+
51+
@Override
52+
public LocalPositionProvider fromJson(JsonObject json, JsonDeserializationContext context) {
53+
LootNumberProvider left = JsonHelper.deserialize(json, "left", context, LootNumberProvider.class);
54+
LootNumberProvider up = JsonHelper.deserialize(json, "up", context, LootNumberProvider.class);
55+
LootNumberProvider forwards = JsonHelper.deserialize(json, "forwards", context, LootNumberProvider.class);
56+
return new LocalPositionProvider(left, up, forwards);
57+
}
58+
}
59+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package errorcraft.entitymodifiers.world.position.provider.providers;
2+
3+
import com.google.gson.JsonDeserializationContext;
4+
import com.google.gson.JsonObject;
5+
import com.google.gson.JsonSerializationContext;
6+
import errorcraft.entitymodifiers.util.RelativeNumberProvider;
7+
import errorcraft.entitymodifiers.world.position.provider.PositionProvider;
8+
import errorcraft.entitymodifiers.world.position.provider.PositionProviderType;
9+
import errorcraft.entitymodifiers.world.position.provider.PositionProviderTypes;
10+
import net.minecraft.loot.context.LootContext;
11+
import net.minecraft.util.JsonHelper;
12+
import net.minecraft.util.math.Vec2f;
13+
import net.minecraft.util.math.Vec3d;
14+
15+
public class WorldPositionProvider implements PositionProvider {
16+
private final RelativeNumberProvider x;
17+
private final RelativeNumberProvider y;
18+
private final RelativeNumberProvider z;
19+
20+
public WorldPositionProvider(RelativeNumberProvider x, RelativeNumberProvider y, RelativeNumberProvider z) {
21+
this.x = x;
22+
this.y = y;
23+
this.z = z;
24+
}
25+
26+
public PositionProviderType getType() {
27+
return PositionProviderTypes.WORLD;
28+
}
29+
30+
@Override
31+
public Vec3d getPosition(Vec3d currentPosition, Vec2f rotation, LootContext lootContext) {
32+
double newX = this.x.getDouble(currentPosition.getX(), lootContext);
33+
double newY = this.y.getDouble(currentPosition.getY(), lootContext);
34+
double newZ = this.z.getDouble(currentPosition.getZ(), lootContext);
35+
return new Vec3d(newX, newY, newZ);
36+
}
37+
38+
public static class Serialiser implements PositionProvider.Serialiser<WorldPositionProvider> {
39+
@Override
40+
public void toJson(JsonObject json, WorldPositionProvider object, JsonSerializationContext context) {
41+
json.add("x", context.serialize(object.x));
42+
json.add("y", context.serialize(object.y));
43+
json.add("z", context.serialize(object.z));
44+
}
45+
46+
@Override
47+
public WorldPositionProvider fromJson(JsonObject json, JsonDeserializationContext context) {
48+
RelativeNumberProvider x = JsonHelper.deserialize(json, "x", context, RelativeNumberProvider.class);
49+
RelativeNumberProvider y = JsonHelper.deserialize(json, "y", context, RelativeNumberProvider.class);
50+
RelativeNumberProvider z = JsonHelper.deserialize(json, "z", context, RelativeNumberProvider.class);
51+
return new WorldPositionProvider(x, y, z);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)