9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-27 02:49:15 +00:00

add crop block

This commit is contained in:
XiaoMoMi
2025-03-29 00:39:09 +08:00
parent 80570d6f42
commit cd30c5b3b3
22 changed files with 316 additions and 84 deletions

View File

@@ -4,10 +4,14 @@ repositories {
maven("https://r.irepo.space/maven/")
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") // papi
maven("https://maven.enginehub.org/repo/") // worldguard worldedit
maven("https://repo.rapture.pw/repository/maven-releases/") // slime world
maven("https://repo.infernalsuite.com/repository/maven-snapshots/") // slime world
maven("https://repo.momirealms.net/releases/")
}
dependencies {
compileOnly(project(":core"))
compileOnly("net.momirealms:sparrow-nbt:${rootProject.properties["sparrow_nbt_version"]}")
// Platform
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
// NeigeItems
@@ -17,6 +21,8 @@ dependencies {
// WorldEdit
compileOnly("com.sk89q.worldedit:worldedit-core:7.2.19")
compileOnly("com.sk89q.worldedit:worldedit-bukkit:7.2.19")
// SlimeWorld
compileOnly("com.infernalsuite.asp:api:4.0.0-SNAPSHOT")
}
java {

View File

@@ -0,0 +1,40 @@
package net.momirealms.craftengine.bukkit.compatibility.slimeworld;
import com.infernalsuite.asp.api.AdvancedSlimePaperAPI;
import com.infernalsuite.asp.api.events.LoadSlimeWorldEvent;
import com.infernalsuite.asp.api.world.SlimeWorld;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldManager;
import net.momirealms.craftengine.core.world.chunk.storage.DefaultStorageAdaptor;
import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
public class SlimeFormatStorageAdaptor extends DefaultStorageAdaptor implements Listener {
private final WorldManager worldManager;
@EventHandler
public void onWorldLoad(LoadSlimeWorldEvent event) {
org.bukkit.World world = Bukkit.getWorld(event.getSlimeWorld().getName());
this.worldManager.loadWorld(this.worldManager.wrap(world));
}
public SlimeFormatStorageAdaptor(WorldManager worldManager) {
this.worldManager = worldManager;
}
public SlimeWorld getWorld(String name) {
return AdvancedSlimePaperAPI.instance().getLoadedWorld(name);
}
@Override
public @NotNull WorldDataStorage adapt(@NotNull World world) {
SlimeWorld slimeWorld = getWorld(world.name());
if (slimeWorld == null) {
return super.adapt(world);
}
return new SlimeWorldDataStorage(slimeWorld);
}
}

View File

@@ -0,0 +1,68 @@
package net.momirealms.craftengine.bukkit.compatibility.slimeworld;
import com.infernalsuite.asp.api.world.SlimeChunk;
import com.infernalsuite.asp.api.world.SlimeWorld;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.ByteArrayBinaryTag;
import net.momirealms.craftengine.core.world.ChunkPos;
import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.NBT;
import org.jetbrains.annotations.Nullable;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
public class SlimeWorldDataStorage implements WorldDataStorage {
private final WeakReference<SlimeWorld> slimeWorld;
public SlimeWorldDataStorage(SlimeWorld slimeWorld) {
this.slimeWorld = new WeakReference<>(slimeWorld);
}
public SlimeWorld getWorld() {
return slimeWorld.get();
}
@Nullable
@Override
public CompoundTag readChunkTagAt(ChunkPos pos) {
SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z);
if (slimeChunk == null) return null;
BinaryTag tag = slimeChunk.getExtraData().get("craftengine");
if (tag == null) return null;
ByteArrayBinaryTag byteArrayBinaryTag = (ByteArrayBinaryTag) tag;
try {
return NBT.readCompound(new DataInputStream(new ByteArrayInputStream(byteArrayBinaryTag.value())));
} catch (IOException e) {
throw new RuntimeException("Failed to read chunk tag from slime world. " + pos, e);
}
}
@Override
public void writeChunkTagAt(ChunkPos pos, @Nullable CompoundTag nbt) {
SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z);
if (slimeChunk == null) return;
if (nbt == null) {
slimeChunk.getExtraData().remove("craftengine");
} else {
slimeChunk.getExtraData().computeIfAbsent("craftengine", l -> {
try {
return ByteArrayBinaryTag.byteArrayBinaryTag(NBT.toBytes(nbt));
} catch (IOException e) {
throw new RuntimeException("Failed to write chunk tag to slime world. " + pos, e);
}
});
}
}
@Override
public void flush() {
}
@Override
public void close() throws IOException {
}
}

