I have been working on a class called Registry Writer, which I am using to, for instance, replace the SpawnEggItem with my own, but it isn't working for some reason, the item (Bat Spawn Egg) will not drop on my client.
Just to start, this is part big project and nothing else messes with registries, only this, so I will not switch to Forge. I am fine with editing the server jar but I would rather do that as a last resort. If you are wondering why I am doing this, it is because you can stop spawning of a spawn egg, but not when it is used on an entity to create offspring (at least, not without losing the item).
Here's the registry writer:
Any uppercase variables are reflection fields, all fields are the objects within the MappedRegistry class pulled and cached.
Just to start, this is part big project and nothing else messes with registries, only this, so I will not switch to Forge. I am fine with editing the server jar but I would rather do that as a last resort. If you are wondering why I am doing this, it is because you can stop spawning of a spawn egg, but not when it is used on an entity to create offspring (at least, not without losing the item).
Here's the registry writer:
Java:
public synchronized void clearCache() {
INTRUSIVE_HOLDER_CACHE.set(registry, new IdentityHashMap<>());
}
public synchronized void open() {
FROZEN.set(registry, false);
clearCache();
}
public synchronized <V extends T> V register(ResourceKey<T> id, V entry) {
return register(id, entry, -1, Lifecycle.stable());
}
private <V extends T> V register(ResourceKey<T> key, V entry, int rawId, Lifecycle lifecycle) {
if (isClosed()) open();
if (rawId < 0) registry.register(key, entry, lifecycle);
else registry.registerMapping(rawId, key, entry, lifecycle);
return entry;
}
// inspired by Registry.registerOrOverride()
public synchronized T unregister(ResourceKey<T> key) {
if (isClosed()) open();
if (key== null) return null;
Optional<Holder<T>> toRemove = registry.getHolder(key);
T t;
if (toRemove.isPresent()) {
t = toRemove.get().value();
lifecycles.remove(t);
toId.removeInt(t);
byValue.remove(t);
} else t = null;
byKey.remove(key);
return t;
}
// should (supposedly) replace the entry of the object at the key with a new entry without changing anything else, but does not work
public synchronized T replace(ResourceKey<T> key, T entry) {
if (isClosed()) open();
int id = toId.getInt(key);
T old = unregister(key);
if (old != null) register(key, entry, id, Lifecycle.stable());
else register(key, entry);
return old;
}
public synchronized boolean isClosed() {
return !FROZEN.get(registry);
}
Any uppercase variables are reflection fields, all fields are the objects within the MappedRegistry class pulled and cached.
Last edited: