mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 00:30:20 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 942a8c9c8b | |||
| 414dcdae3e | |||
| 1195a6676f | |||
| 5501f53056 | |||
| 41d6e1c648 | |||
| 5ac7257517 | |||
| 9f4f9702a6 | |||
| 01d169256e | |||
| 7a703ad091 | |||
| ce9273c7e8 | |||
| 653a414ac1 | |||
| 2080db21ca | |||
| 8a933609ee | |||
| ba4a50e234 | |||
| f8e8ce8bc2 | |||
| 0013d4e682 | |||
| 9a97f1178d | |||
| e6a551d84d | |||
| 92921430d8 | |||
| 20c905aae4 | |||
| ec0730ef73 | |||
| e4576b3405 | |||
| c5800970a8 | |||
| 8f88b1c156 |
+2
-2
@@ -1,6 +1,6 @@
|
||||
import com.dfsek.terra.getGitHash
|
||||
|
||||
val versionObj = Version("5", "1", "0", true)
|
||||
val versionObj = Version("5", "1", "3", true)
|
||||
|
||||
allprojects {
|
||||
version = versionObj
|
||||
@@ -18,4 +18,4 @@ class Version(val major: String, val minor: String, val revision: String, val pr
|
||||
else //Only use git hash if it's a prerelease.
|
||||
"$major.$minor.$revision-BETA+${getGitHash()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@ fun Project.configureDependencies() {
|
||||
|
||||
dependencies {
|
||||
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||
"testImplementation"("org.yaml:snakeyaml:1.27")
|
||||
"testImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||
"testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
||||
}
|
||||
}
|
||||
@@ -62,8 +62,14 @@ fun Project.configureDistribution() {
|
||||
archiveClassifier.set("shaded")
|
||||
setVersion(project.version)
|
||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||
relocate("parsii", "com.dfsek.terra.lib.parsii")
|
||||
relocate("net.jafama", "com.dfsek.terra.lib.jafama")
|
||||
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
|
||||
relocate("com.google.errorprone", "com.dfsek.terra.lib.google.errorprone")
|
||||
relocate("com.google.j2objc", "com.dfsek.terra.lib.google.j2objc")
|
||||
relocate("org.checkerframework", "com.dfsek.terra.lib.checkerframework")
|
||||
relocate("org.javax.annotation", "com.dfsek.terra.lib.javax.annotation")
|
||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||
minimize()
|
||||
}
|
||||
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
|
||||
|
||||
@@ -20,7 +20,8 @@ dependencies {
|
||||
"shadedApi"("org.ow2.asm:asm:9.0")
|
||||
"shadedApi"("commons-io:commons-io:2.6")
|
||||
|
||||
"compileOnly"("com.googlecode.json-simple:json-simple:1.1")
|
||||
"shadedApi"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
"shadedApi"("org.yaml:snakeyaml:1.27")
|
||||
|
||||
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.dfsek.terra.api.event.events;
|
||||
|
||||
import com.dfsek.terra.api.util.mutable.MutableBoolean;
|
||||
|
||||
/**
|
||||
* Abstract class containing basic {@link Cancellable} implementation.
|
||||
*/
|
||||
public abstract class AbstractCancellable implements Cancellable {
|
||||
private final MutableBoolean cancelled = new MutableBoolean(false);
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled.set(cancelled);
|
||||
}
|
||||
}
|
||||
+9
-4
@@ -1,6 +1,5 @@
|
||||
package com.dfsek.terra.api.event.events.world;
|
||||
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.config.pack.WorldConfig;
|
||||
@@ -9,18 +8,24 @@ import com.dfsek.terra.world.TerraWorld;
|
||||
/**
|
||||
* Called upon initialization of a TerraWorld.
|
||||
*/
|
||||
public class TerraWorldLoadEvent implements Event {
|
||||
public class TerraWorldLoadEvent implements PackEvent {
|
||||
private final TerraWorld world;
|
||||
private final ConfigPack pack;
|
||||
|
||||
public TerraWorldLoadEvent(TerraWorld world) {
|
||||
public TerraWorldLoadEvent(TerraWorld world, ConfigPack pack) {
|
||||
this.world = world;
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
public TerraWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public WorldConfig getPack() {
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
public WorldConfig getWorldConfig() {
|
||||
return world.getConfig();
|
||||
}
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.dfsek.terra.api.event.events.world.generation;
|
||||
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.entity.Entity;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedEntity;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
|
||||
/**
|
||||
* Called when an entity is spawned via {@link BufferedEntity}.
|
||||
*/
|
||||
public class EntitySpawnEvent implements PackEvent {
|
||||
private final ConfigPack pack;
|
||||
private final Entity entity;
|
||||
private final Location location;
|
||||
|
||||
public EntitySpawnEvent(ConfigPack pack, Entity entity, Location location) {
|
||||
this.pack = pack;
|
||||
this.entity = entity;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity that triggered the event.
|
||||
*
|
||||
* @return The entity.
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of the entity.
|
||||
*
|
||||
* @return Location of the entity.
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.dfsek.terra.api.event.events.world.generation;
|
||||
|
||||
import com.dfsek.terra.api.event.events.AbstractCancellable;
|
||||
import com.dfsek.terra.api.event.events.Cancellable;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
import com.dfsek.terra.api.platform.block.Block;
|
||||
import com.dfsek.terra.api.platform.block.state.Container;
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
|
||||
import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when loot is populated via {@link BufferedLootApplication}.
|
||||
*/
|
||||
public class LootPopulateEvent extends AbstractCancellable implements PackEvent, Cancellable {
|
||||
private final Block block;
|
||||
private final Container container;
|
||||
private LootTable table;
|
||||
private final ConfigPack pack;
|
||||
private final StructureScript script;
|
||||
|
||||
public LootPopulateEvent(Block block, Container container, LootTable table, ConfigPack pack, StructureScript script) {
|
||||
this.block = block;
|
||||
this.container = container;
|
||||
this.table = table;
|
||||
this.pack = pack;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block containing the tile entity loot is applied to.
|
||||
*
|
||||
* @return Block at which loot is applied.
|
||||
*/
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Container} representing the inventory.
|
||||
*
|
||||
* @return Inventory recieving loot.
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the loot table to be populated.
|
||||
* @return Loot table.
|
||||
*/
|
||||
public LootTable getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the loot table to be populated.
|
||||
*
|
||||
* @param table New loot table.
|
||||
*/
|
||||
public void setTable(@NotNull LootTable table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script used to generate the structure.
|
||||
*
|
||||
* @return Structure script.
|
||||
*/
|
||||
public StructureScript getStructureScript() {
|
||||
return script;
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class StructureScript {
|
||||
.registerFunction("setMark", new SetMarkFunctionBuilder())
|
||||
.registerFunction("getMark", new GetMarkFunctionBuilder())
|
||||
.registerFunction("pull", new PullFunctionBuilder(main))
|
||||
.registerFunction("loot", new LootFunctionBuilder(main, lootRegistry))
|
||||
.registerFunction("loot", new LootFunctionBuilder(main, lootRegistry, this))
|
||||
.registerFunction("entity", new EntityFunctionBuilder(main))
|
||||
.registerFunction("getBiome", new BiomeFunctionBuilder(main))
|
||||
.registerFunction("getBlock", new CheckBlockFunctionBuilder())
|
||||
|
||||
+5
-2
@@ -3,6 +3,7 @@ package com.dfsek.terra.api.structures.script.builders;
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.structures.script.functions.LootFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.registry.config.LootRegistry;
|
||||
@@ -12,16 +13,18 @@ import java.util.List;
|
||||
public class LootFunctionBuilder implements FunctionBuilder<LootFunction> {
|
||||
private final TerraPlugin main;
|
||||
private final LootRegistry registry;
|
||||
private final StructureScript script;
|
||||
|
||||
public LootFunctionBuilder(TerraPlugin main, LootRegistry registry) {
|
||||
public LootFunctionBuilder(TerraPlugin main, LootRegistry registry, StructureScript script) {
|
||||
this.main = main;
|
||||
this.registry = registry;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public LootFunction build(List<Returnable<?>> argumentList, Position position) {
|
||||
return new LootFunction(registry, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), main, position);
|
||||
return new LootFunction(registry, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), main, position, script);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-1
@@ -21,9 +21,11 @@ public class EntityFunction implements Function<Void> {
|
||||
private final EntityType data;
|
||||
private final Returnable<Number> x, y, z;
|
||||
private final Position position;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public EntityFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) throws ParseException {
|
||||
this.position = position;
|
||||
this.main = main;
|
||||
if(!(data instanceof ConstantExpression)) throw new ParseException("Entity data must be constant", data.getPosition());
|
||||
|
||||
this.data = main.getWorldHandle().getEntity(((ConstantExpression<String>) data).getConstant());
|
||||
@@ -39,7 +41,7 @@ public class EntityFunction implements Function<Void> {
|
||||
|
||||
RotationUtil.rotateVector(xz, arguments.getRotation());
|
||||
|
||||
arguments.getBuffer().addItem(new BufferedEntity(data), new Vector3(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ()).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
arguments.getBuffer().addItem(new BufferedEntity(data, main), new Vector3(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ()).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -8,6 +8,7 @@ import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.Function;
|
||||
import com.dfsek.terra.api.structures.parser.lang.variables.Variable;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
|
||||
@@ -23,8 +24,9 @@ public class LootFunction implements Function<Void> {
|
||||
private final Returnable<Number> x, y, z;
|
||||
private final Position position;
|
||||
private final TerraPlugin main;
|
||||
private final StructureScript script;
|
||||
|
||||
public LootFunction(LootRegistry registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) {
|
||||
public LootFunction(LootRegistry registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position, StructureScript script) {
|
||||
this.registry = registry;
|
||||
this.position = position;
|
||||
this.data = data;
|
||||
@@ -32,6 +34,7 @@ public class LootFunction implements Function<Void> {
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.main = main;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +52,7 @@ public class LootFunction implements Function<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
arguments.getBuffer().addItem(new BufferedLootApplication(table, main), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
arguments.getBuffer().addItem(new BufferedLootApplication(table, main, script), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld()));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -1,18 +1,24 @@
|
||||
package com.dfsek.terra.api.structures.structure.buffer.items;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.event.events.world.generation.EntitySpawnEvent;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.entity.Entity;
|
||||
import com.dfsek.terra.api.platform.entity.EntityType;
|
||||
|
||||
public class BufferedEntity implements BufferedItem {
|
||||
|
||||
private final EntityType type;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public BufferedEntity(EntityType type) {
|
||||
public BufferedEntity(EntityType type, TerraPlugin main) {
|
||||
this.type = type;
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
origin.clone().add(0.5, 0, 0.5).getWorld().spawnEntity(origin, type);
|
||||
Entity entity = origin.clone().add(0.5, 0, 0.5).getWorld().spawnEntity(origin, type);
|
||||
main.getEventManager().callEvent(new EntitySpawnEvent(main.getWorld(entity.getWorld()).getGenerator().getConfigPack(), entity, entity.getLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
+14
-3
@@ -1,31 +1,42 @@
|
||||
package com.dfsek.terra.api.structures.structure.buffer.items;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.event.events.world.generation.LootPopulateEvent;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.block.Block;
|
||||
import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
import com.dfsek.terra.api.platform.block.state.Container;
|
||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.util.FastRandom;
|
||||
|
||||
public class BufferedLootApplication implements BufferedItem {
|
||||
private final LootTable table;
|
||||
private final TerraPlugin main;
|
||||
private final StructureScript structure;
|
||||
|
||||
public BufferedLootApplication(LootTable table, TerraPlugin main) {
|
||||
public BufferedLootApplication(LootTable table, TerraPlugin main, StructureScript structure) {
|
||||
this.table = table;
|
||||
this.main = main;
|
||||
this.structure = structure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
try {
|
||||
BlockState data = origin.getBlock().getState();
|
||||
Block block = origin.getBlock();
|
||||
BlockState data = block.getState();
|
||||
if(!(data instanceof Container)) {
|
||||
main.logger().severe("Failed to place loot at " + origin + "; block " + data + " is not container.");
|
||||
return;
|
||||
}
|
||||
Container container = (Container) data;
|
||||
table.fillInventory(container.getInventory(), new FastRandom(origin.hashCode()));
|
||||
|
||||
LootPopulateEvent event = new LootPopulateEvent(block, container, table, main.getWorld(block.getLocation().getWorld()).getGenerator().getConfigPack(), structure);
|
||||
main.getEventManager().callEvent(event);
|
||||
if(event.isCancelled()) return;
|
||||
|
||||
event.getTable().fillInventory(container.getInventory(), new FastRandom(origin.hashCode()));
|
||||
data.update(false);
|
||||
} catch(Exception e) {
|
||||
main.logger().warning("Could not apply loot at " + origin + ": " + e.getMessage());
|
||||
|
||||
@@ -5,6 +5,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class MutableBoolean implements MutablePrimitive<Boolean> {
|
||||
private boolean value;
|
||||
|
||||
public MutableBoolean() {
|
||||
this.value = false;
|
||||
}
|
||||
|
||||
public MutableBoolean(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean get() {
|
||||
return value;
|
||||
|
||||
@@ -139,6 +139,7 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
selfLoader.load(packPostTemplate, new FileInputStream(pack));
|
||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||
checkDeadEntries(main);
|
||||
} catch(FileNotFoundException e) {
|
||||
throw new LoadException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
||||
}
|
||||
@@ -183,6 +184,7 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
selfLoader.load(packPostTemplate, file.getInputStream(pack));
|
||||
biomeProviderBuilder = packPostTemplate.getProviderBuilder();
|
||||
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
|
||||
checkDeadEntries(main);
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Unable to load pack.yml from ZIP file", e);
|
||||
}
|
||||
@@ -198,6 +200,16 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main));
|
||||
}
|
||||
|
||||
private void checkDeadEntries(TerraPlugin main) {
|
||||
biomeRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in biome registry: '" + id + "'"));
|
||||
paletteRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in palette registry: '" + id + "'"));
|
||||
floraRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in flora registry: '" + id + "'"));
|
||||
carverRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in carver registry: '" + id + "'"));
|
||||
treeRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in tree registry: '" + id + "'"));
|
||||
oreRegistry.getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in ore registry: '" + id + "'"));
|
||||
}
|
||||
|
||||
|
||||
private void load(long start, TerraPlugin main) throws ConfigException {
|
||||
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this));
|
||||
|
||||
|
||||
@@ -7,18 +7,19 @@ import com.dfsek.terra.registry.exception.DuplicateEntryException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Registry implementation with read/write access. For internal use only.
|
||||
* @param <T>
|
||||
*/
|
||||
public class OpenRegistry<T> implements Registry<T> {
|
||||
private final Map<String, T> objects = new HashMap<>();
|
||||
private final Map<String, Entry<T>> objects = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public T load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||
@@ -35,6 +36,10 @@ public class OpenRegistry<T> implements Registry<T> {
|
||||
* @param value Value to add.
|
||||
*/
|
||||
public boolean add(String identifier, T value) {
|
||||
return add(identifier, new Entry<>(value));
|
||||
}
|
||||
|
||||
protected boolean add(String identifier, Entry<T> value) {
|
||||
boolean exists = objects.containsKey(identifier);
|
||||
objects.put(identifier, value);
|
||||
return exists;
|
||||
@@ -60,22 +65,22 @@ public class OpenRegistry<T> implements Registry<T> {
|
||||
|
||||
@Override
|
||||
public T get(String identifier) {
|
||||
return objects.get(identifier);
|
||||
return objects.get(identifier).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<T> consumer) {
|
||||
objects.forEach((id, obj) -> consumer.accept(obj));
|
||||
objects.forEach((id, obj) -> consumer.accept(obj.getRaw()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<String, T> consumer) {
|
||||
objects.forEach(consumer);
|
||||
objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> entries() {
|
||||
return new HashSet<>(objects.values());
|
||||
return objects.values().stream().map(Entry::getRaw).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,10 +88,41 @@ public class OpenRegistry<T> implements Registry<T> {
|
||||
return objects.keySet();
|
||||
}
|
||||
|
||||
public Map<String, T> getDeadEntries() {
|
||||
Map<String, T> dead = new HashMap<>();
|
||||
objects.forEach((id, entry) -> {
|
||||
if(entry.dead()) dead.put(id, entry.value); // dont increment value here.
|
||||
});
|
||||
return dead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all entries from the registry.
|
||||
*/
|
||||
public void clear() {
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
|
||||
protected static final class Entry<T> {
|
||||
private final T value;
|
||||
private final AtomicInteger access = new AtomicInteger(0);
|
||||
|
||||
public Entry(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
access.incrementAndGet();
|
||||
return value;
|
||||
}
|
||||
|
||||
private T getRaw() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean dead() {
|
||||
return access.get() == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,9 @@ public class FloraRegistry extends OpenRegistry<Flora> {
|
||||
|
||||
private void addItem(String id, Callable<ConstantFlora> flora) {
|
||||
try {
|
||||
add(id, flora.call());
|
||||
Entry<Flora> entry = new Entry<>(flora.call());
|
||||
entry.getValue(); // Mark as not dead.
|
||||
add(id, entry);
|
||||
} catch(Exception e) {
|
||||
main.logger().warning("Failed to load Flora item: " + id + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class TerraWorld {
|
||||
this.provider = config.getProvider();
|
||||
profiler = new WorldProfiler(w);
|
||||
air = main.getWorldHandle().createBlockData("minecraft:air");
|
||||
main.getEventManager().callEvent(new TerraWorldLoadEvent(this));
|
||||
main.getEventManager().callEvent(new TerraWorldLoadEvent(this, c));
|
||||
safe = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class FloraPopulator implements TerraBlockPopulator {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("FloraTime")) {
|
||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||
if(tw.getConfig().getTemplate().disableFlora()) return;
|
||||
|
||||
if(!tw.isSafe()) return;
|
||||
BiomeProvider provider = tw.getBiomeProvider();
|
||||
|
||||
@@ -28,7 +28,7 @@ public class OrePopulator implements TerraBlockPopulator {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("OreTime")) {
|
||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||
if(tw.getConfig().getTemplate().disableOres()) return;
|
||||
|
||||
if(!tw.isSafe()) return;
|
||||
for(int cx = -1; cx <= 1; cx++) {
|
||||
|
||||
@@ -33,7 +33,7 @@ public class StructurePopulator implements TerraBlockPopulator, Chunkified {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("StructureTime")) {
|
||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||
if(tw.getConfig().getTemplate().disableStructures()) return;
|
||||
|
||||
int cx = (chunk.getX() << 4);
|
||||
int cz = (chunk.getZ() << 4);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class TreePopulator implements TerraBlockPopulator {
|
||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
try(ProfileFuture ignored = tw.getProfiler().measure("TreeTime")) {
|
||||
if(tw.getConfig().getTemplate().disableCarvers()) return;
|
||||
if(tw.getConfig().getTemplate().disableTrees()) return;
|
||||
|
||||
if(!tw.isSafe()) return;
|
||||
BiomeProvider provider = tw.getBiomeProvider();
|
||||
|
||||
@@ -16,19 +16,12 @@ configureCommon()
|
||||
group = "com.dfsek.terra.bukkit"
|
||||
|
||||
val mcVersion = "1.16.5"
|
||||
val testDir = "target/server/"
|
||||
val testDir = "target/server"
|
||||
val testMem = "3G"
|
||||
|
||||
val paperURL = "https://papermc.io/api/v1/paper/%version%/latest/download/"
|
||||
val purpurURL = "https://ci.pl3x.net/job/Purpur/lastSuccessfulBuild/artifact/final/purpurclip.jar"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("http://maven.enginehub.org/repo/") }
|
||||
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"shadedApi"(project(":common"))
|
||||
|
||||
@@ -39,17 +32,17 @@ dependencies {
|
||||
|
||||
"compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
|
||||
|
||||
"shadedImplementation"("com.google.guava:guava:30.0-jre")
|
||||
"shadedApi"("com.google.guava:guava:30.0-jre")
|
||||
}
|
||||
|
||||
val aikarsFlags = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
|
||||
val jvmFlags = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
|
||||
"-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch",
|
||||
"-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M",
|
||||
"-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4",
|
||||
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
|
||||
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
|
||||
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
|
||||
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear")
|
||||
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear", "-javaagent:paperclip.jar")
|
||||
|
||||
fun downloadPaperclip(url: String, dir: String) {
|
||||
val clip = URL(url.replace("%version%", mcVersion))
|
||||
@@ -160,7 +153,7 @@ task<JavaExec>(name = "runPaper") {
|
||||
}
|
||||
|
||||
main = "io.papermc.paperclip.Paperclip"
|
||||
jvmArgs = aikarsFlags
|
||||
jvmArgs = jvmFlags
|
||||
maxHeapSize = testMem
|
||||
minHeapSize = testMem
|
||||
//args = listOf("nogui")
|
||||
@@ -178,7 +171,7 @@ task<JavaExec>(name = "runPurpur") {
|
||||
}
|
||||
|
||||
main = "io.papermc.paperclip.Paperclip"
|
||||
jvmArgs = aikarsFlags
|
||||
jvmArgs = jvmFlags
|
||||
maxHeapSize = testMem
|
||||
minHeapSize = testMem
|
||||
//args = listOf("nogui")
|
||||
@@ -189,6 +182,7 @@ task<JavaExec>(name = "runPurpur") {
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("org.bstats.bukkit", "com.dfsek.terra.lib.bstats")
|
||||
relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib")
|
||||
relocate("com.google.common", "com.dfsek.terra.lib.google.common")
|
||||
}
|
||||
|
||||
publishing {
|
||||
|
||||
@@ -22,7 +22,9 @@ public class TerraListener implements EventListener {
|
||||
public void injectTrees(ConfigPackPreLoadEvent event) {
|
||||
for(TreeType value : TreeType.values()) {
|
||||
try {
|
||||
event.getPack().getTreeRegistry().add(BukkitAdapter.TREE_TRANSFORMER.translate(value), new BukkitTree(value, main));
|
||||
String id = BukkitAdapter.TREE_TRANSFORMER.translate(value);
|
||||
event.getPack().getTreeRegistry().add(id, new BukkitTree(value, main));
|
||||
event.getPack().getTreeRegistry().get(id); // Platform trees should never be marked "dead"
|
||||
} catch(DuplicateEntryException ignore) { // If another addon has already registered trees, do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import com.dfsek.terra.configureCommon
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import com.modrinth.minotaur.TaskModrinthUpload
|
||||
import net.fabricmc.loom.LoomGradleExtension
|
||||
import net.fabricmc.loom.task.RemapJarTask
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
id("fabric-loom").version("0.6-SNAPSHOT")
|
||||
id("com.modrinth.minotaur").version("1.1.0")
|
||||
}
|
||||
|
||||
configureCommon()
|
||||
@@ -19,8 +22,6 @@ group = "com.dfsek.terra.fabric"
|
||||
|
||||
dependencies {
|
||||
"shadedApi"(project(":common"))
|
||||
"shadedImplementation"("org.yaml:snakeyaml:1.27")
|
||||
"shadedImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
|
||||
"minecraft"("com.mojang:minecraft:1.16.5")
|
||||
"mappings"("net.fabricmc:yarn:1.16.5+build.5:v2")
|
||||
@@ -29,17 +30,12 @@ dependencies {
|
||||
"modImplementation"("net.fabricmc.fabric-api:fabric-api:0.31.0+1.16")
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||
}
|
||||
|
||||
|
||||
configure<LoomGradleExtension> {
|
||||
accessWidener("src/main/resources/terra.accesswidener")
|
||||
}
|
||||
|
||||
tasks.register<RemapJarTask>("remapShadedJar") {
|
||||
val remapped = tasks.register<RemapJarTask>("remapShadedJar") {
|
||||
group = "fabric"
|
||||
val shadowJar = tasks.getByName<ShadowJar>("shadowJar")
|
||||
dependsOn(shadowJar)
|
||||
@@ -48,3 +44,41 @@ tasks.register<RemapJarTask>("remapShadedJar") {
|
||||
addNestedDependencies.set(true)
|
||||
remapAccessWidener.set(true)
|
||||
}
|
||||
|
||||
|
||||
tasks.register<TaskModrinthUpload>("publishModrinth") {
|
||||
dependsOn("remapShadedJar")
|
||||
group = "fabric"
|
||||
token = System.getenv("MODRINTH_SECRET")
|
||||
projectId = "FIlZB9L0"
|
||||
versionNumber = project.version.toString()
|
||||
uploadFile = remapped.get().archiveFile.get().asFile
|
||||
releaseType = "beta"
|
||||
addGameVersion("1.16.4")
|
||||
addGameVersion("1.16.5")
|
||||
addLoader("fabric")
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
artifact(tasks["sourcesJar"])
|
||||
artifact(tasks["jar"])
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||
|
||||
maven(mavenUrl) {
|
||||
val mavenUsername: String? by project
|
||||
val mavenPassword: String? by project
|
||||
if (mavenUsername != null && mavenPassword != null) {
|
||||
credentials {
|
||||
username = mavenUsername
|
||||
password = mavenPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,12 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
});
|
||||
}
|
||||
|
||||
public TerraWorld getWorld(long seed) {
|
||||
TerraWorld world = worldMap.get(seed);
|
||||
if(world == null) throw new IllegalArgumentException("No world exists with seed " + seed);
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger logger() {
|
||||
return logger;
|
||||
@@ -242,10 +248,6 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
}
|
||||
|
||||
private Biome createBiome(BiomeBuilder biome) {
|
||||
SpawnSettings.Builder spawnSettings = new SpawnSettings.Builder();
|
||||
DefaultBiomeFeatures.addFarmAnimals(spawnSettings);
|
||||
DefaultBiomeFeatures.addMonsters(spawnSettings, 95, 5, 100);
|
||||
|
||||
BiomeTemplate template = biome.getTemplate();
|
||||
Map<String, Integer> colors = template.getColors();
|
||||
|
||||
@@ -283,7 +285,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
.temperature(vanilla.getTemperature())
|
||||
.downfall(vanilla.getDownfall())
|
||||
.effects(effects.build())
|
||||
.spawnSettings(spawnSettings.build())
|
||||
.spawnSettings(vanilla.getSpawnSettings())
|
||||
.generationSettings(generationSettings.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
import com.dfsek.terra.fabric.world.FabricAdapter;
|
||||
import com.dfsek.terra.fabric.world.block.state.FabricBlockState;
|
||||
import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess;
|
||||
import net.minecraft.block.FluidBlock;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
@@ -21,7 +22,10 @@ public class FabricBlock implements Block {
|
||||
|
||||
@Override
|
||||
public void setBlockData(BlockData data, boolean physics) {
|
||||
delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042, 0);
|
||||
delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042);
|
||||
if(physics && ((FabricBlockData) data).getHandle().getBlock() instanceof FluidBlock) {
|
||||
delegate.worldAccess.getFluidTickScheduler().schedule(delegate.position, ((FluidBlock) ((FabricBlockData) data).getHandle().getBlock()).getFluidState(((FabricBlockData) data).getHandle()).getFluid(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+15
-1
@@ -7,7 +7,9 @@ import com.dfsek.terra.config.pack.ConfigPack;
|
||||
import com.dfsek.terra.fabric.TerraFabricPlugin;
|
||||
import com.dfsek.terra.fabric.world.TerraBiomeSource;
|
||||
import com.dfsek.terra.fabric.world.handles.world.FabricSeededWorldAccess;
|
||||
import com.dfsek.terra.world.TerraWorld;
|
||||
import com.dfsek.terra.world.generation.generators.DefaultChunkGenerator3D;
|
||||
import com.dfsek.terra.world.generation.math.samplers.Sampler;
|
||||
import com.dfsek.terra.world.population.CavePopulator;
|
||||
import com.dfsek.terra.world.population.FloraPopulator;
|
||||
import com.dfsek.terra.world.population.OrePopulator;
|
||||
@@ -15,6 +17,7 @@ import com.dfsek.terra.world.population.StructurePopulator;
|
||||
import com.dfsek.terra.world.population.TreePopulator;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.jafama.FastMath;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.structure.StructureManager;
|
||||
@@ -107,7 +110,18 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
||||
|
||||
@Override
|
||||
public int getHeight(int x, int z, Heightmap.Type heightmapType) {
|
||||
return 0;
|
||||
TerraWorld world = TerraFabricPlugin.getInstance().getWorld(seed);
|
||||
Sampler sampler = world.getConfig().getSamplerCache().getChunk(FastMath.floorDiv(x, 16), FastMath.floorDiv(z, 16));
|
||||
int cx = FastMath.floorMod(x, 16);
|
||||
int cz = FastMath.floorMod(z, 16);
|
||||
|
||||
int height = world.getWorld().getMaxHeight();
|
||||
|
||||
while (height >= 0 && sampler.sample(cx, height - 1, cz) < 0) {
|
||||
height--;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user