View File

@@ -62,4 +62,4 @@ categories:
- default:flame_cane
- default:gunpowder_block
- default:solid_gunpowder_block
- default:ender_pearl_flower_seed
- default:ender_pearl_flower_seeds

View File

@@ -4,7 +4,7 @@ i18n:
item.fairy_flower: "Fairy Flower"
item.reed: "Reed"
item.flame_cane: "Flame Cane"
item.ender_pearl_flower_seed: "Ender Pearl Flower Seeds"
item.ender_pearl_flower_seeds: "Ender Pearl Flower Seeds"
item.bench: "Bench"
item.table_lamp: "Table Lamp"
item.wooden_chair: "Wooden Chair"
@@ -44,7 +44,7 @@ i18n:
item.fairy_flower: "仙灵花"
item.reed: "芦苇"
item.flame_cane: "烈焰甘蔗"
item.ender_pearl_flower_seed: "末影珍珠花种子"
item.ender_pearl_flower_seeds: "末影珍珠花种子"
item.bench: "长椅"
item.table_lamp: "台灯"
item.wooden_chair: "木椅"

View File

@@ -2,7 +2,7 @@ images:
default:icons:
height: 10
ascent: 9
font: minecraft:default # Consider using other fonts if other plugins support custom font!
font: minecraft:icons # Do not use 'minecraft:default' unless other plugins don't support custom font!
file: minecraft:font/image/icons.png
chars:
- '\ub000\ub001'

View File

@@ -35,15 +35,15 @@ items:
behavior:
type: block_item
block: default:flame_cane
default:ender_pearl_flower_seed:
default:ender_pearl_flower_seeds:
material: paper
custom-model-data: 4003
data:
item-name: "<!i><i18n:item.ender_pearl_flower_seed>"
item-name: "<!i><i18n:item.ender_pearl_flower_seeds>"
model:
template: default:model/simplified_generated
arguments:
path: "minecraft:block/custom/ender_pearl_flower_seed"
path: "minecraft:item/custom/ender_pearl_flower_seeds"
behavior:
type: block_item
block: default:ender_pearl_flower
@@ -185,45 +185,53 @@ blocks:
- default:hardness/none
- default:sound/grass
overrides:
item: default:ender_pearl_flower_seed
item: default:ender_pearl_flower_seeds
push-reaction: DESTROY
map-color: 24
is-randomly-ticking: true
behavior:
type: crop_block
grow-speed: 1
min-grow-light: 9
grow-speed: 0.25
light-requirement: 9
bottom-blocks:
- minecraft:end_stone
loot:
template: default:loot_table/seed_crop
arguments:
crop_item: minecraft:ender_pearl
crop_seed: default:ender_pearl_flower_seed
ripe_age: 3
crop_seed: default:ender_pearl_flower_seeds
ripe_age: 2
states:
properties:
age:
type: int
default: 0
range: 0~3
range: 0~2
appearances:
stage_0:
state: "tripwire:0"
models:
- path: "minecraft:block/custom/ender_pearl_flower_stage_0"
generation:
parent: "minecraft:block/cross"
textures:
"cross": "minecraft:block/custom/ender_pearl_flower_stage_0"
stage_1:
state: "tripwire:1"
models:
- path: "minecraft:block/custom/ender_pearl_flower_stage_1"
generation:
parent: "minecraft:block/cross"
textures:
"cross": "minecraft:block/custom/ender_pearl_flower_stage_1"
stage_2:
state: "tripwire:2"
models:
- path: "minecraft:block/custom/ender_pearl_flower_stage_2"
stage_3:
state: "sugar_cane:3"
models:
- path: "minecraft:block/custom/ender_pearl_flower_stage_3"
generation:
parent: "minecraft:block/cross"
textures:
"cross": "minecraft:block/custom/ender_pearl_flower_stage_2"
variants:
age=0:
appearance: stage_0
@@ -234,9 +242,6 @@ blocks:
age=2:
appearance: stage_2
id: 2
age=3:
appearance: stage_3
id: 8
recipes:
default:paper_from_reed:
type: shaped
@@ -269,8 +274,9 @@ recipes:
result:
id: minecraft:magma_block
count: 2
vanilla-loots:
minecraft:ender_pearl_flower_seed_from_endermite:
minecraft:ender_pearl_flower_seeds_from_endermite:
type: entity
target: "minecraft:endermite"
override: false
@@ -287,4 +293,4 @@ vanilla-loots:
- 1
entries:
- type: item
item: "default:ender_pearl_flower_seed"
item: "default:ender_pearl_flower_seeds"

