Skip to content

Commit 3ef85ad

Browse files
authored
Modded ItemInstance Data and TileInteractionCallback (#19)
* version bumps * add tick callback * more world gen events * changes * update loader version * specify stuff * bump version * improve docs * Better copying * warning it's broken * so save/load works * f*kn mojang * progress * attached data * attached data 2 * attached data 3 * e * update mappings * make datamanager constructor public; make DataManager#copyData * Delete MixinItemEntity.java * remove item entity mixin * Update MixinClientInteractionManager.java * Update MixinClass_70.java * Final touches? * docs
1 parent 2e21811 commit 3ef85ad

19 files changed

+468
-19
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ dependencies {
5656
//to change the versions see the gradle.properties file
5757
minecraft "com.mojang:minecraft:${project.minecraft_version}"
5858

59-
mappings loom.fromCommit("minecraft-cursed-legacy/Plasma", "b464f27") {spec ->
60-
spec.version = "b1.7.3-12"
59+
mappings loom.fromCommit("minecraft-cursed-legacy/Plasma", "f900cd3") {spec ->
60+
spec.version = "b1.7.3-14"
6161
}
6262

6363
// for config api

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ org.gradle.jvmargs=-Xmx1G
66
loader_version=8f014a3
77

88
# Mod Properties
9-
mod_version = 0.6.2
9+
mod_version = 0.6.3
1010
maven_group = io.github.minecraftcursedlegacy.api
1111
archives_base_name = cursed-legacy-api
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.github.minecraftcursedlegacy.api.data;
2+
3+
import io.github.minecraftcursedlegacy.api.registry.Id;
4+
import net.minecraft.util.io.CompoundTag;
5+
6+
/**
7+
* Data which can be attached to various vanilla objects, such as items and blocks.
8+
* @see {@link DataManager}.
9+
*/
10+
public interface AttachedData {
11+
/**
12+
* @return the id of this modded data.
13+
*/
14+
Id getId();
15+
/**
16+
* @return a tag representation of this data.
17+
*/
18+
CompoundTag toTag(CompoundTag tag);
19+
/**
20+
* @param tag the tag from which to load data.
21+
*/
22+
void fromTag(CompoundTag tag);
23+
/**
24+
* Creates a deep copy of this {@link AttachedData}, similar to the recommendations for {@link Object#clone}.
25+
*/
26+
AttachedData copy();
27+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package io.github.minecraftcursedlegacy.api.data;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Set;
6+
import java.util.function.Function;
7+
8+
import io.github.minecraftcursedlegacy.api.registry.Id;
9+
import io.github.minecraftcursedlegacy.impl.data.DataStorage;
10+
import net.minecraft.item.ItemInstance;
11+
import net.minecraft.util.io.CompoundTag;
12+
13+
/**
14+
* Manager for data which can be attached to various vanilla objects, such as items and blocks.
15+
*/
16+
public final class DataManager<T> {
17+
private final Map<Id, Function<T, ? extends AttachedData>> attachedDataFactories = new HashMap<>();
18+
19+
/**
20+
* Adds the specified attached data to the {@link DataManager} instance. This data can later be accessed on an instance of the object via {@link #getAttachedData}.
21+
* @return a key to use to retrieve the attached data from an object.
22+
*/
23+
public <E extends AttachedData> DataKey<E> addAttachedData(Id id, Function<T, E> dataProvider) {
24+
this.attachedDataFactories.put(id, dataProvider);
25+
return new DataKey<>(id);
26+
}
27+
28+
/**
29+
* Retrieves the specified attached data from the object.
30+
*/
31+
public <E extends AttachedData> E getAttachedData(T object, DataKey<E> key) throws ClassCastException {
32+
return key.apply(((DataStorage) object).getAttachedData(key.id, () -> this.attachedDataFactories.get(key.id).apply(object)));
33+
}
34+
35+
/**
36+
* Used by the implementation.
37+
* @return a {@linkplain Set set} of all {@linkplain Id ids} of {@link AttachedData} instances registered to this manager.
38+
*/
39+
public Set<Id> getDataKeys() {
40+
return this.attachedDataFactories.keySet();
41+
}
42+
43+
/**
44+
* Used by the implementation.
45+
* @return an attached data instance of the given type constructed by the given tag.
46+
*/
47+
public AttachedData deserialize(T object, Id id, CompoundTag data) {
48+
AttachedData result = this.attachedDataFactories.get(id).apply(object);
49+
result.fromTag(data);
50+
return result;
51+
}
52+
53+
/**
54+
* Used by the implementation.
55+
* @param from the object to use the data of.
56+
* @param to the object to receive the data.
57+
*/
58+
public void copyData(T from, T to) {
59+
DataStorage to_ = (DataStorage) (Object) to;
60+
61+
((DataStorage) (Object) from).getAllAttachedData().forEach(entry -> {
62+
Id dataId = entry.getKey();
63+
AttachedData data = entry.getValue();
64+
to_.putAttachedData(dataId, data.copy());
65+
});
66+
}
67+
68+
public static final DataManager<ItemInstance> ITEM_INSTANCE = new DataManager<>();
69+
70+
public static final class DataKey<T extends AttachedData> {
71+
private DataKey(Id id) throws NullPointerException {
72+
if (id == null) {
73+
throw new NullPointerException("DataKey cannot store a null ID!");
74+
}
75+
76+
this.id = id;
77+
}
78+
79+
private final Id id;
80+
81+
@SuppressWarnings("unchecked")
82+
private T apply(AttachedData data) throws ClassCastException {
83+
return (T) data;
84+
}
85+
}
86+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.github.minecraftcursedlegacy.api.event;
2+
3+
import javax.annotation.Nullable;
4+
5+
import net.fabricmc.fabric.api.event.Event;
6+
import net.fabricmc.fabric.api.event.EventFactory;
7+
import net.minecraft.entity.player.Player;
8+
import net.minecraft.item.ItemInstance;
9+
import net.minecraft.level.Level;
10+
import net.minecraft.tile.Tile;
11+
12+
/**
13+
* Callback for right clicking a tile. This is run both client and server side.
14+
*
15+
* <p>Upon return:
16+
* <ul>
17+
* <li> SUCCESS cancels further event processing and vanilla code, and the method this is event is called from returns true (succeeds).
18+
* <li> PASS falls back to further event processing. If all events PASS, then vanilla behaviour runs.
19+
* <li> FAIL cancels further event processing and vanilla code, and the method this is event is called from returns false (fails).
20+
* </ul>
21+
*/
22+
@FunctionalInterface
23+
public interface TileInteractionCallback {
24+
Event<TileInteractionCallback> EVENT = EventFactory.createArrayBacked(TileInteractionCallback.class,
25+
(listeners) -> (player, level, item, tile, x, y, z, face) -> {
26+
for (TileInteractionCallback listener : listeners) {
27+
ActionResult result = listener.onTileInteract(player, level, item, tile, x, y, z, face);
28+
29+
if (result != ActionResult.PASS) {
30+
return result;
31+
}
32+
}
33+
34+
return ActionResult.PASS;
35+
});
36+
37+
/**
38+
* @param player the player causing the tile interaction.
39+
* @param level the level the tile is being interacted with in.
40+
* @param item the item instance that the player is using to interact with the tile.
41+
* @param tile the tile being interacted with at the time of this event firing. This does not change if an event subscriber alters the tile at that position.
42+
* @param face probably the tile face. The last parameter of {@link ItemInstance#useOnTile(Player, Level, int, int, int, int)};
43+
* @return the action result, as specified in the javadoc of {@link TileInteractionCallback}.
44+
*/
45+
ActionResult onTileInteract(Player player, Level level, @Nullable ItemInstance item, Tile tile, int x, int y, int z, int face);
46+
}

src/main/java/io/github/minecraftcursedlegacy/impl/client/CustomAtlas.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66

77
import javax.imageio.ImageIO;
88

9-
import net.minecraft.client.texture.TextureManager;
10-
119
import net.fabricmc.api.EnvType;
1210
import net.fabricmc.api.Environment;
1311
import net.fabricmc.loader.api.FabricLoader;
12+
import net.minecraft.client.texture.TextureManager;
1413

1514
class CustomAtlas implements Atlas {
1615
private static final short MAX_SLOTS = 16 * 16;
@@ -65,7 +64,7 @@ public int allocate(BufferedImage sprite) {
6564
@Environment(EnvType.CLIENT)
6665
public int getTextureID(TextureManager manager) {
6766
if (textureID < 0) {
68-
textureID = manager.method_1088(image);
67+
textureID = manager.glLoadImage(image);
6968
needsRefresh = false;
7069
} else if (needsRefresh) {
7170
needsRefresh = false;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.github.minecraftcursedlegacy.impl.data;
2+
3+
import java.util.Map.Entry;
4+
import java.util.Set;
5+
import java.util.function.Supplier;
6+
7+
import io.github.minecraftcursedlegacy.api.data.AttachedData;
8+
import io.github.minecraftcursedlegacy.api.registry.Id;
9+
import net.minecraft.util.io.CompoundTag;
10+
11+
public interface DataStorage {
12+
CompoundTag getModdedTag();
13+
void putAttachedData(Id id, AttachedData data);
14+
AttachedData getAttachedData(Id id, Supplier<AttachedData> supplier);
15+
Set<Entry<Id,AttachedData>> getAllAttachedData();
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.github.minecraftcursedlegacy.impl.event;
2+
3+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
4+
5+
import io.github.minecraftcursedlegacy.api.event.ActionResult;
6+
import io.github.minecraftcursedlegacy.api.event.TileInteractionCallback;
7+
import net.minecraft.entity.player.Player;
8+
import net.minecraft.item.ItemInstance;
9+
import net.minecraft.level.Level;
10+
import net.minecraft.tile.Tile;
11+
12+
public class TileInteractionImpl {
13+
public static void onTileInteract(Player player, Level level, ItemInstance item, int x, int y, int z, int i1, CallbackInfoReturnable<Boolean> info) {
14+
int tile = level.getTileId(x, y, z);
15+
ActionResult result = TileInteractionCallback.EVENT.invoker().onTileInteract(player, level, item, Tile.BY_ID[tile], x, y, z, i1);
16+
17+
if (result != ActionResult.PASS) {
18+
info.setReturnValue(result == ActionResult.SUCCESS);
19+
}
20+
}
21+
}

src/main/java/io/github/minecraftcursedlegacy/impl/levelgen/LevelGenImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void onInitialize() {
1616
int xToGen = x + rand.nextInt(16) + 8;
1717
int zToGen = z + rand.nextInt(16) + 8;
1818
Feature var18 = biome.getTree(rand);
19-
var18.method_1143(1.0D, 1.0D, 1.0D);
19+
var18.setupTreeGeneration(1.0D, 1.0D, 1.0D);
2020
var18.generate(level, rand, xToGen, level.getHeight(xToGen, zToGen), zToGen);
2121
}
2222
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.github.minecraftcursedlegacy.mixin;
2+
3+
import org.spongepowered.asm.mixin.Mixin;
4+
import org.spongepowered.asm.mixin.injection.At;
5+
import org.spongepowered.asm.mixin.injection.Inject;
6+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
7+
8+
import io.github.minecraftcursedlegacy.impl.event.TileInteractionImpl;
9+
import net.minecraft.client.ClientInteractionManager;
10+
import net.minecraft.entity.player.Player;
11+
import net.minecraft.item.ItemInstance;
12+
import net.minecraft.level.Level;
13+
14+
@Mixin(ClientInteractionManager.class)
15+
public class MixinClientInteractionManager {
16+
@Inject(at = @At("HEAD"), method = "useItemOnTile", cancellable = true)
17+
private void api_onTileInteract(Player player, Level level, ItemInstance item, int x, int y, int z, int i1, CallbackInfoReturnable<Boolean> info) {
18+
TileInteractionImpl.onTileInteract(player, level, item, x, y, z, i1, info);
19+
}
20+
}

0 commit comments

Comments
 (0)