View File

@@ -0,0 +1,43 @@
{
"ambientocclusion": false,
"textures": {
"1": "item/ender_pearl",
"particle": "block/custom/ender_pearl_flower_stage_3",
"cross": "block/custom/ender_pearl_flower_stage_3"
},
"elements": [
{
"from": [0.8, 0, 8],
"to": [15.2, 16, 8],
"shade": false,
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8], "rescale": true},
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#cross"},
"south": {"uv": [0, 0, 16, 16], "texture": "#cross"}
}
},
{
"from": [8, 0, 0.8],
"to": [8, 16, 15.2],
"shade": false,
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8], "rescale": true},
"faces": {
"east": {"uv": [0, 0, 16, 16], "texture": "#cross"},
"west": {"uv": [0, 0, 16, 16], "texture": "#cross"}
}
},
{
"from": [8, 5, -1],
"to": [8, 21, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 5, 7]},
"faces": {
"north": {"uv": [0, 0, 0, 16], "texture": "#1"},
"east": {"uv": [0, 0, 16, 16], "texture": "#1"},
"south": {"uv": [0, 0, 0, 16], "texture": "#1"},
"west": {"uv": [0, 0, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 0, 16], "texture": "#1"},
"down": {"uv": [0, 0, 0, 16], "texture": "#1"}
}
}
]
}

View File

@@ -34,46 +34,16 @@ public class CropBlockBehavior extends BushBlockBehavior {
this.minGrowLight = minGrowLight;
}
public final boolean isMaxAge(Object state) {
return this.getAge(state) >= this.ageProperty.max;
}
public final boolean isMaxAge(ImmutableBlockState state) {
return this.getAge(state) >= this.ageProperty.max;
}
public static ImmutableBlockState getCEBlockState(Object nmsState) {
return BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(nmsState));
}
public final int getAge(Object state) {
return getCEBlockState(state).get(ageProperty);
}
public final int getAge(ImmutableBlockState state) {
return state.get(ageProperty);
}
public Object getStateForAge(Object state, int age) {
ImmutableBlockState afterState = getCEBlockState(state).owner().value().defaultState().with(ageProperty, age);
return afterState.customBlockState().handle();
}
public void growCrops(Object level, Object pos, Object state) throws InvocationTargetException, IllegalAccessException {
int i = this.getAge(state) + RandomUtils.generateRandomInt(2, 5);
int maxAge = this.ageProperty.max;
if (i > maxAge) {
i = maxAge;
}
Reflections.method$Level$setBlock.invoke(level, pos, getStateForAge(state, i), UpdateOption.UPDATE_NONE.flags());
}
private static int getRawBrightness(Object level, Object pos) throws InvocationTargetException, IllegalAccessException {
return (int) Reflections.method$BlockAndTintGetter$getRawBrightness.invoke(level, pos, 0);
}
private boolean hasSufficientLight(Object level, Object pos) throws InvocationTargetException, IllegalAccessException {
return getRawBrightness(level, pos) >= minGrowLight - 1;
return getRawBrightness(level, pos) >= this.minGrowLight - 1;
}
@Override
@@ -81,11 +51,13 @@ public class CropBlockBehavior extends BushBlockBehavior {
Object state = args[0];
Object level = args[1];
Object pos = args[2];
if (getRawBrightness(level, pos) >= minGrowLight) {
int age = this.getAge(state);
float randomFloat = RandomUtils.generateRandomFloat(0, 1);
if (age < this.ageProperty.max && randomFloat < 1.0 / Math.floor(25.0 / this.growSpeed + 1.0)) {
Reflections.method$Level$setBlock.invoke(level, pos, getStateForAge(state, age + 1), UpdateOption.UPDATE_ALL.flags());
if (getRawBrightness(level, pos) >= this.minGrowLight) {
ImmutableBlockState currentState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(state));
if (currentState != null && !currentState.isEmpty()) {
int age = this.getAge(currentState);
if (age < this.ageProperty.max && RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) {
Reflections.method$Level$setBlock.invoke(level, pos, currentState.with(this.ageProperty, age + 1).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
}
}
}
}
@@ -103,12 +75,30 @@ public class CropBlockBehavior extends BushBlockBehavior {
@Override
public boolean isValidBoneMealTarget(Object thisBlock, Object[] args) {
Object state = args[2];
return !this.isMaxAge(state);
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(state));
if (immutableBlockState != null && !immutableBlockState.isEmpty()) {
return getAge(immutableBlockState) != this.ageProperty.max;
} else {
return false;
}
}
@Override
public void performBoneMeal(Object thisBlock, Object[] args) throws Exception {
this.growCrops(args[0], args[2], args[3]);
this.performBoneMeal(args[0], args[2], args[3]);
}
private void performBoneMeal(Object level, Object pos, Object state) throws InvocationTargetException, IllegalAccessException {
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(state));
if (immutableBlockState == null || immutableBlockState.isEmpty()) {
return;
}
int i = this.getAge(immutableBlockState) + RandomUtils.generateRandomInt(2, 5);
int maxAge = this.ageProperty.max;
if (i > maxAge) {
i = maxAge;
}
Reflections.method$Level$setBlock.invoke(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags());
}
public static class Factory implements BlockBehaviorFactory {
@@ -122,8 +112,8 @@ public class CropBlockBehavior extends BushBlockBehavior {
throw new IllegalArgumentException("age property not set for crop");
}
// 存活条件是最小生长亮度-1
int minGrowLight = MiscUtils.getAsInt(arguments.getOrDefault("min-grow-light", 9));
float growSpeed = MiscUtils.getAsFloat(arguments.getOrDefault("grow-speed", 1));
int minGrowLight = MiscUtils.getAsInt(arguments.getOrDefault("light-requirement", 9));
float growSpeed = MiscUtils.getAsFloat(arguments.getOrDefault("grow-speed", 0.25f));
return new CropBlockBehavior(tuple.left(), tuple.mid(), tuple.right(), ageProperty, growSpeed, minGrowLight);
}
}

View File

@@ -5,11 +5,12 @@ import net.momirealms.craftengine.core.plugin.config.ConfigManager;
import net.momirealms.craftengine.core.util.SectionPosUtils;
import net.momirealms.craftengine.core.world.CEWorld;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor;
public class BukkitCEWorld extends CEWorld {
public BukkitCEWorld(World world) {
super(world);
public BukkitCEWorld(World world, StorageAdaptor adaptor) {
super(world, adaptor);
}
@Override

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.world;
import net.momirealms.craftengine.bukkit.compatibility.slimeworld.SlimeFormatStorageAdaptor;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector;
@@ -8,6 +9,7 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.plugin.config.ConfigManager;
import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.CEWorld;
import net.momirealms.craftengine.core.world.ChunkPos;
import net.momirealms.craftengine.core.world.SectionPos;
@@ -15,6 +17,8 @@ import net.momirealms.craftengine.core.world.WorldManager;
import net.momirealms.craftengine.core.world.chunk.CEChunk;
import net.momirealms.craftengine.core.world.chunk.CESection;
import net.momirealms.craftengine.core.world.chunk.serialization.ChunkSerializer;
import net.momirealms.craftengine.core.world.chunk.storage.DefaultStorageAdaptor;
import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor;
import net.momirealms.sparrow.nbt.CompoundTag;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
@@ -27,6 +31,7 @@ import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.HashMap;
@@ -38,18 +43,34 @@ public class BukkitWorldManager implements WorldManager, Listener {
private static BukkitWorldManager instance;
private final BukkitCraftEngine plugin;
private final Map<UUID, CEWorld> worlds;
private CEWorld[] worldArray;
private CEWorld[] worldArray = new CEWorld[0];
private final ReentrantReadWriteLock worldMapLock = new ReentrantReadWriteLock();
private SchedulerTask tickTask;
// cache
private UUID lastVisitedUUID;
private CEWorld lastVisitedWorld;
private StorageAdaptor storageAdaptor;
public BukkitWorldManager(BukkitCraftEngine plugin) {
instance = this;
this.plugin = plugin;
this.worlds = new HashMap<>();
resetWorldArray();
if (VersionHelper.isVersionNewerThan1_21_4()) {
try {
Class.forName("com.infernalsuite.asp.api.AdvancedSlimePaperAPI");
SlimeFormatStorageAdaptor adaptor = new SlimeFormatStorageAdaptor(this);
this.storageAdaptor = adaptor;
Bukkit.getPluginManager().registerEvents(adaptor, plugin.bootstrap());
return;
} catch (ClassNotFoundException ignored) {
}
}
this.storageAdaptor = new DefaultStorageAdaptor();
}
@Override
public void setStorageAdaptor(@NotNull StorageAdaptor storageAdaptor) {
this.storageAdaptor = storageAdaptor;
}
public static BukkitWorldManager instance() {
@@ -95,7 +116,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
this.worldMapLock.writeLock().lock();
try {
for (World world : Bukkit.getWorlds()) {
CEWorld ceWorld = new BukkitCEWorld(new BukkitWorld(world));
CEWorld ceWorld = new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor);
this.worlds.put(world.getUID(), ceWorld);
this.resetWorldArray();
for (Chunk chunk : world.getLoadedChunks()) {
@@ -110,8 +131,11 @@ public class BukkitWorldManager implements WorldManager, Listener {
@Override
public void disable() {
HandlerList.unregisterAll(this);
if (tickTask != null && !tickTask.cancelled()) {
tickTask.cancel();
if (this.storageAdaptor instanceof Listener listener) {
HandlerList.unregisterAll(listener);
}
if (this.tickTask != null && !this.tickTask.cancelled()) {
this.tickTask.cancel();
}
for (World world : Bukkit.getWorlds()) {
@@ -125,14 +149,18 @@ public class BukkitWorldManager implements WorldManager, Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onWorldLoad(WorldLoadEvent event) {
World world = event.getWorld();
CEWorld ceWorld = new BukkitCEWorld(new BukkitWorld(world));
this.loadWorld(new BukkitWorld(event.getWorld()));
}
@Override
public void loadWorld(net.momirealms.craftengine.core.world.World world) {
this.worldMapLock.writeLock().lock();
try {
if (this.worlds.containsKey(world.getUID())) return;
this.worlds.put(event.getWorld().getUID(), ceWorld);
if (this.worlds.containsKey(world.uuid())) return;
CEWorld ceWorld = new BukkitCEWorld(world, this.storageAdaptor);
this.worlds.put(world.uuid(), ceWorld);
this.resetWorldArray();
for (Chunk chunk : world.getLoadedChunks()) {
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
handleChunkLoad(ceWorld, chunk);
}
} finally {
@@ -142,11 +170,15 @@ public class BukkitWorldManager implements WorldManager, Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onWorldUnload(WorldUnloadEvent event) {
World world = event.getWorld();
unloadWorld(new BukkitWorld(event.getWorld()));
}
@Override
public void unloadWorld(net.momirealms.craftengine.core.world.World world) {
CEWorld ceWorld;
this.worldMapLock.writeLock().lock();
try {
ceWorld = this.worlds.remove(world.getUID());
ceWorld = this.worlds.remove(world.uuid());
if (ceWorld == null) {
return;
}
@@ -158,11 +190,20 @@ public class BukkitWorldManager implements WorldManager, Listener {
} finally {
this.worldMapLock.writeLock().unlock();
}
for (Chunk chunk : world.getLoadedChunks()) {
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
handleChunkUnload(ceWorld, chunk);
}
}
@Override
public <T> net.momirealms.craftengine.core.world.World wrap(T world) {
if (world instanceof World w) {
return new BukkitWorld(w);
} else {
throw new IllegalArgumentException(world.getClass() + " is not a Bukkit World");
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onChunkLoad(ChunkLoadEvent event) {
this.worldMapLock.readLock().lock();

View File

@@ -286,8 +286,6 @@ public abstract class AbstractPackManager implements PackManager {
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/netherite_anvil_top.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/solid_gunpowder_block.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/gunpowder_block.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/flame_cane_1.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/flame_cane_2.png");
// items
plugin.saveResource("resources/default/configuration/items.yml");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/topaz_rod.png");
@@ -302,7 +300,6 @@ public abstract class AbstractPackManager implements PackManager {
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/topaz_crossbow_pulling_1.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/topaz_crossbow_pulling_2.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/topaz_crossbow.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/flame_cane.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/entity/equipment/humanoid/topaz.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/entity/equipment/humanoid_leggings/topaz.png");
for (String item : List.of("helmet", "chestplate", "leggings", "boots", "pickaxe", "axe", "sword", "hoe", "shovel")) {
@@ -334,8 +331,15 @@ public abstract class AbstractPackManager implements PackManager {
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_3.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_4.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/reed.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/flame_cane_1.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/flame_cane_2.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/ender_pearl_flower_stage_0.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/ender_pearl_flower_stage_1.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/ender_pearl_flower_stage_2.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/fairy_flower.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/reed.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/flame_cane.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/ender_pearl_flower_seeds.png");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/fairy_flower_1.json");
plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/reed.json");
// furniture

View File

@@ -3,7 +3,7 @@ package net.momirealms.craftengine.core.world;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.world.chunk.CEChunk;
import net.momirealms.craftengine.core.world.chunk.storage.DefaultRegionFileStorage;
import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor;
import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage;
import org.jetbrains.annotations.Nullable;
@@ -25,10 +25,10 @@ public abstract class CEWorld {
private CEChunk lastChunk;
private long lastChunkPos;
public CEWorld(World world) {
public CEWorld(World world, StorageAdaptor adaptor) {
this.world = world;
this.loadedChunkMap = new Long2ObjectOpenHashMap<>(1024, 0.5f);
this.worldDataStorage = new DefaultRegionFileStorage(world.directory().resolve(REGION_DIRECTORY));
this.worldDataStorage = adaptor.adapt(world);
this.worldHeightAccessor = world.worldHeight();
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
}

View File

@@ -1,12 +1,22 @@
package net.momirealms.craftengine.core.world;
import net.momirealms.craftengine.core.plugin.Reloadable;
import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public interface WorldManager extends Reloadable {
void setStorageAdaptor(@NotNull StorageAdaptor storageAdaptor);
CEWorld getWorld(UUID uuid);
void delayedInit();
void loadWorld(World world);
void unloadWorld(World world);
<T> World wrap(T world);
}

View File

@@ -0,0 +1,13 @@
package net.momirealms.craftengine.core.world.chunk.storage;
import net.momirealms.craftengine.core.world.CEWorld;
import net.momirealms.craftengine.core.world.World;
import org.jetbrains.annotations.NotNull;
public class DefaultStorageAdaptor implements StorageAdaptor {
@Override
public @NotNull WorldDataStorage adapt(@NotNull World world) {
return new DefaultRegionFileStorage(world.directory().resolve(CEWorld.REGION_DIRECTORY));
}
}

View File

@@ -0,0 +1,10 @@
package net.momirealms.craftengine.core.world.chunk.storage;
import net.momirealms.craftengine.core.world.World;
import org.jetbrains.annotations.NotNull;
public interface StorageAdaptor {
@NotNull
WorldDataStorage adapt(@NotNull World world);
}

View File

@@ -40,7 +40,7 @@ geantyref_version=1.3.16
zstd_version=1.5.6-9
commons_io_version=2.17.0
sparrow_nbt_version=0.3
sparrow_util_version=0.33
sparrow_util_version=0.34
fastutil_version=8.5.15
netty_version=4.1.119.Final
joml_version=1.10.8