Compare commits
No commits in common. "develop" and "master" have entirely different histories.
11
.devcontainer/Dockerfile
Normal file
11
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM mcr.microsoft.com/devcontainers/anaconda:1-3
|
||||
|
||||
# Copy environment.yml (if found) to a temp location so we update the environment. Also
|
||||
# copy "noop.txt" so the COPY instruction does not fail if no environment.yml exists.
|
||||
COPY environment.yml* .devcontainer/noop.txt /tmp/conda-tmp/
|
||||
RUN if [ -f "/tmp/conda-tmp/environment.yml" ]; then umask 0002 && /opt/conda/bin/conda env update -n base -f /tmp/conda-tmp/environment.yml; fi \
|
||||
&& rm -rf /tmp/conda-tmp
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
@ -1,31 +1,31 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/java
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/anaconda
|
||||
{
|
||||
"name": "Java",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"image": "mcr.microsoft.com/devcontainers/java:1-11-bullseye",
|
||||
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/java:1": {
|
||||
"version": "none",
|
||||
"installMaven": "true",
|
||||
"installGradle": "true"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/powershell:1": {}
|
||||
"name": "Anaconda (Python 3)",
|
||||
"build": {
|
||||
"context": "..",
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"vscjava.vscode-java-pack"
|
||||
"vscjava.vscode-java-test",
|
||||
"vscjava.vscode-java-dependency",
|
||||
"vscjava.vscode-maven",
|
||||
"redhat.java",
|
||||
"vscjava.vscode-java-debug"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "java -version",
|
||||
// "postCreateCommand": "python --version",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
3
.devcontainer/noop.txt
Normal file
3
.devcontainer/noop.txt
Normal file
@ -0,0 +1,3 @@
|
||||
This file copied into the container along with environment.yml* from the parent
|
||||
folder. This file is included to prevents the Dockerfile COPY instruction from
|
||||
failing if no environment.yml is found.
|
30
.vscode/launch.json
vendored
30
.vscode/launch.json
vendored
@ -1,30 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "java",
|
||||
"request": "attach",
|
||||
"name": "Attach by Process ID",
|
||||
"processId": "${command:PickJavaProcess}"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Debug (Launch) - Current File",
|
||||
"request": "launch",
|
||||
"mainClass": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Debug With MC Server",
|
||||
"request": "attach",
|
||||
"hostName": "localhost",
|
||||
"port": 25566,
|
||||
"sourcePaths": [
|
||||
"src/main/java"
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@ -1,10 +1,3 @@
|
||||
{
|
||||
"java.configuration.updateBuildConfiguration": "automatic",
|
||||
"cSpell.words": [
|
||||
"Bukkit",
|
||||
"islandsurvivalcraft",
|
||||
"Minecraft",
|
||||
"QUICKBAR"
|
||||
],
|
||||
"java.compile.nullAnalysis.mode": "automatic"
|
||||
"java.configuration.updateBuildConfiguration": "automatic"
|
||||
}
|
86
.vscode/tasks.json
vendored
86
.vscode/tasks.json
vendored
@ -1,86 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "verify",
|
||||
"type": "shell",
|
||||
"command": "mvn -B verify",
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "test",
|
||||
"type": "shell",
|
||||
"command": "mvn -B test",
|
||||
"group": "test"
|
||||
},
|
||||
{
|
||||
"label": "package",
|
||||
"type": "shell",
|
||||
"command": "mvn package -DskipTests",
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "delete server world",
|
||||
"type": "shell",
|
||||
"options": {"cwd": "${workspaceFolder}/test-server/"},
|
||||
"args": ["-ExecutionPolicy", "Bypass", "-File", "./delete_worlds.ps1"],
|
||||
"command": "pwsh",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"dependsOn": ["package"],
|
||||
"label": "load build",
|
||||
"type": "shell",
|
||||
"args": ["-ExecutionPolicy", "Bypass", "-File", "./load_build.ps1"],
|
||||
"options": {"cwd": "${workspaceFolder}/test-server/"},
|
||||
"command": "pwsh",
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"dependsOn": ["load build"],
|
||||
"label": "start test server",
|
||||
"type": "shell",
|
||||
"runOptions": {"instanceLimit": 1},
|
||||
"args": ["-ExecutionPolicy", "Bypass", "-File", "./start_process.ps1"],
|
||||
"options": {"cwd": "${workspaceFolder}/test-server/"},
|
||||
"command": "pwsh",
|
||||
"problemMatcher": [],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"clear": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "stop test server",
|
||||
"type": "shell",
|
||||
"args": ["-ExecutionPolicy", "Bypass", "-File", "./end_process.ps1"],
|
||||
"options": {"cwd": "${workspaceFolder}/test-server/"},
|
||||
"command": "pwsh",
|
||||
"problemMatcher": [],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
35
Jenkinsfile
vendored
35
Jenkinsfile
vendored
@ -1,35 +0,0 @@
|
||||
pipeline {
|
||||
agent {
|
||||
kubernetes {
|
||||
cloud 'Reslate Systems'
|
||||
defaultContainer 'conda'
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage ("Install") {
|
||||
steps {
|
||||
sh 'conda update conda -y -q'
|
||||
sh 'conda env update -n base --file environment.yml -q'
|
||||
sh "conda run -n base mvn validate"
|
||||
}
|
||||
}
|
||||
stage ("Build") {
|
||||
steps {
|
||||
sh "conda run -n base mvn compile"
|
||||
}
|
||||
}
|
||||
stage ("Test") {
|
||||
steps {
|
||||
sh "conda run -n base mvn -Dmaven.test.skip=false test"
|
||||
xunit checksName: '', tools: [JUnit(excludesPattern: '', pattern: 'target/surefire-reports/TEST-*.xml', stopProcessingIfError: true)]
|
||||
recordCoverage(tools: [[parser: 'JUNIT', pattern: 'target/surefire-reports/TEST-*.xml']])
|
||||
}
|
||||
}
|
||||
stage ("Package") {
|
||||
steps {
|
||||
sh "conda run -n base mvn package"
|
||||
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true, followSymlinks: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
name: islandsurvivalcraft
|
||||
channels:
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- openjdk=21
|
||||
- maven
|
57
pom.xml
57
pom.xml
@ -1,7 +1,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>net.reslate.islandsurvivalcraft</groupId>
|
||||
<groupId>ca.recrown.islandsurvivalcraft</groupId>
|
||||
<artifactId>IslandSurvivalCraft</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0</version>
|
||||
@ -9,56 +9,37 @@
|
||||
<url>http://maven.apache.org</url>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sk89q-repo</id>
|
||||
<url>https://maven.enginehub.org/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.6.2</version>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.6.2</version>
|
||||
<scope>test</scope>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.15.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.16.2-R0.1-SNAPSHOT</version>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<maven.compiler.release>11</maven.compiler.release>
|
||||
<maven.test.skip>true</maven.test.skip>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
</project>
|
@ -0,0 +1,21 @@
|
||||
package ca.recrown.islandsurvivalcraft;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
/**
|
||||
* Hello world!
|
||||
*
|
||||
*/
|
||||
public class IslandSurvivalCraftPlugin extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// TODO Auto-generated method stub
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// TODO Auto-generated method stub
|
||||
super.onDisable();
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.ServerLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.interaction.commands.CommandProcessor;
|
||||
import net.reslate.islandsurvivalcraft.interaction.items.ItemVariantManager;
|
||||
import net.reslate.islandsurvivalcraft.world.WorldInfoManager;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.GeneratorModes;
|
||||
|
||||
public class IslandSurvivalCraft extends JavaPlugin implements Listener {
|
||||
private PluginManager pluginManager;
|
||||
private WorldInfoManager worldInfoManager;
|
||||
private CommandProcessor commandProcessor;
|
||||
private ItemVariantManager variedItemManager;
|
||||
|
||||
public IslandSurvivalCraft() {
|
||||
worldInfoManager = new WorldInfoManager();
|
||||
variedItemManager = new ItemVariantManager(this);
|
||||
commandProcessor = new CommandProcessor(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
pluginManager = getServer().getPluginManager();
|
||||
pluginManager.registerEvents(worldInfoManager, this);
|
||||
pluginManager.registerEvents(variedItemManager, this);
|
||||
pluginManager.registerEvents(this, this);
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onReady(ServerLoadEvent e) {
|
||||
variedItemManager.loadAllItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
HandlerList.unregisterAll(worldInfoManager);
|
||||
HandlerList.unregisterAll(variedItemManager);
|
||||
HandlerList.unregisterAll((Listener) this);
|
||||
variedItemManager.unloadAllItems();
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
|
||||
GeneratorModes gID = null;
|
||||
try {
|
||||
gID = GeneratorModes.valueOf(id);
|
||||
} catch (NullPointerException | IllegalArgumentException e) {
|
||||
gID = GeneratorModes.UNIQUE;
|
||||
}
|
||||
return worldInfoManager.getChunkGenerator(worldName, gID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
return commandProcessor.onCommand(sender, command, label, args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the world information manager.
|
||||
*/
|
||||
public WorldInfoManager getWorldInfoManager() {
|
||||
return worldInfoManager;
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.commands;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
|
||||
public class CommandProcessor implements CommandExecutor {
|
||||
private IslandSurvivalCraft islandSurvivalCraft;
|
||||
|
||||
public CommandProcessor(IslandSurvivalCraft islandSurvivalCraft) {
|
||||
this.islandSurvivalCraft = islandSurvivalCraft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args.length < 1 || args[0].isEmpty()) return false;
|
||||
RegisteredCommands currentCommand = null;
|
||||
try {
|
||||
currentCommand = RegisteredCommands.valueOf(args[0].toUpperCase());
|
||||
if (currentCommand.getCommandRunnable().requiresInitialization()) currentCommand.getCommandRunnable().initialize(islandSurvivalCraft);
|
||||
String[] commandArguments = Arrays.copyOfRange(args, 1, args.length);
|
||||
boolean success = currentCommand.getCommandRunnable().invoke(sender, commandArguments);
|
||||
if (!success) {
|
||||
sender.sendMessage(String.format("The command arguments were incorrect. Please refer to \"/IslandSurvivalCraft help %s\" for help.", currentCommand.toString()));
|
||||
return false;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
sender.sendMessage(ChatColor.LIGHT_PURPLE + "This command was not understood. Refer to \"/IslandSurvivalCraft help\" for more info.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.commands;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.interaction.commands.runnables.IslandCommand;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.interaction.commands.runnables.*;
|
||||
|
||||
public enum RegisteredCommands {
|
||||
ISLAND(new IslandCommand()),
|
||||
HELP(new HelpCommand()),
|
||||
VALUE(new ValueCommand()),
|
||||
;
|
||||
|
||||
private final CommandRunnable commandRunnable;
|
||||
|
||||
private RegisteredCommands(CommandRunnable runnable) {
|
||||
this.commandRunnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the commandRunnable
|
||||
*/
|
||||
public CommandRunnable getCommandRunnable() {
|
||||
return commandRunnable;
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.commands.runnables;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
|
||||
public interface CommandRunnable {
|
||||
/**
|
||||
* @return a string that gives users an idea of what this command does. Should be short and not include details on arguments.
|
||||
*/
|
||||
public String getDescription();
|
||||
|
||||
/**
|
||||
* @return A more detailed description. Doesn't need to contain information already present in normal description as will print with that one. This string should describe proper usage arguments required.
|
||||
*/
|
||||
public String getDetailedDescription();
|
||||
|
||||
/**
|
||||
* Invokes this particular command.
|
||||
* Should check for correct arguments.
|
||||
* @param sender The sender of this command.
|
||||
* @param args The arguments given for this command. May be length of 0, in which case there were no arguments.
|
||||
* @return True if the execution of this command was a success, and false to display the help message for this command.
|
||||
*/
|
||||
public boolean invoke(CommandSender sender, String[] args);
|
||||
|
||||
/**
|
||||
* Initializes the command. Is run the first time this command is run.
|
||||
* @param islandSurvivalCraft
|
||||
*/
|
||||
public void initialize(IslandSurvivalCraft islandSurvivalCraft);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return True if on the next call, should initialize.
|
||||
*/
|
||||
public boolean requiresInitialization();
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.commands.runnables;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
import net.reslate.islandsurvivalcraft.interaction.commands.RegisteredCommands;
|
||||
|
||||
public class HelpCommand implements CommandRunnable {
|
||||
private String helpMessage;
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Displays these help messages.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean invoke(CommandSender sender, String[] args) {
|
||||
if (args == null || args.length == 0) {
|
||||
sender.sendMessage(helpMessage);
|
||||
return true;
|
||||
} else {
|
||||
RegisteredCommands command = null;
|
||||
try {
|
||||
command = RegisteredCommands.valueOf(args[0].toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(ChatColor.YELLOW + args[0]);
|
||||
sb.append(": " + ChatColor.GRAY);
|
||||
sb.append(command.getCommandRunnable().getDescription());
|
||||
sb.append("\n" + ChatColor.WHITE);
|
||||
sb.append(command.getCommandRunnable().getDetailedDescription());
|
||||
sender.sendMessage(sb.toString().trim());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(IslandSurvivalCraft islandSurvivalCraft) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
RegisteredCommands[] commands = RegisteredCommands.values();
|
||||
stringBuilder.append(ChatColor.YELLOW + "IslandSurvivalCraft Commands:\n");
|
||||
for (int i = 0; i < commands.length; i++) {
|
||||
stringBuilder.append(ChatColor.GREEN + commands[i].toString());
|
||||
stringBuilder.append(": " + ChatColor.WHITE);
|
||||
stringBuilder.append(commands[i].getCommandRunnable().getDescription());
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
helpMessage = stringBuilder.toString().trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetailedDescription() {
|
||||
return " \"islandsurvivalcraft help [command]\". Where [command] is a listed command, can optionally be added to get a detailed look at the command. Help is a command that lists all the other potential commands that may be run. Can also look at the detailed commands. But you knew this since your using help with help...";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresInitialization() {
|
||||
return helpMessage == null;
|
||||
}
|
||||
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.commands.runnables;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
import net.reslate.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.world.WorldInfo;
|
||||
import net.reslate.islandsurvivalcraft.world.Information.IslandInformation;
|
||||
|
||||
public class IslandCommand implements CommandRunnable {
|
||||
private IslandSurvivalCraft islandSurvivalCraft;
|
||||
private final Particle.DustOptions EDGE_DUST_OPTIONS = new Particle.DustOptions(Color.RED, 1f);
|
||||
private final Particle.DustOptions ORIGIN_DUST_OPTIONS = new Particle.DustOptions(Color.LIME, 1.5f);
|
||||
private final int PARTICLE_AMOUNT = 1;
|
||||
private final double OFFSET_X = 0.0d, OFFSET_Y = 6.0d, OFFSET_Z = 0.0d;
|
||||
private final double EXTRA = 0d;
|
||||
HashSet<Player> playersHighlighting = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Various debugging information about islands.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean invoke(CommandSender sender, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage("This command can only be run as a player!");
|
||||
return false;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
if (args.length == 0 || args[0].isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (args[0].toLowerCase().equals("highlight")) {
|
||||
if (playersHighlighting.add(player)) {
|
||||
sender.sendMessage("You are now highlighting islands.");
|
||||
} else {
|
||||
sender.sendMessage("You are already highlighting islands.");
|
||||
}
|
||||
} else if (args[0].toLowerCase().equals("stop")) {
|
||||
if (playersHighlighting.remove(player)) {
|
||||
sender.sendMessage("You are no longer highlighting islands.");
|
||||
} else {
|
||||
sender.sendMessage("You weren't highlighting islands.");
|
||||
}
|
||||
} else if (args[0].toLowerCase().equals("origin")) {
|
||||
Point2 playerLoc = new Point2(player.getLocation().getBlockX(), player.getLocation().getBlockZ());
|
||||
sender.sendMessage("Current island's origin point: " + islandSurvivalCraft.getWorldInfoManager().retrieve(player.getWorld().getName()).getIslandInfoManager().getIslandInformation(playerLoc, true).getIslandOrigin());
|
||||
} else if (args[0].toLowerCase().equals("size")) {
|
||||
Point2 playerLoc = new Point2(player.getLocation().getBlockX(), player.getLocation().getBlockZ());
|
||||
IslandInformation info = islandSurvivalCraft.getWorldInfoManager().retrieve(player.getWorld().getName()).getIslandInfoManager().getIslandInformation(playerLoc, true);
|
||||
if (info != null) {
|
||||
sender.sendMessage("Current island's raw size in blocks: " + info.getIslandSize());
|
||||
} else {
|
||||
sender.sendMessage("Current location is not an island!");
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(IslandSurvivalCraft islandsurvivalcraft) {
|
||||
this.islandSurvivalCraft = islandsurvivalcraft;
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(islandsurvivalcraft, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Player player : playersHighlighting) {
|
||||
if (player == null) continue;
|
||||
if (!player.isOnline()) {
|
||||
playersHighlighting.remove(player);
|
||||
continue;
|
||||
}
|
||||
World world = player.getWorld();
|
||||
WorldInfo worldInfo = islandsurvivalcraft.getWorldInfoManager().retrieve(world.getName());
|
||||
Location playerLocation = player.getLocation();
|
||||
double playerX = playerLocation.getX(), playerY = playerLocation.getY(), playerZ = playerLocation.getZ();
|
||||
Point2 playerCoords = new Point2(playerLocation.getBlockX(), playerLocation.getBlockZ());
|
||||
IslandInformation islandInfo = worldInfo.getIslandInfoManager().getIslandInformation(playerCoords, true);
|
||||
if (islandInfo != null) {
|
||||
Set<Point2> islandBorder = islandInfo.getEdgeCoordinates();
|
||||
for (Point2 current : islandBorder) {
|
||||
spawnParticle(false, true, world, current.x, playerY, current.y, EDGE_DUST_OPTIONS);
|
||||
}
|
||||
Point2 islandOrigin = islandInfo.getIslandOrigin();
|
||||
double xDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.x - playerCoords.x), -1), 1) + playerX;
|
||||
double yDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.y - playerCoords.y), -1), 1) + playerZ;
|
||||
spawnParticle(false, false, world, xDirection, playerY + 1, yDirection, ORIGIN_DUST_OPTIONS);
|
||||
spawnParticle(true, true, world, islandOrigin.x, playerY, islandOrigin.y, ORIGIN_DUST_OPTIONS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0, 10);
|
||||
|
||||
}
|
||||
|
||||
private void spawnParticle(boolean focus, boolean column, World world, double x, double y, double z, Particle.DustOptions dustOptions) {
|
||||
world.spawnParticle(Particle.REDSTONE, x, y, z, focus ? PARTICLE_AMOUNT * 2 : PARTICLE_AMOUNT, OFFSET_X, column ? OFFSET_Y : 0.2, OFFSET_Z, EXTRA, dustOptions, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetailedDescription() {
|
||||
return "Usage: \"island <arg>\". replacing <args> with \"highlight\" will start highlighting the island by " +
|
||||
"displaying red particles that indicate the islands border, and green particles indicate the origin. \"stop\" will stop the highlighting. " +
|
||||
"\"origin\" will print the current island's origin point. " +
|
||||
"\"size\" will print the raw island size in blocks including the shallow portions.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresInitialization() {
|
||||
return islandSurvivalCraft == null;
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.commands.runnables;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
|
||||
public class ValueCommand implements CommandRunnable {
|
||||
private IslandSurvivalCraft isc;
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Gives the world value this plugin is using.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetailedDescription() {
|
||||
return "Player only command. Usage: \"IslandSurvivalCraft value [x] [z]\". Gives the current world value at the given x and z coordinates. If the two coordinates are not provided, player location is used.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean invoke(CommandSender sender, String[] args) {
|
||||
if (!(sender instanceof Player)) return false;
|
||||
Player p = (Player) sender;
|
||||
int worldX = 0, worldZ = 0;
|
||||
if (args.length > 0) {
|
||||
if (args.length != 2) return false;
|
||||
try {
|
||||
worldX = Integer.valueOf(args[0]);
|
||||
worldZ = Integer.valueOf(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
worldX = p.getLocation().getBlockX();
|
||||
worldZ = p.getLocation().getBlockZ();
|
||||
|
||||
}
|
||||
|
||||
IslandWorldMap map = isc.getWorldInfoManager().retrieve(p.getWorld().getName()).getIslandMap();
|
||||
p.sendMessage(String.format("world: %s, World value (%d, %d): %s",
|
||||
p.getWorld().getName(),
|
||||
worldX, worldZ,
|
||||
map.getWorldValue(worldX, worldZ)));
|
||||
|
||||
p.sendMessage(String.format("Terrain: \nIsland: %b, Shallow: %b, Hill: %b, Land: %b, Shore: %b, Edge: %b, Transitional: %b, Deep: %b",
|
||||
map.isIsland(worldX, worldZ),
|
||||
map.isShallowPortion(worldX, worldZ),
|
||||
map.isHill(worldX, worldZ),
|
||||
map.isLand(worldX, worldZ),
|
||||
map.isShore(worldX, worldZ),
|
||||
map.isEdgeOfIsland(worldX, worldZ),
|
||||
map.isTransitional(worldX, worldZ),
|
||||
map.isDeep(worldX, worldZ)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(IslandSurvivalCraft islandSurvivalCraft) {
|
||||
isc = islandSurvivalCraft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresInitialization() {
|
||||
return isc == null;
|
||||
}
|
||||
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.items;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
|
||||
public interface ItemVariant {
|
||||
/**
|
||||
* Should be used to perform anything that need only be called once.
|
||||
* Is called only when the needInitialization() method returns true.
|
||||
* Is called after assigning identity.
|
||||
* @param islandSurvivalCraft The IslandSurvivalCraft plugin object that contains references to various managers that may be used.
|
||||
*/
|
||||
public void initialize(IslandSurvivalCraft islandSurvivalCraft);
|
||||
|
||||
/**
|
||||
* The recipe of the item variant. If null, these features will hook directly into the original map.
|
||||
* @return the recipe to be registered with bukkit.
|
||||
*/
|
||||
public Recipe getRecipe();
|
||||
|
||||
/**
|
||||
* @return a string representing the key name of the item.
|
||||
*/
|
||||
public String getItemName();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The material item this item is a variation of.
|
||||
*/
|
||||
public Material[] getBaseItems();
|
||||
|
||||
/**
|
||||
* Assigns a persistent metadata identifier.
|
||||
* This identifier should be saved to any itemstack that is considered this item.
|
||||
* @param identifier The identifier.
|
||||
*/
|
||||
public void assignIdentifier(ItemVariantIdentifier identifier);
|
||||
|
||||
|
||||
/**
|
||||
* Should give the identifier used identify this variation of the base item from the original.
|
||||
* This usually should just return the assigned identifier.
|
||||
* @return The identifier metadata.
|
||||
*/
|
||||
public ItemVariantIdentifier getIdentifier();
|
||||
|
||||
/**
|
||||
* If this item needs initializing.
|
||||
* If returning true, the initialize method will be called before being registered as a recipe.
|
||||
* @return True if the initialize method should be called.
|
||||
*/
|
||||
public boolean needInitialization();
|
||||
|
||||
/**
|
||||
* Called when this variety of the item is crafted.
|
||||
* @param item The resulting itemstack.
|
||||
* @param crafter The entity performing the crafting.
|
||||
* @param recipe The recipe used to craft this.
|
||||
* @return true if the remaining chain of events for this crafting should not occur. Otherwise, false.
|
||||
*/
|
||||
public boolean onItemCrafted(ItemStack item, HumanEntity crafter);
|
||||
|
||||
/**
|
||||
* Called when this item is right clicked with.
|
||||
* @param item The itemstack that was right clicked with.
|
||||
* @param clicker The player that did the clicking.
|
||||
* @param hand The hand that it was in.
|
||||
* @param block The block the item was right clicked on.
|
||||
* @param blockFace The face of the block that was clicked.
|
||||
* @return True if the vanilla chain of events should no longer run. False otherwise.
|
||||
*/
|
||||
public boolean onItemRightClicked(ItemStack item, HumanEntity clicker, EquipmentSlot hand, Block block, BlockFace blockFace);
|
||||
|
||||
/**
|
||||
* Called once when the player changes to holding the item.
|
||||
* @param heldItem The itemstack representing the held item.
|
||||
* @param holder The player holding the item.
|
||||
*/
|
||||
public void onItemHeld(ItemStack heldItem, HumanEntity holder);
|
||||
|
||||
/**
|
||||
* Called when this item is put away.
|
||||
* @param item The itemstack that was put away.
|
||||
* @param holder The player that put away the itemstack.
|
||||
*/
|
||||
public void onItemPutAway(ItemStack item, HumanEntity holder);
|
||||
|
||||
/**
|
||||
* Called when a player joins and called when player picks up this variation of the item.
|
||||
* Can be used to initialize any data the item doesn't save on server shutdown.
|
||||
* You may need to check if the item already has been instantiated.
|
||||
* @param item The itemstack that represents the item in question.
|
||||
*/
|
||||
public void initializeInstanceOfItem(ItemStack item);
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.items;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.bukkit.persistence.PersistentDataAdapterContext;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public class ItemVariantIdentifier implements PersistentDataType<byte[], String> {
|
||||
private final String ID;
|
||||
|
||||
public ItemVariantIdentifier(String ID) {
|
||||
this.ID = ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<byte[]> getPrimitiveType() {
|
||||
return byte[].class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<String> getComplexType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte [] toPrimitive(String complex, PersistentDataAdapterContext context) {
|
||||
return complex.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fromPrimitive(byte [] primitive, PersistentDataAdapterContext context) {
|
||||
return new String(primitive, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the iD
|
||||
*/
|
||||
public String getID() {
|
||||
return ID;
|
||||
}
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.items;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
|
||||
public class ItemVariantManager implements Listener {
|
||||
private final IslandSurvivalCraft islandSurvivalCraft;
|
||||
|
||||
public ItemVariantManager(IslandSurvivalCraft islandSurvivalCraft) {
|
||||
this.islandSurvivalCraft = islandSurvivalCraft;
|
||||
}
|
||||
|
||||
public void loadAllItems() {
|
||||
RegisteredItemVariants[] items = RegisteredItemVariants.values();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (items[i].getVariedItem().needInitialization()) {
|
||||
items[i].getVariedItem().initialize(islandSurvivalCraft);
|
||||
}
|
||||
Recipe currentRecipe = items[i].getVariedItem().getRecipe();
|
||||
if (currentRecipe != null) {
|
||||
islandSurvivalCraft.getServer().addRecipe(currentRecipe);
|
||||
}
|
||||
}
|
||||
|
||||
Collection<? extends Player> players = islandSurvivalCraft.getServer().getOnlinePlayers();
|
||||
for (Player player : players) {
|
||||
initializeInventoryVariedItems(player.getInventory());
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadAllItems() {
|
||||
RegisteredItemVariants[] items = RegisteredItemVariants.values();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
Bukkit.removeRecipe(new NamespacedKey(islandSurvivalCraft, items[i].getVariedItem().getItemName()));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onHeld(PlayerItemHeldEvent e) {
|
||||
ItemStack item = e.getPlayer().getInventory().getItem(e.getNewSlot());
|
||||
ItemVariant variedItem = getVariedItemFromItemStack(item);
|
||||
if (variedItem != null) {
|
||||
variedItem.onItemHeld(item, e.getPlayer());
|
||||
} else {
|
||||
item = e.getPlayer().getInventory().getItem(e.getPreviousSlot());
|
||||
variedItem = getVariedItemFromItemStack(item);
|
||||
if (variedItem != null) {
|
||||
variedItem.onItemPutAway(item, e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onInventoryInteract(InventoryClickEvent e) {
|
||||
ItemStack item = e.getCurrentItem();
|
||||
ItemVariant variedItem = getVariedItemFromItemStack(item);
|
||||
if (e.getSlotType() == SlotType.RESULT) {
|
||||
if (variedItem != null) {
|
||||
if (variedItem.onItemCrafted(item, e.getWhoClicked())) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
} else if (e.getSlotType() == SlotType.QUICKBAR) {
|
||||
if (e.getWhoClicked().getInventory().getHeldItemSlot() == e.getSlot()) {
|
||||
if (variedItem != null) {
|
||||
variedItem.onItemPutAway(item, e.getWhoClicked());
|
||||
} else if ((variedItem = getVariedItemFromItemStack(e.getCursor())) != null) {
|
||||
variedItem.onItemHeld(item, e.getWhoClicked());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerDropItem(PlayerDropItemEvent e) {
|
||||
ItemStack item = e.getItemDrop().getItemStack();
|
||||
ItemVariant variedItem = getVariedItemFromItemStack(item);
|
||||
if (variedItem != null) {
|
||||
variedItem.onItemPutAway(item, e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onEntityPickup(EntityPickupItemEvent e) {
|
||||
ItemStack item = e.getItem().getItemStack();
|
||||
if (e.getEntityType() == EntityType.PLAYER) {
|
||||
ItemVariant variedItem = getVariedItemFromItemStack(item);
|
||||
if (variedItem != null) {
|
||||
Player player = (Player) e.getEntity();
|
||||
if (player.getInventory().getHeldItemSlot() == player.getInventory().firstEmpty()) {
|
||||
variedItem.onItemHeld(item, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteraction(PlayerInteractEvent e) {
|
||||
if (e.useItemInHand() == Result.DENY || (e.getAction() != Action.RIGHT_CLICK_AIR && e.getAction() != Action.RIGHT_CLICK_BLOCK)) return;
|
||||
ItemStack item = e.getItem();
|
||||
ItemVariant variedItem = getVariedItemFromItemStack(item);
|
||||
if (variedItem != null) {
|
||||
if(variedItem.onItemRightClicked(item, e.getPlayer(), e.getHand(), e.getClickedBlock(), e.getBlockFace())) {
|
||||
e.setCancelled(true);
|
||||
e.setUseItemInHand(Result.DENY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
initializeInventoryVariedItems(e.getPlayer().getInventory());
|
||||
ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
|
||||
ItemVariant variedItem = getVariedItemFromItemStack(item); //Check to see of we can find a variation of the item.
|
||||
if (variedItem != null) {
|
||||
variedItem.onItemHeld(item, e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeInventoryVariedItems(Inventory inv) {
|
||||
RegisteredItemVariants[] registeredVariedItems = RegisteredItemVariants.values();
|
||||
for (RegisteredItemVariants registeredVariedItem : registeredVariedItems) {
|
||||
ItemVariant variedItem = registeredVariedItem.getVariedItem();
|
||||
|
||||
Material[] bases = variedItem.getBaseItems();
|
||||
for (Material base : bases) {
|
||||
HashMap<Integer, ? extends ItemStack> potentials = inv.all(base);
|
||||
for (Entry<Integer, ? extends ItemStack> entry : potentials.entrySet()) {
|
||||
if (registeredVariedItem.getVariedItem().getRecipe() != null) {
|
||||
NamespacedKey key = new NamespacedKey(islandSurvivalCraft, variedItem.getItemName() + ".identifier");
|
||||
String identifier = entry.getValue().getItemMeta().getPersistentDataContainer().get(key, variedItem.getIdentifier());
|
||||
if (identifier != null) {
|
||||
variedItem.initializeInstanceOfItem(entry.getValue());
|
||||
}
|
||||
} else {
|
||||
variedItem.initializeInstanceOfItem(entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ItemVariant getVariedItemFromItemStack(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) return null;
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
RegisteredItemVariants[] items = RegisteredItemVariants.values();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
ItemVariant current = items[i].getVariedItem();
|
||||
if (current.getRecipe() == null) {
|
||||
for (Material material : current.getBaseItems()) {
|
||||
if (item.getType() == material) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
NamespacedKey key = new NamespacedKey(islandSurvivalCraft, current.getItemName());
|
||||
String identifier = meta.getPersistentDataContainer().get(key, current.getIdentifier());
|
||||
if (identifier != null) {
|
||||
if (current.getIdentifier().getID().equals(identifier)) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.items;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.interaction.items.variations.*;
|
||||
|
||||
public enum RegisteredItemVariants {
|
||||
ISLAND_MAP(new IslandMapItem())
|
||||
;
|
||||
|
||||
private final ItemVariant variedItem;
|
||||
private RegisteredItemVariants(ItemVariant alternateItem) {
|
||||
this.variedItem = alternateItem;
|
||||
this.variedItem.assignIdentifier(new ItemVariantIdentifier(this.name() + ".identifier"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the variedItem
|
||||
*/
|
||||
public ItemVariant getVariedItem() {
|
||||
return variedItem;
|
||||
}
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.interaction.items.variations;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
import org.bukkit.map.MapCanvas;
|
||||
import org.bukkit.map.MapPalette;
|
||||
import org.bukkit.map.MapRenderer;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.IslandSurvivalCraft;
|
||||
import net.reslate.islandsurvivalcraft.interaction.items.ItemVariant;
|
||||
import net.reslate.islandsurvivalcraft.interaction.items.ItemVariantIdentifier;
|
||||
import net.reslate.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.world.WorldInfo;
|
||||
import net.reslate.islandsurvivalcraft.world.Information.IslandInformation;
|
||||
import net.reslate.islandsurvivalcraft.world.Information.IslandInformationManager;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
public class IslandMapItem extends MapRenderer implements ItemVariant {
|
||||
IslandSurvivalCraft plugin;
|
||||
ItemVariantIdentifier identifier;
|
||||
Color mainColor = new Color(0, 180, 0);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void render(MapView map, MapCanvas canvas, Player player) {
|
||||
WorldInfo worldInfo = plugin.getWorldInfoManager().retrieve(map.getWorld().getName());
|
||||
IslandInformationManager islandInformationManager = worldInfo.getIslandInfoManager();
|
||||
int blocksPerPixel = (int) (1 * Math.pow(2, map.getScale().getValue()));
|
||||
for (int x = 0; x < 128; x += 1) {
|
||||
for (int y = x % 2; y < 128; y += 2) {
|
||||
if (canvas.getPixel(x, y) != MapPalette.matchColor(mainColor)) {
|
||||
int actualX = blocksPerPixel * (x - Byte.MAX_VALUE/2) + map.getCenterX();
|
||||
int actualZ = blocksPerPixel * (y - Byte.MAX_VALUE/2) + map.getCenterZ();
|
||||
Point2 pCoords = new Point2(actualX, actualZ);
|
||||
if (islandInformationManager.isChunkIslandInformationLoaded(GeneralUtilities.worldToChunkCoordinates(pCoords), false)) {
|
||||
IslandInformation info = islandInformationManager.getIslandInformation(pCoords, false);
|
||||
if (info != null) {
|
||||
canvas.setPixel(x, y, MapPalette.matchColor(mainColor));
|
||||
}
|
||||
} else if (worldInfo.getIslandMap().isIsland(actualX, actualZ)) {
|
||||
canvas.setPixel(x, y, MapPalette.matchColor(mainColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(IslandSurvivalCraft islandSurvivalCraft) {
|
||||
this.plugin = islandSurvivalCraft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Recipe getRecipe() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemName() {
|
||||
return "Island_Map";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material[] getBaseItems() {
|
||||
return new Material[] {Material.FILLED_MAP};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignIdentifier(ItemVariantIdentifier identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemVariantIdentifier getIdentifier() {
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needInitialization() {
|
||||
return this.plugin == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemCrafted(ItemStack item, HumanEntity crafter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemRightClicked(ItemStack item, HumanEntity clicker, EquipmentSlot hand, Block block,
|
||||
BlockFace blockFace) {
|
||||
if (((Player)clicker).isSneaking()) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
NamespacedKey key = new NamespacedKey(plugin, getItemName() + ".state");
|
||||
if (!container.has(key, PersistentDataType.BYTE)) {
|
||||
container.set(key, PersistentDataType.BYTE, (byte) 0);
|
||||
}
|
||||
if (container.get(key, PersistentDataType.BYTE) == 0) {
|
||||
container.set(key, PersistentDataType.BYTE, (byte) 1);
|
||||
MapMeta mapMeta = (MapMeta) item.getItemMeta();
|
||||
mapMeta.getMapView().addRenderer(this);
|
||||
} else {
|
||||
container.set(key, PersistentDataType.BYTE, (byte) 0);
|
||||
MapMeta mapMeta = (MapMeta) item.getItemMeta();
|
||||
mapMeta.getMapView().removeRenderer(this);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemHeld(ItemStack heldItem, HumanEntity holder) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemPutAway(ItemStack item, HumanEntity holder) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeInstanceOfItem(ItemStack item) {
|
||||
MapMeta mapMeta = (MapMeta) item.getItemMeta();
|
||||
PersistentDataContainer container = mapMeta.getPersistentDataContainer();
|
||||
NamespacedKey key = new NamespacedKey(plugin, getItemName() + ".state");
|
||||
|
||||
if (container.has(key, PersistentDataType.BYTE)) {
|
||||
if (container.get(key, PersistentDataType.BYTE) == 1) {
|
||||
mapMeta = (MapMeta) item.getItemMeta();
|
||||
mapMeta.getMapView().addRenderer(this);
|
||||
item.setItemMeta(mapMeta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.persistence;
|
||||
|
||||
public enum Settings {
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public class GeneralUtilities {
|
||||
public final static int CHUNK_SIZE = 16;
|
||||
public final static ExecutorService ISC_EXECUTOR_ALPHA = Executors.newFixedThreadPool(1, createThreadFactory("ALPHA", Thread.NORM_PRIORITY + 1));
|
||||
public final static ExecutorService ISC_EXECUTOR_BETA = Executors.newFixedThreadPool(2, createThreadFactory("BETA", Thread.NORM_PRIORITY));
|
||||
|
||||
public static <K, V> HashMap<V, ArrayList<K>> invertHashMap(HashMap<K, V> hashMap) {
|
||||
HashMap<V, ArrayList<K>> res = new HashMap<>();
|
||||
for (Entry<K, V> entry : hashMap.entrySet()) {
|
||||
if (!res.containsKey(entry.getValue())) {
|
||||
ArrayList<K> l = new ArrayList<K>();
|
||||
l.add(entry.getKey());
|
||||
res.put(entry.getValue(), l);
|
||||
} else {
|
||||
res.get(entry.getValue()).add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static int addMagnitude(int value, int add) {
|
||||
boolean negative = false;
|
||||
if (value < 0) negative = true;
|
||||
int res = Math.abs(value) + add;
|
||||
return negative ? - res : res;
|
||||
}
|
||||
|
||||
public static Point2 worldToChunkCoordinates(int x, int y) {
|
||||
int xRes = 0;
|
||||
if (x < 0) {
|
||||
xRes = (int) Math.floor((float) x / CHUNK_SIZE);
|
||||
} else {
|
||||
xRes = x / CHUNK_SIZE;
|
||||
}
|
||||
int yRes = 0;
|
||||
if (y < 0) {
|
||||
yRes = (int) Math.floor((float) y / CHUNK_SIZE);
|
||||
} else {
|
||||
yRes = y / CHUNK_SIZE;
|
||||
}
|
||||
return new Point2(xRes, yRes);
|
||||
}
|
||||
|
||||
public static Point2 worldToChunkCoordinates(Point2 worldCoordinates) {
|
||||
return worldToChunkCoordinates(worldCoordinates.x, worldCoordinates.y);
|
||||
}
|
||||
|
||||
public static Point2 worldToLocalChunkCoordinates(int x, int y) {
|
||||
int xRes = 0;
|
||||
if (x < 0) {
|
||||
xRes = CHUNK_SIZE + (x % CHUNK_SIZE);
|
||||
xRes %= CHUNK_SIZE;
|
||||
} else {
|
||||
xRes = x % CHUNK_SIZE;
|
||||
}
|
||||
int yRes = 0;
|
||||
if (y < 0) {
|
||||
yRes = CHUNK_SIZE + (y % CHUNK_SIZE);
|
||||
yRes %= CHUNK_SIZE;
|
||||
} else {
|
||||
yRes = y % CHUNK_SIZE;
|
||||
}
|
||||
return new Point2(xRes, yRes);
|
||||
}
|
||||
|
||||
public static Point2 worldToLocalChunkCoordinates(Point2 worldCoordinates) {
|
||||
return worldToLocalChunkCoordinates(worldCoordinates.x, worldCoordinates.y);
|
||||
}
|
||||
|
||||
public static ThreadFactory createThreadFactory(final String identifier, final int priority) {
|
||||
return new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r, String.format("ISC-worker-%s", identifier));
|
||||
thread.setPriority(priority);
|
||||
return thread;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.biomes;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.weighting.Weightable;
|
||||
import net.reslate.islandsurvivalcraft.utilities.weighting.WeightedSelector;
|
||||
|
||||
public enum BiomeClassifications implements Weightable {
|
||||
SNOWY(0.2f, new OceanBiomeInfo(Biome.FROZEN_OCEAN, Biome.COLD_OCEAN, Biome.DEEP_FROZEN_OCEAN),
|
||||
new LandBiomeInfo(Biome.SNOWY_TAIGA, null, Biome.SNOWY_TAIGA_HILLS, Biome.SNOWY_BEACH, 0.3f),
|
||||
new LandBiomeInfo(Biome.SNOWY_TAIGA_MOUNTAINS, Biome.SNOWY_TAIGA, null, Biome.SNOWY_BEACH, 0.25f),
|
||||
new LandBiomeInfo(Biome.SNOWY_TUNDRA, null, null, Biome.SNOWY_BEACH, 0.3f),
|
||||
new LandBiomeInfo(Biome.ICE_SPIKES, null, null, Biome.SNOWY_BEACH, 0.15f)
|
||||
),
|
||||
COLD(0.3f, new OceanBiomeInfo(Biome.COLD_OCEAN, null, Biome.DEEP_COLD_OCEAN),
|
||||
new LandBiomeInfo(Biome.MOUNTAINS, null, null, Biome.STONE_SHORE, 0.14f),
|
||||
new LandBiomeInfo(Biome.GRAVELLY_MOUNTAINS, 0.1f),
|
||||
new LandBiomeInfo(Biome.WOODED_MOUNTAINS, 0.08f),
|
||||
new LandBiomeInfo(Biome.MODIFIED_GRAVELLY_MOUNTAINS, 0.08f),
|
||||
new LandBiomeInfo(Biome.TAIGA, null, Biome.TAIGA_HILLS, Biome.BEACH, 0.15f),
|
||||
new LandBiomeInfo(Biome.TAIGA_MOUNTAINS, 0.15f),
|
||||
new LandBiomeInfo(Biome.GIANT_TREE_TAIGA, null, Biome.GIANT_TREE_TAIGA_HILLS, Biome.BEACH, 0.15f),
|
||||
new LandBiomeInfo(Biome.GIANT_SPRUCE_TAIGA, null, Biome.GIANT_SPRUCE_TAIGA_HILLS, Biome.BEACH, 0.15f)
|
||||
),
|
||||
LUSH(0.3f, new OceanBiomeInfo(Biome.WARM_OCEAN, Biome.LUKEWARM_OCEAN, Biome.DEEP_LUKEWARM_OCEAN),
|
||||
new LandBiomeInfo(Biome.PLAINS, 0.15f),
|
||||
new LandBiomeInfo(Biome.SUNFLOWER_PLAINS, 0.075f),
|
||||
new LandBiomeInfo(Biome.FOREST, null, Biome.WOODED_HILLS, Biome.BEACH, 0.1f),
|
||||
new LandBiomeInfo(Biome.FLOWER_FOREST, 0.05f),
|
||||
new LandBiomeInfo(Biome.BIRCH_FOREST, null, Biome.BIRCH_FOREST_HILLS, Biome.BEACH, 0.1f),
|
||||
new LandBiomeInfo(Biome.TALL_BIRCH_FOREST, null, Biome.TALL_BIRCH_HILLS, Biome.BEACH, 0.075f),
|
||||
new LandBiomeInfo(Biome.DARK_FOREST, null, Biome.DARK_FOREST_HILLS, Biome.BEACH, 0.075f),
|
||||
new LandBiomeInfo(Biome.SWAMP, null, Biome.SWAMP_HILLS, null, 0.1f),
|
||||
new LandBiomeInfo(Biome.JUNGLE, Biome.JUNGLE_EDGE, Biome.JUNGLE_HILLS, Biome.BEACH, 0.075f),
|
||||
new LandBiomeInfo(Biome.MODIFIED_JUNGLE, Biome.MODIFIED_JUNGLE_EDGE, null, Biome.BEACH, 0.075f),
|
||||
new LandBiomeInfo(Biome.BAMBOO_JUNGLE, null, Biome.BAMBOO_JUNGLE_HILLS, Biome.BEACH, 0.075f),
|
||||
new LandBiomeInfo(Biome.MUSHROOM_FIELDS, null, null, Biome.MUSHROOM_FIELD_SHORE, 0.05f)
|
||||
),
|
||||
WARM(0.2f, new OceanBiomeInfo(Biome.OCEAN, null, Biome.DEEP_OCEAN),
|
||||
new LandBiomeInfo(Biome.DESERT, null, Biome.DESERT_HILLS, Biome.BEACH, 0.2f),
|
||||
new LandBiomeInfo(Biome.SAVANNA, 0.2f),
|
||||
new LandBiomeInfo(Biome.SHATTERED_SAVANNA, 0.075f),
|
||||
new LandBiomeInfo(Biome.BADLANDS, 0.075f),
|
||||
new LandBiomeInfo(Biome.ERODED_BADLANDS, 0.075f),
|
||||
new LandBiomeInfo(Biome.WOODED_BADLANDS_PLATEAU, 0.075f),
|
||||
new LandBiomeInfo(Biome.MODIFIED_WOODED_BADLANDS_PLATEAU, 0.075f),
|
||||
new LandBiomeInfo(Biome.BADLANDS_PLATEAU, 0.075f),
|
||||
new LandBiomeInfo(Biome.SAVANNA_PLATEAU, 0.05f),
|
||||
new LandBiomeInfo(Biome.MODIFIED_BADLANDS_PLATEAU, 0.05f),
|
||||
new LandBiomeInfo(Biome.SHATTERED_SAVANNA_PLATEAU, 0.05f)
|
||||
),
|
||||
;
|
||||
|
||||
private final LandBiomeInfo[] biomeInfos;
|
||||
private final float weight;
|
||||
private final OceanBiomeInfo associatedOceanBiomeInfo;
|
||||
private final WeightedSelector<LandBiomeInfo> selector;
|
||||
|
||||
BiomeClassifications(float weight, OceanBiomeInfo oceanBiomeInfo, LandBiomeInfo... biomeInfos) {
|
||||
this.biomeInfos = biomeInfos;
|
||||
this.weight = weight;
|
||||
this.associatedOceanBiomeInfo = oceanBiomeInfo;
|
||||
selector = new WeightedSelector<>(Arrays.asList(biomeInfos));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the biomes associated with this classification.
|
||||
*/
|
||||
public LandBiomeInfo[] getBiomeInfos() {
|
||||
return biomeInfos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the associatedOceanBiomeInfo
|
||||
*/
|
||||
public OceanBiomeInfo getAssociatedOceanBiomeInfo() {
|
||||
return associatedOceanBiomeInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the selector
|
||||
*/
|
||||
public WeightedSelector<LandBiomeInfo> getSelector() {
|
||||
return selector;
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.biomes;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
public interface BiomeInfo {
|
||||
public Biome getMainBiome();
|
||||
public Biome getTransitionBiome();
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.biomes;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.weighting.Weightable;
|
||||
|
||||
public class LandBiomeInfo implements Weightable, BiomeInfo {
|
||||
private final Biome biome;
|
||||
private final float weight;
|
||||
private final Biome hillBiome;
|
||||
private final Biome transitionBiome;
|
||||
private final Biome preferredShore;
|
||||
|
||||
/**
|
||||
* Creates a land biome information object.
|
||||
* @param biome the main biome this object represents.
|
||||
* @param transitionBiome the transition biome to go with this biome. May be null.
|
||||
* @param hill the hill biome that goes with this biome. May be null.
|
||||
* @param shore the shore that goes with this biome. May be null.
|
||||
* @param weight the weight, relative to the others, chance this biome spawns.
|
||||
*/
|
||||
public LandBiomeInfo(Biome biome, Biome transitionBiome, Biome hill, Biome shore, float weight) {
|
||||
if (biome == null) throw new IllegalArgumentException("Argument biome may never be null.");
|
||||
this.weight = weight;
|
||||
this.biome = biome;
|
||||
this.hillBiome = hill;
|
||||
this.preferredShore = shore;
|
||||
this.transitionBiome = transitionBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a land biome information object.
|
||||
* Leaves the transition biome and hill biomes as null.
|
||||
* The shore is set to beach.
|
||||
* @param biome The biome this object represents.
|
||||
* @param weight The probability of selecting this biome.
|
||||
*/
|
||||
public LandBiomeInfo(Biome biome, float weight) {
|
||||
this(biome, null, null, Biome.BEACH, weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the weight
|
||||
*/
|
||||
public float getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hill biome. Will return the normal biome if there is no special hill biome for this biome.
|
||||
*/
|
||||
public Biome getHillBiome() {
|
||||
if (hillBiome == null) return getMainBiome();
|
||||
return hillBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the shore biome. Will return the normal biome if there is no shore specificied.
|
||||
*/
|
||||
public Biome getShoreBiome() {
|
||||
if (preferredShore != null) return preferredShore;
|
||||
return getMainBiome();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the transition biome if it has one. May be null.
|
||||
*/
|
||||
public Biome getTransitionBiome() {
|
||||
return transitionBiome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getMainBiome() {
|
||||
return biome;
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.biomes;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
public class OceanBiomeInfo implements BiomeInfo {
|
||||
private final Biome ocean;
|
||||
private final Biome transitionOcean;
|
||||
private final Biome deepAlternative;
|
||||
|
||||
public OceanBiomeInfo(Biome ocean, Biome transitionOcean, Biome deepAlternative) {
|
||||
if (ocean == null || deepAlternative == null) throw new IllegalArgumentException("Neither argument ocean nor deepAlternative may be null.");
|
||||
this.ocean = ocean;
|
||||
this.transitionOcean = transitionOcean;
|
||||
this.deepAlternative = deepAlternative;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the main ocean.
|
||||
*/
|
||||
public Biome getOcean() {
|
||||
return ocean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deep version of this ocean.
|
||||
*/
|
||||
public Biome getDeepAlternative() {
|
||||
return deepAlternative;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getMainBiome() {
|
||||
return getOcean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getTransitionBiome() {
|
||||
if (transitionOcean == null) return getOcean();
|
||||
return transitionOcean;
|
||||
}
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.caching;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class Cache<K, V> {
|
||||
private final int maxSize;
|
||||
private final ConcurrentHashMap<K, CacheValue<K, V>> data;
|
||||
private final CacheUsageStack<K, V> usage = new CacheUsageStack<>();
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Creates a thread safe cache.
|
||||
* @param maxSize If this is greater than 0, this cache will operate as an LRU cache. Otherwise, the user will need to remove objects manually.
|
||||
*/
|
||||
public Cache(int maxSize) {
|
||||
data = new ConcurrentHashMap<>(maxSize + 1, 0.75f, 16);
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a thread safe cache.
|
||||
* This creates the cache without a limit, and therefore, does not operate as a LSU.
|
||||
*/
|
||||
public Cache() {
|
||||
this(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value with the respective associated key.
|
||||
* If the addition of this value and key cause the cache to be bigger than its designated max size,
|
||||
* It will remove one of the least used values in the cache to accomodate.
|
||||
* @param key The key to associate with the value.
|
||||
* @param value The value to store.
|
||||
*/
|
||||
public void set(K key, V value) {
|
||||
if (data.containsKey(key)) {
|
||||
data.get(key).value = value;
|
||||
} else {
|
||||
lock.lock();
|
||||
try {
|
||||
if (data.containsKey(key)) return;
|
||||
CacheValue<K, V> val = new CacheValue<>(key, value);
|
||||
data.put(key, val);
|
||||
usage.add(val);
|
||||
if (maxSize > 0 && data.size() > maxSize) {
|
||||
data.remove(usage.pop().key);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves cached value associated to the key.
|
||||
* Uses equals.
|
||||
* If does not exist, returns null.
|
||||
* @param key the key associated with the value.
|
||||
* @return the value associated to the key.
|
||||
*/
|
||||
public V get(K key) {
|
||||
CacheValue<K, V> cacheValue = data.get(key);
|
||||
if (cacheValue == null) return null;
|
||||
usage.tryMoveToTop(cacheValue);
|
||||
return cacheValue.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the associated key and value pair.
|
||||
* @param key The associated key.
|
||||
* @return The associated value.
|
||||
*/
|
||||
public V remove(K key) {
|
||||
CacheValue<K, V> cacheValue = data.remove(key);
|
||||
if (cacheValue == null) return null;
|
||||
usage.remove(cacheValue);
|
||||
return cacheValue.value;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
public boolean contains(K key) {
|
||||
return data.containsKey(key);
|
||||
}
|
||||
|
||||
public V getMostRecent() {
|
||||
return usage.getTop().value;
|
||||
}
|
||||
|
||||
public K getMostRecentKey() {
|
||||
return usage.getTop().key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cache of all values.
|
||||
*/
|
||||
public void clearCache() {
|
||||
lock.lock();
|
||||
try {
|
||||
data.clear();
|
||||
usage.clear();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.caching;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
class CacheUsageStack<K, V> {
|
||||
private volatile int size;
|
||||
private volatile CacheValue<K, V> first, last;
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private void addValueToStackTop(CacheValue<K, V> value) {
|
||||
if (value == first) return;
|
||||
if (first != null) {
|
||||
first.front = value;
|
||||
value.back = first;
|
||||
} else {
|
||||
last = value;
|
||||
}
|
||||
|
||||
value.front = null;
|
||||
first = value;
|
||||
size++;
|
||||
}
|
||||
|
||||
private void removeValueFromStack(CacheValue<K, V> value) {
|
||||
if (value.front != null) {
|
||||
value.front.back = value.back;
|
||||
} else {
|
||||
first = value.back;
|
||||
}
|
||||
if (value.back != null) {
|
||||
value.back.front = value.front;
|
||||
} else {
|
||||
last = value.front;
|
||||
}
|
||||
value.front = null;
|
||||
value.back = null;
|
||||
size--;
|
||||
}
|
||||
|
||||
public void moveToTop(CacheValue<K, V> value) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (!value.detached) {
|
||||
removeValueFromStack(value);
|
||||
addValueToStackTop(value);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean tryMoveToTop(CacheValue<K, V> value) {
|
||||
boolean success = false;
|
||||
success = lock.tryLock();
|
||||
if (success) {
|
||||
try {
|
||||
if (!value.detached) {
|
||||
removeValueFromStack(value);
|
||||
addValueToStackTop(value);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public void add(CacheValue<K, V> value) {
|
||||
lock.lock();
|
||||
try {
|
||||
addValueToStackTop(value);
|
||||
value.detached = false;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(CacheValue<K, V> value) {
|
||||
lock.lock();
|
||||
try {
|
||||
removeValueFromStack(value);
|
||||
value.detached = true;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public CacheValue<K, V> pop() {
|
||||
CacheValue<K, V> cacheValue;
|
||||
lock.lock();
|
||||
try {
|
||||
cacheValue = last;
|
||||
removeValueFromStack(last);
|
||||
cacheValue.detached = true;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return cacheValue;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
lock.lock();
|
||||
try {
|
||||
first = null;
|
||||
last = null;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public CacheValue<K, V> getTop() {
|
||||
return first;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.caching;
|
||||
|
||||
class CacheValue<KeyType, ValueType> {
|
||||
/**
|
||||
* The key that represents this cache value in the caches hashmap.
|
||||
*/
|
||||
public final KeyType key;
|
||||
|
||||
/**
|
||||
* The actual value that this cache value stores.
|
||||
*/
|
||||
public volatile ValueType value;
|
||||
|
||||
/**
|
||||
* The cache value in this position.
|
||||
*/
|
||||
public volatile CacheValue<KeyType, ValueType> front, back;
|
||||
|
||||
/**
|
||||
* Whether or not this value is detached from the cache's hashmap.
|
||||
*/
|
||||
public volatile boolean detached = true;
|
||||
|
||||
public CacheValue(KeyType key, ValueType value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.datatypes;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Point2 {
|
||||
public final int x, y;
|
||||
private final int hash;
|
||||
|
||||
public Point2(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.hash = Objects.hash(x, y);
|
||||
}
|
||||
|
||||
public Point2(Point2 point) {
|
||||
this(point.x, point.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Point2) {
|
||||
Point2 p = (Point2) obj;
|
||||
return p.x == this.x && p.y == this.y;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean fastEquals(Point2 point) {
|
||||
return point.hashCode() == this.hash && x == point.x && y == point.y;
|
||||
}
|
||||
|
||||
public double distance(Point2 point) {
|
||||
return Math.hypot(point.x - this.x, point.y - this.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%d, %d)", x, y);
|
||||
}
|
||||
|
||||
public Point2 shift(int x, int y) {
|
||||
return new Point2(this.x + x, this.y + y);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.datatypes;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Point3 {
|
||||
public final int x, y, z;
|
||||
private final int hash;
|
||||
|
||||
public Point3(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.hash = Objects.hash(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Point3) {
|
||||
Point3 p = (Point3) obj;
|
||||
return p.x == this.x && p.y == this.y && p.z == this.z;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean fastEquals(Point3 point) {
|
||||
return point.hashCode() == this.hash && x == point.x && y == point.y && z == point.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%d, %d, %d)", x, y, z);
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.datatypes;
|
||||
|
||||
public class Reference<T> {
|
||||
public T value;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.datatypes;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Vector3 {
|
||||
public final float x, y, z;
|
||||
private final int hash;
|
||||
|
||||
public Vector3(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.hash = Objects.hash(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Point3) {
|
||||
Point3 p = (Point3) obj;
|
||||
return p.x == this.x && p.y == this.y && p.z == this.z;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean fastEquals(Point3 point) {
|
||||
return point.hashCode() == this.hash && x == point.x && y == point.y && z == point.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%d, %d, %d)", x, y, z);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.drawing;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.utilities.pathfinding.CoordinateValidatable;
|
||||
|
||||
public class Circle {
|
||||
public final Point2 center;
|
||||
public final CoordinateValidatable drawer;
|
||||
public final int r;
|
||||
int p, x, y;
|
||||
|
||||
/**
|
||||
* A circle drawing object.
|
||||
* @param center The center point.
|
||||
* @param radius The radius of the circle to be drawn.
|
||||
* @param drawer The coordinate validator to be used to draw. The value the validator returns is ignored.
|
||||
*/
|
||||
public Circle(Point2 center, int radius, CoordinateValidatable drawer) {
|
||||
if (center == null) throw new NullPointerException("Center cannot be null.");
|
||||
if (radius <= 0) throw new IllegalArgumentException("radius cannot be 0 or less.");
|
||||
if (drawer == null) throw new NullPointerException("Drawer cannot be null.");
|
||||
this.center = center;
|
||||
this.r = radius;
|
||||
this.drawer = drawer;
|
||||
|
||||
p = 1 - radius;
|
||||
x = 0;
|
||||
y = this.r;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if done.
|
||||
*/
|
||||
public boolean step() {
|
||||
if (x > y) return true;
|
||||
drawer.validate(new Point2(center.x + x, center.y + y));
|
||||
drawer.validate(new Point2(center.x + x, center.y - y));
|
||||
drawer.validate(new Point2(center.x - x, center.y + y));
|
||||
drawer.validate(new Point2(center.x - x, center.y - y));
|
||||
drawer.validate(new Point2(center.x + y, center.y + x));
|
||||
drawer.validate(new Point2(center.x + y, center.y - x));
|
||||
drawer.validate(new Point2(center.x - y, center.y + x));
|
||||
drawer.validate(new Point2(center.x - y, center.y - x));
|
||||
if (p < 0) {
|
||||
p += 2*x + 3;
|
||||
} else {
|
||||
p += 2 * x - 2 * y + 5;
|
||||
y--;
|
||||
}
|
||||
x++;
|
||||
return x > y;
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
while (!step());
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.drawing;
|
||||
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.utilities.pathfinding.CoordinateValidatable;
|
||||
|
||||
public class Flooder {
|
||||
private final Point2 start;
|
||||
private final CoordinateValidatable floodable;
|
||||
|
||||
public Flooder(Point2 start, CoordinateValidatable floodable) {
|
||||
this.start = start;
|
||||
this.floodable = floodable;
|
||||
}
|
||||
|
||||
public Flooder(int xStart, int yStart, CoordinateValidatable floodable) {
|
||||
this(new Point2(xStart, yStart), floodable);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
HashSet<Point2> checked = new HashSet<>();
|
||||
LinkedList<Point2> queue = new LinkedList<>();
|
||||
|
||||
if (!checked.add(start)) return;
|
||||
if (!floodable.validate(start)) return;
|
||||
queue.add(start);
|
||||
while (!queue.isEmpty()) {
|
||||
Point2 p = queue.pop();
|
||||
|
||||
Point2 pE = new Point2(p.x + 1, p.y);
|
||||
if (checked.add(pE) && floodable.validate(pE)) queue.add(pE);
|
||||
|
||||
Point2 pW = new Point2(p.x - 1, p.y);
|
||||
if (checked.add(pW) && floodable.validate(pW)) queue.add(pW);
|
||||
|
||||
Point2 pN = new Point2(p.x, p.y + 1);
|
||||
if (checked.add(pN) && floodable.validate(pN)) queue.add(pN);
|
||||
|
||||
Point2 pS = new Point2(p.x, p.y - 1);
|
||||
if (checked.add(pS) && floodable.validate(pS)) queue.add(pS);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.noise;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.util.noise.SimplexOctaveGenerator;
|
||||
|
||||
public class FractalOctaveGenerator {
|
||||
private final SimplexOctaveGenerator simplex;
|
||||
private final double amplitude = 0.5d;
|
||||
private final double frequency = 0.5d;
|
||||
private final double scale = 0.05D;
|
||||
|
||||
public FractalOctaveGenerator(Random random) {
|
||||
simplex = new SimplexOctaveGenerator(random, 4);
|
||||
simplex.setScale(scale);
|
||||
}
|
||||
|
||||
public double noise(int x, int y) {
|
||||
return 1d - Math.abs(simplex.noise(x, y, frequency, amplitude, true));
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.pathfinding;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public interface CoordinateValidatable {
|
||||
public boolean validate(Point2 point);
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.pathfinding;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public class DepthFirstSearch {
|
||||
private final HashSet<Node> checkedNodes;
|
||||
private final NodeComparable comparable;
|
||||
private final Queue<Node> queue;
|
||||
private final Node startNode;
|
||||
private final Point2 endGoal;
|
||||
private final int maxNodesSearched;
|
||||
private Node currentValidNode;
|
||||
private Node results;
|
||||
|
||||
/**
|
||||
* Instantiates a DFS search object.
|
||||
* @param start The starting point for this search.
|
||||
* @param endGoal The objective. May be null, but a target validator will then be required.
|
||||
* @param customComparable The comparable to use to compare points. May be null, where then there will be no prioritization of direction.
|
||||
* @param maxNodesSearched The maximum amount of allowed searched nodes. set to 0 for infinite.
|
||||
*/
|
||||
public DepthFirstSearch(Point2 start, Point2 endGoal, NodeComparable customComparable, int maxNodesSearched) {
|
||||
if (start == null) throw new NullPointerException("Start point cannot be null.");
|
||||
checkedNodes = new HashSet<>();
|
||||
queue = new PriorityQueue<>();
|
||||
this.comparable = customComparable;
|
||||
this.endGoal = endGoal;
|
||||
this.startNode = new Node(null, start, endGoal, customComparable);
|
||||
queue.add(startNode);
|
||||
this.maxNodesSearched = maxNodesSearched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a DFS search object.
|
||||
* Where there is no comparable set and distance to goal will be used if there is one,
|
||||
* and where there is no limit on amount of searched nodes.
|
||||
* @param start The starting point of the search.
|
||||
* @param endGoal The objective of the search, may be null.
|
||||
*/
|
||||
public DepthFirstSearch(Point2 start, Point2 endGoal) {
|
||||
this(start, endGoal, null, 0);
|
||||
}
|
||||
|
||||
|
||||
public Node getResult() {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the currentNode
|
||||
*/
|
||||
public Node getCurrentNode() {
|
||||
return currentValidNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a search step.
|
||||
* @param validity the validator.
|
||||
* @param objective used to determine whether or not this DFS has founds its objective. Will use this over using the end goal.
|
||||
* @return true if done, whether or not it found the objective is determined by the result.
|
||||
*/
|
||||
public boolean step(CoordinateValidatable validity, CoordinateValidatable objective) {
|
||||
if (validity == null) throw new NullPointerException("The validator cannot be null.");
|
||||
Node node = queue.poll();
|
||||
if (node == null) return true;
|
||||
|
||||
if (checkedNodes.add(node) && validity.validate(node)) {
|
||||
currentValidNode = node;
|
||||
if (objective != null) {
|
||||
if (objective.validate(currentValidNode)) {
|
||||
results = currentValidNode;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (endGoal == null) throw new IllegalStateException("Cannot build path without a target or goal.");
|
||||
if (endGoal.fastEquals(currentValidNode)) {
|
||||
results = currentValidNode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (maxNodesSearched > 0 && getSearchedCount() >= maxNodesSearched) return true;
|
||||
Node north = new Node(currentValidNode, currentValidNode.x, currentValidNode.y + 1, endGoal, comparable);
|
||||
queue.add(north);
|
||||
Node south = new Node(currentValidNode, currentValidNode.x, currentValidNode.y - 1, endGoal, comparable);
|
||||
queue.add(south);
|
||||
Node west = new Node(currentValidNode, currentValidNode.x - 1, currentValidNode.y, endGoal, comparable);
|
||||
queue.add(west);
|
||||
Node east = new Node(currentValidNode, currentValidNode.x + 1, currentValidNode.y, endGoal, comparable);
|
||||
queue.add(east);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches until complete. Completion is defined such that when a call to the step function does not return true.
|
||||
* @param validator The validator to use to check if a node is considered allowed to be used.
|
||||
* @param targetValidatable The validator to be used to determine whether or not the current node is the objective. May be null, however, the end goal must not be null in such a case.
|
||||
* @return
|
||||
*/
|
||||
public boolean buildToGoal(CoordinateValidatable validator, CoordinateValidatable targetValidatable) {
|
||||
while (!step(validator, targetValidatable));
|
||||
return results != null;
|
||||
}
|
||||
|
||||
public int getSearchedCount() {
|
||||
return checkedNodes.size();
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.pathfinding;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public class LinkedCoordinateValidator implements CoordinateValidatable {
|
||||
private final CoordinateValidatable[] CoordinateValidatables;
|
||||
|
||||
public LinkedCoordinateValidator(CoordinateValidatable...coordinateValidatables) {
|
||||
this.CoordinateValidatables = coordinateValidatables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Point2 point) {
|
||||
for (int i = 0; i < CoordinateValidatables.length; i++) {
|
||||
if (CoordinateValidatables[i].validate(point)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.pathfinding;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public class Node extends Point2 implements Comparable<Point2> {
|
||||
private final NodeComparable nodeComparable;
|
||||
private final Point2 parent;
|
||||
private final Point2 goal;
|
||||
private Point2 child;
|
||||
|
||||
public Node(Point2 parent, int x, int y, Point2 goal, NodeComparable nodeComparable) {
|
||||
super(x, y);
|
||||
this.parent = parent;
|
||||
this.goal = goal;
|
||||
this.nodeComparable = nodeComparable;
|
||||
}
|
||||
|
||||
public Node(Point2 parent, Point2 location, Point2 goal, NodeComparable nodeComparable) {
|
||||
this(parent, location.x, location.y, goal, nodeComparable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the child of this node. Can only be set once.
|
||||
* @param child the child to set.
|
||||
*/
|
||||
public void setChild(Point2 child) {
|
||||
if (this.child != null) throw new IllegalStateException("Child has already been set.");
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Point2 o) {
|
||||
if (nodeComparable != null) return nodeComparable.compare(this, o);
|
||||
if (goal == null) return 0;
|
||||
double distDiff = distance(goal) - distance(o);
|
||||
if (distDiff == 0) {
|
||||
return 0;
|
||||
} else if (distDiff < 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the parent
|
||||
*/
|
||||
public Point2 getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.pathfinding;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public interface NodeComparable {
|
||||
public int compare(Point2 current, Point2 other);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.weighting;
|
||||
|
||||
public interface Weightable {
|
||||
public float getWeight();
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.weighting;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class WeightedSelector<T extends Weightable> {
|
||||
private final TreeMap<Float, T> map;
|
||||
private final float totalWeights;
|
||||
|
||||
public WeightedSelector(Iterable<T> set) {
|
||||
float totalWeights = 0;
|
||||
map = new TreeMap<>();
|
||||
for (T t : set) {
|
||||
totalWeights += t.getWeight();
|
||||
map.put(totalWeights, t);
|
||||
}
|
||||
this.totalWeights = totalWeights;
|
||||
}
|
||||
|
||||
public T selectRandom(Random random) {
|
||||
return map.ceilingEntry(random.nextFloat() * totalWeights).getValue();
|
||||
}
|
||||
|
||||
public T selectRandom(float selector) {
|
||||
return map.ceilingEntry(selector * totalWeights).getValue();
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.util.noise.SimplexOctaveGenerator;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.BiomeClassifications;
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.LandBiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.OceanBiomeInfo;
|
||||
|
||||
public class BiomeMap {
|
||||
private final SimplexOctaveGenerator noise;
|
||||
|
||||
|
||||
public BiomeMap(Random random) {
|
||||
this(random, 0.02d);
|
||||
}
|
||||
|
||||
public BiomeMap(Random random, double scale) {
|
||||
noise = new SimplexOctaveGenerator(random, 2);
|
||||
noise.setScale(scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to procure a biome that helps transition from one biome to another biome
|
||||
* for given biome.
|
||||
* @param from the biome to transition from.
|
||||
* @return the resulting transition biome.
|
||||
*/
|
||||
public Biome getTransitionalBiome(Biome from) {
|
||||
String biomeName = from.name().toLowerCase();
|
||||
if (biomeName.contains("jungle")) {
|
||||
if (biomeName.contains("modified")) {
|
||||
return Biome.MODIFIED_JUNGLE_EDGE;
|
||||
}
|
||||
return Biome.JUNGLE_EDGE;
|
||||
} else if (biomeName.contains("mountain")) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BiomeClassifications getClassification(float temperature) {
|
||||
if (temperature <= 0.1f) {
|
||||
return BiomeClassifications.SNOWY;
|
||||
} else if (temperature <= 0.3f) {
|
||||
return BiomeClassifications.COLD;
|
||||
} else if (temperature <= 1f) {
|
||||
return BiomeClassifications.LUSH;
|
||||
} else {
|
||||
return BiomeClassifications.WARM;
|
||||
}
|
||||
}
|
||||
|
||||
public LandBiomeInfo getLandBiomeInfo(float temperature, int worldX, int worldZ) {
|
||||
return getClassification(temperature).getSelector().selectRandom((float) noise.noise(worldX, worldZ, 0.5d, 0.5d, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Randomly selects an ocean biome that fits in given temperature.
|
||||
*
|
||||
* @param temperature Minecraft temperature to select biome from.
|
||||
* @param isDeep If this ocean should be of the deep variant.
|
||||
* @param seed The seed to use to select the biome.
|
||||
* @return The randomly selected biome.
|
||||
*/
|
||||
public OceanBiomeInfo getOceanBiome(float temperature) {
|
||||
BiomeClassifications classification = getClassification(temperature);
|
||||
return classification.getAssociatedOceanBiomeInfo();
|
||||
}
|
||||
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.Information;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public class IslandInformation {
|
||||
private final Set<Point2> chunkSpan;
|
||||
private final Set<Point2> islandCoordinates;
|
||||
private final Set<Point2> edgeCoordinates;
|
||||
private final Point2 islandOrigin;
|
||||
private UUID ownerUUID;
|
||||
|
||||
public IslandInformation(Point2 islandOrigin, Set<Point2> islandCoordinates, Set<Point2> edgeCoordinates, Set<Point2> chunksUsed) {
|
||||
this.islandCoordinates = Collections.unmodifiableSet(islandCoordinates);
|
||||
this.chunkSpan = Collections.unmodifiableSet(chunksUsed);
|
||||
this.edgeCoordinates = Collections.unmodifiableSet(edgeCoordinates);
|
||||
this.islandOrigin = islandOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a set that represents all coordinates within this island.
|
||||
*/
|
||||
public Set<Point2> getIslandCoordinates() {
|
||||
return islandCoordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a set of chunks that this island spans.
|
||||
*/
|
||||
public Set<Point2> getChunkSpan() {
|
||||
return chunkSpan;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a set of points that represent all the edges of this island.
|
||||
*/
|
||||
public Set<Point2> getEdgeCoordinates() {
|
||||
return edgeCoordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ownerUUID the UUID of the player owner of this island. May be null.
|
||||
*/
|
||||
public void setOwnerUUID(UUID ownerUUID) {
|
||||
this.ownerUUID = ownerUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the islandOrigin
|
||||
*/
|
||||
public Point2 getIslandOrigin() {
|
||||
return islandOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the UUID of the player owner of this island. May be null.
|
||||
*/
|
||||
public UUID getOwnerUUID() {
|
||||
return ownerUUID;
|
||||
}
|
||||
|
||||
public boolean isWithinIsland(Point2 coordinates) {
|
||||
return islandCoordinates.contains(coordinates);
|
||||
}
|
||||
|
||||
public boolean isEdgeOfIsland(Point2 coordinates) {
|
||||
return edgeCoordinates.contains(coordinates);
|
||||
}
|
||||
|
||||
public boolean isIslandInChunk(Point2 chunkCoords) {
|
||||
return chunkSpan.contains(chunkCoords);
|
||||
}
|
||||
|
||||
public int getIslandSize() {
|
||||
return islandCoordinates.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return islandOrigin.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof IslandInformation) {
|
||||
return islandOrigin.equals(((IslandInformation) obj).getIslandOrigin());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.Information;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public class IslandInformationBuilder {
|
||||
private final HashSet<Point2> islandCoordinates = new HashSet<>();
|
||||
private final HashSet<Point2> edgeCoordinates = new HashSet<>();
|
||||
private final HashSet<Point2> chunksUsed = new HashSet<>();
|
||||
private boolean built = false;
|
||||
|
||||
public boolean addCoordinate(Point2 coordinate, boolean isEdge) {
|
||||
if (coordinate == null) throw new NullPointerException("Coordinate cannot be null!");
|
||||
if (built) throw new IllegalStateException("Island information has already been built!");
|
||||
if (isEdge) edgeCoordinates.add(coordinate);
|
||||
return islandCoordinates.add(coordinate);
|
||||
}
|
||||
|
||||
public boolean addChunk(Point2 chunkCoordinate) {
|
||||
if (chunkCoordinate == null) throw new NullPointerException("Chunk coordinate cannot be null!");
|
||||
if (built) throw new IllegalStateException("Island information has already been built!");
|
||||
return chunksUsed.add(chunkCoordinate);
|
||||
}
|
||||
|
||||
public IslandInformation build(Point2 islandOrigin) {
|
||||
if (islandOrigin == null) throw new NullPointerException("IslandOrigin cannot be null.");
|
||||
if (built) throw new IllegalStateException("This island informationh as already been built!");
|
||||
built = true;
|
||||
return new IslandInformation(islandOrigin, islandCoordinates, edgeCoordinates, chunksUsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the chunksUsed
|
||||
*/
|
||||
public HashSet<Point2> getChunksUsed() {
|
||||
return chunksUsed;
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.Information;
|
||||
|
||||
import java.lang.Thread.State;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import net.reslate.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
|
||||
public class IslandInformationManager implements Runnable {
|
||||
private final IslandWorldMap islandMap;
|
||||
private final Thread loader;
|
||||
private final Cache<Point2, CompletableFuture<HashSet<IslandInformation>>> buildingCache = new Cache<>();
|
||||
private final ConcurrentHashMap<Point2, HashSet<IslandInformation>> islandSets = new ConcurrentHashMap<>();
|
||||
|
||||
public IslandInformationManager(IslandWorldMap islandWorldMap) {
|
||||
this.islandMap = islandWorldMap;
|
||||
loader = new Thread(this);
|
||||
loader.setDaemon(true);
|
||||
loader.setName("Island-Info-Builder");
|
||||
loader.setPriority(Thread.MIN_PRIORITY);
|
||||
loader.start();
|
||||
}
|
||||
|
||||
private HashSet<IslandInformation> buildChunkIslandInformation(Point2 chunkCoords) {
|
||||
HashSet<IslandInformation> result = new HashSet<>();
|
||||
Point2[] surroundings = new Point2[4];
|
||||
surroundings[0] = chunkCoords.shift(1, 0);
|
||||
surroundings[1] = chunkCoords.shift(-1, 0);
|
||||
surroundings[2] = chunkCoords.shift(0, -1);
|
||||
surroundings[3] = chunkCoords.shift(0, 1);
|
||||
HashSet<Point2> checkedCoordinates = new HashSet<>();
|
||||
for (Point2 surrounding : surroundings) {
|
||||
if (Thread.currentThread().isInterrupted())
|
||||
return null;
|
||||
HashSet<IslandInformation> chunkIslandSet = islandSets.get(surrounding);
|
||||
if (chunkIslandSet != null) {
|
||||
for (IslandInformation islandInformation : chunkIslandSet) {
|
||||
if (islandInformation.isIslandInChunk(chunkCoords)) {
|
||||
checkedCoordinates.addAll(islandInformation.getIslandCoordinates());
|
||||
result.add(islandInformation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = 0; x < GeneralUtilities.CHUNK_SIZE; x++) {
|
||||
for (int z = 0; z < GeneralUtilities.CHUNK_SIZE; z++) {
|
||||
if (Thread.currentThread().isInterrupted())
|
||||
return null;
|
||||
int worldX = chunkCoords.x * GeneralUtilities.CHUNK_SIZE + x;
|
||||
int worldZ = chunkCoords.y * GeneralUtilities.CHUNK_SIZE + z;
|
||||
if (islandMap.isIsland(worldX, worldZ)) {
|
||||
IslandInformationBuilder infoBuilder = new IslandInformationBuilder();
|
||||
Point2 origin = islandMap.findIslandOrigin(worldX, worldZ, (p) -> {
|
||||
if (Thread.currentThread().isInterrupted())
|
||||
return true;
|
||||
if (!checkedCoordinates.add(p))
|
||||
return true;
|
||||
|
||||
HashSet<IslandInformation> chunkIslandSet = islandSets.get(GeneralUtilities.worldToChunkCoordinates(p));
|
||||
if (chunkIslandSet != null) {
|
||||
for (IslandInformation islandInformation : chunkIslandSet) {
|
||||
if (islandInformation.isIslandInChunk(chunkCoords)) {
|
||||
checkedCoordinates.addAll(islandInformation.getIslandCoordinates());
|
||||
result.add(islandInformation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
infoBuilder.addCoordinate(p, islandMap.isEdgeOfIsland(p.x, p.y));
|
||||
infoBuilder.addChunk(GeneralUtilities.worldToChunkCoordinates(p));
|
||||
return false;
|
||||
});
|
||||
if (origin != null) {
|
||||
IslandInformation islandInfo = infoBuilder.build(origin);
|
||||
result.add(islandInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void loadChunkIslandInformation(Point2 chunkCoords) {
|
||||
CompletableFuture<HashSet<IslandInformation>> completableFuture = new CompletableFuture<>();
|
||||
buildingCache.set(chunkCoords, completableFuture);
|
||||
if (loader.getState() == State.WAITING) {
|
||||
synchronized (loader) {
|
||||
loader.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadChunkIslandInformation(Point2 chunkCoords) {
|
||||
if (buildingCache.contains(chunkCoords))
|
||||
buildingCache.remove(chunkCoords).cancel(true);
|
||||
islandSets.remove(chunkCoords);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the island information for the given coordinates.
|
||||
*
|
||||
* @param coords The coordinates to check for island information.
|
||||
* @param checkLoading Whether or not to check for the currently loading chunks.
|
||||
* @return The island information or null if there is no island at those
|
||||
* coordinates.
|
||||
*/
|
||||
public IslandInformation getIslandInformation(Point2 coords, boolean checkLoading) {
|
||||
Point2 chunkCoords = GeneralUtilities.worldToChunkCoordinates(coords);
|
||||
if (!islandSets.containsKey(chunkCoords)) {
|
||||
if (checkLoading && buildingCache.contains(chunkCoords)) {
|
||||
try {
|
||||
buildingCache.get(chunkCoords).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<IslandInformation> chunkIslands = islandSets.get(chunkCoords);
|
||||
|
||||
if (chunkIslands != null) {
|
||||
for (IslandInformation islandInformation : chunkIslands) {
|
||||
if (islandInformation.isWithinIsland(coords))
|
||||
return islandInformation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isChunkIslandInformationLoaded(Point2 chunkCoords, boolean checkLoading) {
|
||||
return islandSets.containsKey(chunkCoords) || buildingCache.contains(chunkCoords);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
while (buildingCache.size() > 0) {
|
||||
Point2 chunkCoords = buildingCache.getMostRecentKey();
|
||||
CompletableFuture<HashSet<IslandInformation>> future = buildingCache.remove(chunkCoords);
|
||||
HashSet<IslandInformation> islandInfos = buildChunkIslandInformation(chunkCoords);
|
||||
islandSets.put(chunkCoords, islandInfos);
|
||||
future.complete(islandInfos);
|
||||
}
|
||||
try {
|
||||
synchronized (loader) {
|
||||
loader.wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.util.noise.SimplexOctaveGenerator;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Reference;
|
||||
import net.reslate.islandsurvivalcraft.utilities.pathfinding.CoordinateValidatable;
|
||||
import net.reslate.islandsurvivalcraft.utilities.pathfinding.DepthFirstSearch;
|
||||
|
||||
public class IslandWorldMap {
|
||||
private final float SHALLOW_PORTION = 0.06f;
|
||||
private final float TRANSITION_DEPTH_PORTION = 0.1f;
|
||||
private final float DEEP_OCEAN_PORTION = 0.5f;
|
||||
private final float HILL_PORTION = 0.4f;
|
||||
private final float SHORE_PORTION = 0.095f;
|
||||
|
||||
private final Cache<Point2, Double> blockValueCache;
|
||||
private final SimplexOctaveGenerator noiseGenerator;
|
||||
public final islandValidator islandValidator = new islandValidator();
|
||||
private final int NOISE_OCTAVES = 4;
|
||||
private final float ISLAND_PERCENT = 0.36f;
|
||||
private final double NOISE_FREQ = 1.78D;
|
||||
private final double NOISE_AMP = 0.47D;
|
||||
private final double SCALE = 0.005D;
|
||||
|
||||
public IslandWorldMap(Random random) {
|
||||
this.noiseGenerator = new SimplexOctaveGenerator(random, NOISE_OCTAVES);
|
||||
noiseGenerator.setScale(SCALE);
|
||||
this.blockValueCache = new Cache<>(256000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Considers this land if the world block value is greater than or equal to 0.
|
||||
* @param worldX the X coordinate of location in world.
|
||||
* @param worldZ the Z coordinate of location in world.
|
||||
* @return
|
||||
*/
|
||||
public boolean isLand(int worldX, int worldZ) {
|
||||
if (getWorldValue(worldX, worldZ) >= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates if this is the edge of the island by checking if it's surrounding blocks are part of this island.
|
||||
* @param worldX The world X coordinate.
|
||||
* @param worldZ The world Z coordinate.
|
||||
* @return true if it is the edge of the island and false if it isn't.
|
||||
*/
|
||||
public boolean isEdgeOfIsland(int worldX, int worldZ) {
|
||||
return isIsland(worldX, worldZ) &&
|
||||
!(isIsland(worldX + 1, worldZ) &&
|
||||
isIsland(worldX - 1, worldZ) &&
|
||||
isIsland(worldX , worldZ + 1) &&
|
||||
isIsland(worldX, worldZ - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Considers these coordinates to be part of an island if:
|
||||
* It is land, or if it is a shallow portion of land.
|
||||
* @param worldX the X coordinate of location in world.
|
||||
* @param worldZ the Y coordinate of location in world.
|
||||
* @return true if these coordinates represent an island.
|
||||
*/
|
||||
public boolean isIsland(int worldX, int worldZ) {
|
||||
return isLand(worldX, worldZ) || isShallowPortion(worldX, worldZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks coordinates for if this location is a hill.
|
||||
* It is considered a hill when its world value is greater than the HILL_PORTION.
|
||||
* @param worldX
|
||||
* @param worldZ
|
||||
* @return
|
||||
*/
|
||||
public boolean isHill(int worldX, int worldZ) {
|
||||
return getWorldValue(worldX, worldZ) >= HILL_PORTION;
|
||||
}
|
||||
|
||||
public boolean isShore(int worldX, int worldZ) {
|
||||
return isLand(worldX, worldZ) && getWorldValue(worldX, worldZ) <= SHORE_PORTION;
|
||||
}
|
||||
|
||||
public boolean isTransitional(int worldX, int worldZ) {
|
||||
return !isIsland(worldX, worldZ) && getWorldValue(worldX, worldZ) >= -TRANSITION_DEPTH_PORTION;
|
||||
}
|
||||
|
||||
public boolean isDeep(int worldX, int worldZ) {
|
||||
return getWorldValue(worldX, worldZ) <= -DEEP_OCEAN_PORTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* This block is considered a shallow portion of the island:
|
||||
* The block height is less than the sea level,
|
||||
* and that the block height is greater than the shallow portion.
|
||||
* If it is land, it is not shallow.
|
||||
* @param worldX the X coordinate of location in world.
|
||||
* @param worldZ the Z coordinate of location in world.
|
||||
* @return true if it is considered the shallow portion.
|
||||
*/
|
||||
public boolean isShallowPortion(int worldX, int worldZ) {
|
||||
if (!isLand(worldX, worldZ) && getWorldValue(worldX, worldZ) >= -SHALLOW_PORTION) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* World block value will be 0 or positive if it is a part of an island.
|
||||
* If less than, it is considered under the sea.
|
||||
* Does not factor in a shallow depth.
|
||||
* The value is normalized to [-1, 1].
|
||||
* @param worldX the x world coordinate to obtain this value for.
|
||||
* @param worldZ the z world coordinate to obtain this value for.
|
||||
* @return a value representing the island at the given point.
|
||||
*/
|
||||
public double getWorldValue(int worldX, int worldZ) {
|
||||
Point2 p = new Point2(worldX, worldZ);
|
||||
|
||||
Double res = blockValueCache.get(p);
|
||||
if (res == null) {
|
||||
double shift = 1f - 2f * ISLAND_PERCENT;
|
||||
double rawNoise = noiseGenerator.noise(worldX, worldZ, NOISE_FREQ, NOISE_AMP, true) - shift;
|
||||
double maxNeg = -1 - shift;
|
||||
double maxPos = 1 - shift;
|
||||
|
||||
if (rawNoise < 0) {
|
||||
res = - rawNoise / maxNeg;
|
||||
} else {
|
||||
res = rawNoise / maxPos;
|
||||
}
|
||||
blockValueCache.set(p, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines of the two columns are part of the same island.
|
||||
* If both points are connected consistently by island, than both are considered part of the same island.
|
||||
* @param firstColumn The column of the first island.
|
||||
* @param secondColumn The column of the second island.
|
||||
* @return If the two islands are connected.
|
||||
*/
|
||||
public boolean isSameIsland(Point2 firstColumn, Point2 secondColumn) {
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(firstColumn, secondColumn);
|
||||
boolean same = dfs.buildToGoal(islandValidator, null);
|
||||
return same;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the island's origin block. Will call the coordinate target validatable to end early if nessecary.
|
||||
* @param worldX The x coordinate of the island block in question.
|
||||
* @param worldZ The y coordinate of the island block in question.
|
||||
* @param targetValidator The coordinate target validator to use. May be null.
|
||||
* @return The island origin point. Will be null if the passed target target validator stops search prematurely.
|
||||
*/
|
||||
public Point2 findIslandOrigin(int worldX, int worldZ, CoordinateValidatable targetValidator) {
|
||||
if (!isIsland(worldX, worldZ)) throw new IllegalArgumentException("The given coordinates are not part is an island.");
|
||||
final Point2 goal = new Point2(0, 0);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(worldX, worldZ), goal);
|
||||
Reference<Point2> closest = new Reference<>();
|
||||
dfs.buildToGoal(islandValidator, new CoordinateValidatable() {
|
||||
Double closestDistance = null;
|
||||
@Override
|
||||
public boolean validate(Point2 point) {
|
||||
if (targetValidator != null && targetValidator.validate(point)) {
|
||||
closest.value = null;
|
||||
return true;
|
||||
}
|
||||
double currentDistance = point.distance(goal);
|
||||
if (closestDistance == null || (currentDistance) < closestDistance) {
|
||||
closestDistance = currentDistance;
|
||||
closest.value = point;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return closest.value;
|
||||
}
|
||||
|
||||
public Point2 findIslandOrigin(int worldX, int worldZ) {
|
||||
return findIslandOrigin(worldX, worldZ, null);
|
||||
}
|
||||
|
||||
public int calculateIslandHash(int worldX, int worldZ) {
|
||||
return findIslandOrigin(worldX, worldZ).hashCode();
|
||||
}
|
||||
|
||||
private class islandValidator implements CoordinateValidatable {
|
||||
|
||||
@Override
|
||||
public boolean validate(Point2 point) {
|
||||
return isIsland(point.x, point.y);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.util.noise.SimplexOctaveGenerator;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
public class TemperatureMap {
|
||||
|
||||
private final Cache<Point2, Float> temperatureCache;
|
||||
private final double frequency = 0.5D;
|
||||
private final double amplitude = 0.5D;
|
||||
|
||||
private volatile SimplexOctaveGenerator noiseGenerator;
|
||||
|
||||
public TemperatureMap(Random random) {
|
||||
temperatureCache = new Cache<>(1024);
|
||||
noiseGenerator = new SimplexOctaveGenerator(random, 2);
|
||||
noiseGenerator.setScale(0.001D);
|
||||
}
|
||||
|
||||
public float getTemperature(int worldX, int worldZ) {
|
||||
Point2 loc = new Point2(worldX, worldZ);
|
||||
Float val = temperatureCache.get(loc);
|
||||
if (val == null) {
|
||||
val = (float) (((noiseGenerator.noise(worldX, worldZ, frequency, amplitude, true) + 1D) / 2D) * 3D - 1D);
|
||||
temperatureCache.set(loc, val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.world.Information.IslandInformationManager;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.chunks.IslandWorldChunkGenerator;
|
||||
|
||||
public class WorldInfo {
|
||||
private final WorldInfoManager manager;
|
||||
private volatile IslandInformationManager islandInfoManager;
|
||||
private volatile Random random;
|
||||
private volatile int seaLevel;
|
||||
private volatile int worldHeight;
|
||||
private volatile boolean initialized;
|
||||
private volatile long seed;
|
||||
private volatile BiomeMap biomeMap;
|
||||
private volatile TemperatureMap tempMap;
|
||||
private volatile IslandWorldMap islandMap;
|
||||
private volatile IslandWorldChunkGenerator generator;
|
||||
|
||||
/**
|
||||
* Will initialize with the known information extracted from the given world if
|
||||
* world is not null. If the world is null, this world info will not be
|
||||
* initialized and awaits initialization from the generator.
|
||||
*
|
||||
* @param world The world this object is describing. May be null to create a
|
||||
* non-initialized info object.
|
||||
*/
|
||||
public WorldInfo(WorldInfoManager manager) {
|
||||
this.manager = manager;
|
||||
this.generator = new IslandWorldChunkGenerator(this);
|
||||
}
|
||||
|
||||
public void initialize(World world) {
|
||||
if (initialized)
|
||||
throw new IllegalStateException("This world information object has already been initialized.");
|
||||
if (world == null) throw new NullPointerException("The world argument cannot be null.");
|
||||
this.initialized = true;
|
||||
this.seed = world.getSeed();
|
||||
this.random = new Random(seed);
|
||||
this.biomeMap = new BiomeMap(random);
|
||||
this.tempMap = new TemperatureMap(random);
|
||||
this.islandMap = new IslandWorldMap(random);
|
||||
this.islandInfoManager = new IslandInformationManager(islandMap);
|
||||
this.worldHeight = world.getMaxHeight();
|
||||
this.seaLevel = world.getSeaLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether or not this world info is initialized.
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the islandInfoManager
|
||||
*/
|
||||
public IslandInformationManager getIslandInfoManager() {
|
||||
return islandInfoManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the biomeMap
|
||||
*/
|
||||
public BiomeMap getBiomeMap() {
|
||||
return biomeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the generator
|
||||
*/
|
||||
public IslandWorldChunkGenerator getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the islandMap
|
||||
*/
|
||||
public IslandWorldMap getIslandMap() {
|
||||
return islandMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the manager
|
||||
*/
|
||||
public WorldInfoManager getManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the random
|
||||
*/
|
||||
public Random getRandom() {
|
||||
return random;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the seaLevel
|
||||
*/
|
||||
public int getSeaLevel() {
|
||||
return seaLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the seed
|
||||
*/
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tempMap
|
||||
*/
|
||||
public TemperatureMap getTempMap() {
|
||||
return tempMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the worldHeight
|
||||
*/
|
||||
public int getWorldHeight() {
|
||||
return worldHeight;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.lang.NullArgumentException;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.GeneratorModes;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.chunks.IslandWorldChunkGenerator;
|
||||
|
||||
public class WorldInfoManager implements Listener {
|
||||
public final ConcurrentHashMap<String, WorldInfo> worldInformation = new ConcurrentHashMap<>();
|
||||
|
||||
public WorldInfoManager() {
|
||||
}
|
||||
/**
|
||||
* Return the world info requested for the given world.
|
||||
* Should not be null.
|
||||
* @param world The world the associated info is to be requested for.
|
||||
* @return The world info.
|
||||
*/
|
||||
public WorldInfo retrieve(String worldName) {
|
||||
if (worldName == null) throw new NullArgumentException("world");
|
||||
return worldInformation.computeIfAbsent(worldName, (name) -> {
|
||||
return new WorldInfo(this);
|
||||
});
|
||||
}
|
||||
|
||||
public ChunkGenerator getChunkGenerator(String worldName, GeneratorModes mode) {
|
||||
IslandWorldChunkGenerator islandWorldChunkGenerator = retrieve(worldName).getGenerator();
|
||||
if (!islandWorldChunkGenerator.isInitialized()) islandWorldChunkGenerator.setGeneratorType(mode);
|
||||
return islandWorldChunkGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the manager deleting all currently loaded world info from memory.
|
||||
*/
|
||||
public void reset() {
|
||||
worldInformation.clear();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
Chunk chunk = event.getChunk();
|
||||
if (!worldInformation.containsKey(event.getWorld().getName())) return;
|
||||
WorldInfo worldInfo = retrieve(event.getWorld().getName());
|
||||
if (!worldInfo.isInitialized()) worldInfo.initialize(event.getWorld());
|
||||
worldInfo.getIslandInfoManager().loadChunkIslandInformation(new Point2(chunk.getX(), chunk.getZ()));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onChunkUnload(ChunkUnloadEvent event) {
|
||||
Chunk chunk = event.getChunk();
|
||||
if (!worldInformation.containsKey(event.getWorld().getName())) return;
|
||||
WorldInfo worldInfo = retrieve(event.getWorld().getName());
|
||||
if (!worldInfo.isInitialized()) worldInfo.initialize(event.getWorld());
|
||||
worldInfo.getIslandInfoManager().unloadChunkIslandInformation(new Point2(chunk.getX(), chunk.getZ()));
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.generation;
|
||||
|
||||
public enum GeneratorModes {
|
||||
UNIQUE
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.generation.biomes;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.world.BiomeMap;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
import net.reslate.islandsurvivalcraft.world.TemperatureMap;
|
||||
|
||||
public interface BiomeGenerator {
|
||||
|
||||
/**
|
||||
* Given a biome array, requests for it to be saturated by the IslandWorldChunkGenerator.
|
||||
* The array should store the columns of biomes for the entire chunk.
|
||||
* It doesn't need to be populated on the first call as this method will be called once for every column in the chunk.
|
||||
* However, if some biomes can be set without repetative calls, doing so will prevent this method from being called for those locals.
|
||||
*
|
||||
* @param localBiomeInfo The array of biomes that are to be saturated. First two arrays represent the x and y values, and the third represents the biome set.
|
||||
* @param chunkX The X coordinate of the chunk.
|
||||
* @param chunkZ The Z coordinate of the chunk.
|
||||
* @param localX The X coordinate of the column within the chunk.
|
||||
* @param localZ The Z coordinate of the column within the chunk.
|
||||
* @param islandMap The island mapper to be used.
|
||||
* @param tempGenerator The temperature generator to be used.
|
||||
* @param biomeCache Cache for biomes.
|
||||
* @param chunkGenCache Cache for whether or not the chunk is generated.
|
||||
*/
|
||||
public void generateBiomeColumn(BiomeInfo[][] localBiomeInfo, int chunkX, int chunkZ, int localX, int localZ, IslandWorldMap islandMap, BiomeMap biomeSelector, TemperatureMap tempGenerator, Cache<Point2, BiomeInfo> biomeCache);
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.generation.biomes;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Reference;
|
||||
import net.reslate.islandsurvivalcraft.utilities.drawing.Flooder;
|
||||
import net.reslate.islandsurvivalcraft.utilities.pathfinding.CoordinateValidatable;
|
||||
import net.reslate.islandsurvivalcraft.world.BiomeMap;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
import net.reslate.islandsurvivalcraft.world.TemperatureMap;
|
||||
|
||||
public class UniqueBiomeGenerator implements BiomeGenerator {
|
||||
|
||||
@Override
|
||||
public void generateBiomeColumn(BiomeInfo[][] localBiomeInfo, int chunkX, int chunkZ, int localX, int localZ,
|
||||
IslandWorldMap islandMap, BiomeMap biomeSelector, TemperatureMap tempGenerator,
|
||||
Cache<Point2, BiomeInfo> biomeCache) {
|
||||
int worldX = 16 * chunkX + localX;
|
||||
int worldZ = 16 * chunkZ + localZ;
|
||||
Point2 worldCoords = new Point2(worldX, worldZ);
|
||||
|
||||
localBiomeInfo[localX][localZ] = biomeCache.get(worldCoords);
|
||||
if (localBiomeInfo[localX][localZ] != null) return;
|
||||
|
||||
float temperature = tempGenerator.getTemperature(worldX, worldZ);
|
||||
if (!islandMap.isIsland(worldX, worldZ)) {
|
||||
BiomeInfo oceanInfo = biomeSelector.getOceanBiome(temperature);
|
||||
localBiomeInfo[localX][localZ] = oceanInfo;
|
||||
biomeCache.set(worldCoords, oceanInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference<BiomeInfo> currentIslandInfo = new Reference<>();
|
||||
Point2 islandOrigin = islandMap.findIslandOrigin(worldX, worldZ, new CoordinateValidatable() {
|
||||
@Override
|
||||
public boolean validate(Point2 coord) {
|
||||
BiomeInfo info = biomeCache.get(coord);
|
||||
if (info == null) return false;
|
||||
currentIslandInfo.value = info;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (currentIslandInfo.value == null) {
|
||||
temperature = tempGenerator.getTemperature(islandOrigin.x, islandOrigin.y);
|
||||
currentIslandInfo.value = biomeSelector.getLandBiomeInfo(temperature, islandOrigin.x, islandOrigin.y);
|
||||
}
|
||||
Flooder flooder = new Flooder(worldCoords, new CoordinateValidatable() {
|
||||
@Override
|
||||
public boolean validate(Point2 point) {
|
||||
Point2 chunkCoords = GeneralUtilities.worldToChunkCoordinates(point);
|
||||
if (chunkCoords.x != chunkX || chunkCoords.y != chunkZ || !islandMap.isIsland(point.x, point.y)) return false;
|
||||
biomeCache.set(point, currentIslandInfo.value);
|
||||
Point2 localCoords = GeneralUtilities.worldToLocalChunkCoordinates(point);
|
||||
localBiomeInfo[localCoords.x][localCoords.y] = currentIslandInfo.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
flooder.start();
|
||||
}
|
||||
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.generation.chunks;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.LandBiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.OceanBiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.world.BiomeMap;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
import net.reslate.islandsurvivalcraft.world.TemperatureMap;
|
||||
import net.reslate.islandsurvivalcraft.world.WorldInfo;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.GeneratorModes;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.biomes.BiomeGenerator;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.biomes.UniqueBiomeGenerator;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.shaders.WorldHeightShader;
|
||||
import net.reslate.islandsurvivalcraft.world.generation.shaders.WorldLayerShader;
|
||||
|
||||
public class IslandWorldChunkGenerator extends ChunkGenerator implements Listener {
|
||||
private final int BEDROCK_HEIGHT = 5;
|
||||
private volatile GeneratorModes generatorType;
|
||||
private volatile boolean initialized = false;
|
||||
private volatile WorldInfo worldInfo;
|
||||
private volatile IslandWorldMap islandMap;
|
||||
private volatile TemperatureMap temperatureMap;
|
||||
private volatile BiomeMap biomeMap;
|
||||
private volatile BiomeGenerator biomeGenerator;
|
||||
private volatile WorldHeightShader heightShader;
|
||||
private volatile WorldLayerShader layerShader;
|
||||
private volatile Cache<Point2, BiomeInfo> biomeCache = new Cache<>(131072);
|
||||
private final ExecutorService exAlpha = GeneralUtilities.ISC_EXECUTOR_ALPHA;
|
||||
|
||||
public void initialize() {
|
||||
if (initialized) throw new IllegalStateException("This generator has already been initialized.");
|
||||
initialized = true;
|
||||
this.islandMap = worldInfo.getIslandMap();
|
||||
this.temperatureMap = worldInfo.getTempMap();
|
||||
this.biomeMap = worldInfo.getBiomeMap();
|
||||
this.heightShader = new WorldHeightShader(worldInfo.getRandom(), islandMap, worldInfo.getSeaLevel(), worldInfo.getWorldHeight(), BEDROCK_HEIGHT + 1);
|
||||
this.layerShader = new WorldLayerShader(worldInfo.getRandom(), worldInfo.getSeaLevel(), worldInfo.getWorldHeight(), islandMap);
|
||||
|
||||
if (generatorType == GeneratorModes.UNIQUE) {
|
||||
biomeGenerator = new UniqueBiomeGenerator();
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param generatorType the gID to set to.
|
||||
*/
|
||||
public void setGeneratorType(GeneratorModes generatorType) {
|
||||
if (initialized) throw new IllegalStateException("This generator has already been initialized.");
|
||||
this.generatorType = generatorType;
|
||||
}
|
||||
|
||||
public IslandWorldChunkGenerator(WorldInfo worldInfo) {
|
||||
this.worldInfo = worldInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biomeGrid) {
|
||||
if (!worldInfo.isInitialized()) {
|
||||
worldInfo.initialize(world);
|
||||
}
|
||||
if (!isInitialized()) initialize();
|
||||
if (!initialized) throw new IllegalStateException("This generator has not been initialized.");
|
||||
Future<Boolean> preLoader = exAlpha.submit(() -> {
|
||||
for (int x = GeneralUtilities.CHUNK_SIZE - 1; x >= 0; x--) {
|
||||
for (int z = GeneralUtilities.CHUNK_SIZE - 1; z >= 0; z--) {
|
||||
if (Thread.currentThread().isInterrupted()) return false;
|
||||
islandMap.getWorldValue(GeneralUtilities.CHUNK_SIZE * chunkX + x, GeneralUtilities.CHUNK_SIZE * chunkZ + z);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
ChunkData chunkData = createChunkData(world);
|
||||
|
||||
BiomeInfo[][] localBiomeInfos = new BiomeInfo[GeneralUtilities.CHUNK_SIZE][GeneralUtilities.CHUNK_SIZE];
|
||||
for (int x = 0; x < GeneralUtilities.CHUNK_SIZE; x++) {
|
||||
for (int z = 0; z < GeneralUtilities.CHUNK_SIZE; z++) {
|
||||
final int localX = x;
|
||||
final int localZ = z;
|
||||
final int worldX = GeneralUtilities.CHUNK_SIZE * chunkX + localX;
|
||||
final int worldZ = GeneralUtilities.CHUNK_SIZE * chunkZ + localZ;
|
||||
if (localBiomeInfos[localX][localZ] == null) {
|
||||
biomeGenerator.generateBiomeColumn(localBiomeInfos, chunkX, chunkZ, localX, localZ, islandMap, biomeMap,
|
||||
temperatureMap, biomeCache);
|
||||
}
|
||||
if (localBiomeInfos[localX][localZ] == null) throw new IllegalStateException("Biome column produced was null.");
|
||||
Biome currentBiome = null;
|
||||
|
||||
BiomeInfo biomeInfo = localBiomeInfos[localX][localZ];
|
||||
if (islandMap.isHill(worldX, worldZ)) {
|
||||
currentBiome = ((LandBiomeInfo) biomeInfo).getHillBiome();
|
||||
} else if (islandMap.isShore(worldX, worldZ)) {
|
||||
currentBiome = ((LandBiomeInfo) biomeInfo).getShoreBiome();
|
||||
} else if (islandMap.isShallowPortion(worldX, worldZ)) {
|
||||
currentBiome = ((LandBiomeInfo) biomeInfo).getShoreBiome();
|
||||
} else if (islandMap.isLand(worldX, worldZ)) {
|
||||
currentBiome = biomeInfo.getMainBiome();
|
||||
} else if (islandMap.isTransitional(worldX, worldZ)) {
|
||||
currentBiome = biomeInfo.getTransitionBiome();
|
||||
} else if (islandMap.isDeep(worldX, worldZ)) {
|
||||
currentBiome = ((OceanBiomeInfo) biomeInfo).getDeepAlternative();
|
||||
} else {
|
||||
currentBiome = biomeInfo.getMainBiome();
|
||||
}
|
||||
|
||||
for (int y = 0; y < worldInfo.getWorldHeight(); y++) {
|
||||
biomeGrid.setBiome(localX, y, localZ, currentBiome);
|
||||
|
||||
}
|
||||
|
||||
BiomeInfo currentBiomeInfo = localBiomeInfos[localX][localZ];
|
||||
int terrainHeight = heightShader.getTerrainHeight(worldX, worldZ, currentBiomeInfo);
|
||||
int currentTerrainHeight = terrainHeight - 1;
|
||||
int bedrockHeight = random.nextInt(5) + 1;
|
||||
if (layerShader.hasSpecialLayers(currentBiome)) {
|
||||
BlockData currentMaterial = layerShader.getMaterialForHeight(worldInfo.getSeed(), worldX, worldZ, currentTerrainHeight, terrainHeight - 1, currentBiome);
|
||||
while (currentMaterial != null) {
|
||||
chunkData.setBlock(localX, currentTerrainHeight, localZ, currentMaterial);
|
||||
currentTerrainHeight--;
|
||||
currentMaterial = layerShader.getMaterialForHeight(worldInfo.getSeed(), worldX, worldZ, currentTerrainHeight, terrainHeight - 1, currentBiome);
|
||||
}
|
||||
} else {
|
||||
int surfaceThickness = layerShader.getSurfaceThickness(worldX, worldZ, currentBiome);
|
||||
currentTerrainHeight = currentTerrainHeight - surfaceThickness;
|
||||
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + surfaceThickness + 1, localZ + 1, layerShader.getSurfaceMaterial(currentBiome));
|
||||
int transitionThickness = layerShader.getTransitionMaterialThickness(worldX, worldZ, currentBiome);
|
||||
currentTerrainHeight = currentTerrainHeight - transitionThickness;
|
||||
chunkData.setRegion(localX, currentTerrainHeight, localZ, localX + 1, currentTerrainHeight + transitionThickness + 1, localZ + 1, layerShader.getTransitionMaterial(currentBiome));
|
||||
}
|
||||
chunkData.setRegion(localX, bedrockHeight, localZ, localX + 1, currentTerrainHeight + 1, localZ + 1, Material.STONE);
|
||||
if (terrainHeight < worldInfo.getSeaLevel()) {
|
||||
chunkData.setRegion(localX, terrainHeight, localZ, localX + 1, worldInfo.getSeaLevel(), localZ + 1, Material.WATER);
|
||||
}
|
||||
chunkData.setRegion(localX, 0, localZ, localX + 1, bedrockHeight, localZ + 1, Material.BEDROCK);
|
||||
}
|
||||
}
|
||||
preLoader.cancel(false);
|
||||
return chunkData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if this generator has been initialized.
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSpawn(World world, int x, int z) {
|
||||
return islandMap.isLand(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getFixedSpawnLocation(World world, Random random) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateCaves() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateDecorations() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateStructures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParallelCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateMobs() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.generation.shaders;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.util.noise.SimplexOctaveGenerator;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
|
||||
public class WorldHeightShader {
|
||||
private final IslandWorldMap mapper;
|
||||
private final SimplexOctaveGenerator noiseGenerator;
|
||||
private final int seaLevel;
|
||||
private final int worldHeight;
|
||||
private final int minimumHeight;
|
||||
|
||||
public WorldHeightShader(Random random, IslandWorldMap islandLocator, int seaLevel, int worldHeight, int minimumHeight) {
|
||||
this.mapper = islandLocator;
|
||||
this.seaLevel = seaLevel;
|
||||
this.worldHeight = worldHeight;
|
||||
this.minimumHeight = minimumHeight;
|
||||
this.noiseGenerator = new SimplexOctaveGenerator(random, 8);
|
||||
this.noiseGenerator.setScale(0.0225d);
|
||||
}
|
||||
|
||||
public int getTerrainHeight(int worldX, int worldZ, BiomeInfo biomeInfo) {
|
||||
int height = 0;
|
||||
if (!mapper.isLand(worldX, worldZ)) {
|
||||
height = (int) Math.floor(calculateTerrainFactor(worldX, worldZ, seaLevel * 0.8d, 1.7d, 0.5d, 1d, 0.09d));
|
||||
} else {
|
||||
height = getIslandBiomeHeight(worldX, worldZ, biomeInfo.getMainBiome(), 0d);
|
||||
if (!mapper.isShore(worldX, worldZ)) height ++;
|
||||
}
|
||||
|
||||
height = Math.max(minimumHeight, height);
|
||||
if (height > worldHeight) throw new IllegalStateException(String.format("Resulting height is greater than world height! Current biome info: %s, maximum height: %d, minimum height %d", biomeInfo, worldHeight, minimumHeight));
|
||||
return height;
|
||||
}
|
||||
|
||||
private int getIslandBiomeHeight(int worldX, int worldZ, Biome biome, double heightModifier) {
|
||||
int res = 0;
|
||||
String biomeName = biome.name().toLowerCase();
|
||||
if (biomeName.contains("mountains")) {
|
||||
if (biomeName.contains("gravelly")) {
|
||||
res = (int) calculateTerrainFactor(worldX, worldZ, 100d + heightModifier, 1.8d, 0.8d);
|
||||
} else {
|
||||
res = (int) calculateTerrainFactor(worldX, worldZ, 180d + heightModifier, 1.88d, 0.5d);
|
||||
}
|
||||
} else if (biomeName.contains("plateau")) {
|
||||
res = (int) Math.min(calculateTerrainFactor(worldX, worldZ, 60d + heightModifier), seaLevel + 30d);
|
||||
} else if (biomeName.contains("modified")) {
|
||||
res = (int) calculateTerrainFactor(worldX, worldZ, 80d + heightModifier);
|
||||
} else if (biomeName.contains("shattered")) {
|
||||
res = (int) calculateTerrainFactor(worldX, worldZ, 90d + heightModifier);
|
||||
} else if (biomeName.contains("tall")) {
|
||||
res = (int) calculateTerrainFactor(worldX, worldZ, 80d + heightModifier);
|
||||
} else {
|
||||
res = (int) calculateTerrainFactor(worldX, worldZ, 35d + heightModifier);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private double calculateTerrainFactor(int worldX, int worldZ, double heightFactor, double freq, double amplitude, double shift, double exaggerationFactor) {
|
||||
double res = seaLevel;
|
||||
double shapeValue = (noiseGenerator.noise(worldX, worldZ, freq, amplitude, true) + shift) / (shift + 1d);
|
||||
if (shift == 1d && exaggerationFactor != 1d) shapeValue = Math.pow(shapeValue, exaggerationFactor);
|
||||
double islandValue = mapper.getWorldValue(worldX, worldZ);
|
||||
res += (islandValue) * (shapeValue * heightFactor);
|
||||
return res;
|
||||
}
|
||||
|
||||
private double calculateTerrainFactor(int worldX, int worldZ, double heightFactor, double freq, double amp) {
|
||||
return calculateTerrainFactor(worldX, worldZ, heightFactor, freq, amp, 0.75d, 1d);
|
||||
}
|
||||
|
||||
private double calculateTerrainFactor(int worldX, int worldZ, double heightFactor) {
|
||||
return calculateTerrainFactor(worldX, worldZ, heightFactor, 1.6d, 0.5d);
|
||||
}
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.generation.shaders;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.noise.SimplexOctaveGenerator;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Vector3;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class WorldLayerShader {
|
||||
private final Cache<Vector3, Double> noiseCache = new Cache<>(256);
|
||||
private final SimplexOctaveGenerator noiseGenerator;
|
||||
private final IslandWorldMap islandMap;
|
||||
private final int seaLevel, maxHeight;
|
||||
|
||||
|
||||
private final Material[] badlandTerrocota = new Material[] {
|
||||
Material.BLACK_TERRACOTTA,
|
||||
Material.BROWN_TERRACOTTA,
|
||||
Material.GRAY_TERRACOTTA,
|
||||
Material.LIGHT_GRAY_TERRACOTTA,
|
||||
Material.YELLOW_TERRACOTTA,
|
||||
Material.WHITE_TERRACOTTA
|
||||
};
|
||||
|
||||
public WorldLayerShader(Random random, int seaLevel, int maxHeight, IslandWorldMap islandMap) {
|
||||
this.islandMap = islandMap;
|
||||
this.seaLevel = seaLevel;
|
||||
this.maxHeight = maxHeight;
|
||||
this.noiseGenerator = new SimplexOctaveGenerator(random, 4);
|
||||
this.noiseGenerator.setScale(0.1d);
|
||||
}
|
||||
|
||||
public boolean hasSpecialLayers(Biome biome) {
|
||||
String biomeName = biome.toString().toLowerCase();
|
||||
return
|
||||
biomeName.contains("badlands") ||
|
||||
biomeName.contains("mountain");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the material for the height. If there are no more special materials, this will return null.
|
||||
*
|
||||
* @param seed The seed to use for special layer generation.
|
||||
* @param worldX The x world coordinate.
|
||||
* @param worldZ The z world coordinate.
|
||||
* @param y The current layer (AKA the y world coordinate).
|
||||
* @param highestPoint The y level of the top layer.
|
||||
* @param biomeSet The biomeset for the current column.
|
||||
* @return The block data for the material, or null if there are no further special materials.
|
||||
*/
|
||||
public BlockData getMaterialForHeight(long seed, int worldX, int worldZ, int y, int highestPoint, Biome currentBiome) {
|
||||
Biome mainBiome = currentBiome;
|
||||
String mainBiomeName = mainBiome.toString().toLowerCase();
|
||||
BlockData res = null;
|
||||
|
||||
if (mainBiomeName.contains("badlands")) {
|
||||
int seedOffset = (worldX + worldZ) / 1000;
|
||||
Random random = new Random(seed + seedOffset);
|
||||
random.setSeed(seed + seedOffset);
|
||||
int yInterval = (int) (random.nextFloat() * 9) + 1;
|
||||
int yBandInitial = (int) (seaLevel + random.nextDouble() * 50);
|
||||
|
||||
if (y > yBandInitial) {
|
||||
int amountOfLayers = Math.min(Math.max(1, random.nextInt(badlandTerrocota.length)), 4);
|
||||
int subLayer = y % yInterval;
|
||||
if (subLayer < amountOfLayers) {
|
||||
Material[] selected = new Material[amountOfLayers];
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
selected[i] = badlandTerrocota[random.nextInt(amountOfLayers)];
|
||||
}
|
||||
res = selected[subLayer].createBlockData();
|
||||
} else {
|
||||
res = Material.TERRACOTTA.createBlockData();
|
||||
}
|
||||
}
|
||||
} else if (mainBiomeName.contains("mountain")) {
|
||||
if (y > (maxHeight * 0.4d) - getNormalizedNoise(worldX, worldZ, 2.8f) * 8d) {
|
||||
res = Material.STONE.createBlockData();
|
||||
} else if (y > highestPoint - getSurfaceThickness(worldX, worldZ, mainBiome)) {
|
||||
res = getSurfaceMaterial(mainBiome).createBlockData();
|
||||
} else if (y > highestPoint - getSurfaceThickness(worldX, worldZ, mainBiome) - getTransitionMaterialThickness(worldX, worldZ, mainBiome)) {
|
||||
res = getTransitionMaterial(mainBiome).createBlockData();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public Material getSurfaceMaterial(Biome biome) {
|
||||
String biomeName = biome.toString().toLowerCase();
|
||||
if (biomeName.contains("beach") || biomeName.contains("desert") || biomeName.contains("warm_ocean")) {
|
||||
return Material.SAND;
|
||||
} else if (biome == Biome.ICE_SPIKES) {
|
||||
return Material.SNOW_BLOCK;
|
||||
} else if (biomeName.contains("ocean") || biomeName.contains("gravelly")) {
|
||||
return Material.GRAVEL;
|
||||
} else if (biomeName.contains("stone")) {
|
||||
return Material.STONE;
|
||||
}
|
||||
return Material.GRASS_BLOCK;
|
||||
}
|
||||
|
||||
public int getSurfaceThickness(int worldX, int worldZ, Biome biome) {
|
||||
String biomeName = biome.toString().toLowerCase();
|
||||
|
||||
if (biomeName.contains("beach") || biomeName.contains("desert")) {
|
||||
return (int) (getNormalizedNoise(worldX, worldZ, 1.3f) * 8) + 5;
|
||||
} else if (biomeName.contains("gravelly")) {
|
||||
return (int) (getNormalizedNoise(worldX, worldZ, 1.3f) * 5);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Material getTransitionMaterial(Biome biome) {
|
||||
String biomeName = biome.toString().toLowerCase();
|
||||
if (biomeName.contains("beach") || biomeName.contains("desert")) {
|
||||
return Material.SANDSTONE;
|
||||
} else if (biomeName.contains("gravelly") || biome == Biome.STONE_SHORE) {
|
||||
return Material.STONE;
|
||||
} else if (biomeName.contains("ocean")) {
|
||||
return Material.GRAVEL;
|
||||
}
|
||||
return Material.DIRT;
|
||||
}
|
||||
|
||||
public int getTransitionMaterialThickness(int worldX, int worldZ, Biome biome) {
|
||||
return (int) (getNormalizedNoise(worldX, worldZ, 1.3f) * 4) + 4;
|
||||
}
|
||||
|
||||
private double getNormalizedNoise(int worldX, int worldZ, float freq) {
|
||||
Vector3 key = new Vector3(worldX, worldZ, freq);
|
||||
Double res = noiseCache.get(key);
|
||||
if (res == null) {
|
||||
res = (noiseGenerator.noise(worldX, worldZ, freq, 0.5d) + 1d) / 2d;
|
||||
noiseCache.set(key, res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
name: IslandSurvivalCraft
|
||||
main: net.reslate.islandsurvivalcraft.IslandSurvivalCraft
|
||||
version: 1.0.0
|
||||
author: Reslate
|
||||
description: Adds the gamemode IslandSurvivalCraft.
|
||||
depend: []
|
||||
load: startup
|
||||
api-version: 1.15
|
||||
commands:
|
||||
IslandSurvivalCraft:
|
||||
aliases: [isc]
|
||||
description: The administration command for Island Survival Craft.
|
||||
usage: Type "/IslandSurvivalCraft help" (or any of its aliases) for a list of commands.
|
||||
permission: islandsurvivalcraft.admin
|
||||
permission-message: This command isn't needed for normal gameplay, and therefore, by default, only operators have access to it.
|
||||
permissions:
|
||||
islandsurvivalcraft.admin:
|
||||
description: Gives ability to configure and test Island Survival Craft features in game.
|
||||
default: op
|
@ -1,129 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class GeneralUtilitiesTest {
|
||||
/**
|
||||
* Basic hashmap inversion test.
|
||||
*/
|
||||
@Test
|
||||
public void testInvertHashMap()
|
||||
{
|
||||
HashMap<String, Integer> hashMap = new HashMap<>();
|
||||
hashMap.put("a", 1);
|
||||
hashMap.put("b", 1);
|
||||
hashMap.put("c", 2);
|
||||
hashMap.put("d", 2);
|
||||
|
||||
HashMap<Integer, ArrayList<String>> res = GeneralUtilities.invertHashMap(hashMap);
|
||||
ArrayList<String> first = res.get(1);
|
||||
ArrayList<String> expectedFirst = new ArrayList<>();
|
||||
expectedFirst.add("a");
|
||||
expectedFirst.add("b");
|
||||
|
||||
ArrayList<String> second = res.get(2);
|
||||
ArrayList<String> expectedSecond = new ArrayList<>();
|
||||
expectedSecond.add("c");
|
||||
expectedSecond.add("d");
|
||||
assertEquals(first, expectedFirst);
|
||||
assertEquals(second, expectedSecond);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMagnitudeAddPositive() {
|
||||
assertEquals(2, GeneralUtilities.addMagnitude(1, 1));
|
||||
}
|
||||
@Test
|
||||
public void testMagnitudeAddNegative() {
|
||||
assertEquals(-2, GeneralUtilities.addMagnitude(-1, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToChunkCoordinatesNegativePerfect() {
|
||||
assertEquals(new Point2(-4, -3), GeneralUtilities.worldToChunkCoordinates(-64, -48));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToChunkCoordinatesNegativeOff() {
|
||||
assertEquals(new Point2(-4, -3), GeneralUtilities.worldToChunkCoordinates(-55, -33));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToChunkCoordinatesNegativeOffClose() {
|
||||
assertEquals(new Point2(15, -15), GeneralUtilities.worldToChunkCoordinates(255, -227));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToChunkCoordinatesPositivePerfect() {
|
||||
assertEquals(new Point2(4, 5), GeneralUtilities.worldToChunkCoordinates(64, 80));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToChunkCoordinatesPositiveOff() {
|
||||
assertEquals(new Point2(4, 5), GeneralUtilities.worldToChunkCoordinates(67, 84));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToLocalCoordinatesNegative() {
|
||||
assertEquals(new Point2(2, 5), GeneralUtilities.worldToLocalChunkCoordinates(-62, -27));
|
||||
assertEquals(new Point2(2, 5), GeneralUtilities.worldToLocalChunkCoordinates(new Point2(-62, -27)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToLocalCoordinatesNegativePerfect() {
|
||||
assertEquals(new Point2(0, 0), GeneralUtilities.worldToLocalChunkCoordinates(-128, -32));
|
||||
assertEquals(new Point2(0, 0), GeneralUtilities.worldToLocalChunkCoordinates(new Point2(-256, -16)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToLocalCoordinatesPositive() {
|
||||
assertEquals(new Point2(7, 3), GeneralUtilities.worldToLocalChunkCoordinates(39, 83));
|
||||
assertEquals(new Point2(7, 3), GeneralUtilities.worldToLocalChunkCoordinates(new Point2(39, 83)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToLocalCoordinatesPositivePerfect() {
|
||||
assertEquals(new Point2(0, 0), GeneralUtilities.worldToLocalChunkCoordinates(1024, 32));
|
||||
assertEquals(new Point2(0, 0), GeneralUtilities.worldToLocalChunkCoordinates(new Point2(16, 80)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToLocalCoordinatesPositiveEntirety() {
|
||||
int chunkX = 4;
|
||||
int chunkZ = 3;
|
||||
for (int x = 0; x < GeneralUtilities.CHUNK_SIZE; x++) {
|
||||
for (int z = 0; z < GeneralUtilities.CHUNK_SIZE; z++) {
|
||||
int worldX = GeneralUtilities.CHUNK_SIZE * chunkX + x;
|
||||
int worldZ = GeneralUtilities.CHUNK_SIZE * chunkZ + z;
|
||||
assertEquals(new Point2(x, z), GeneralUtilities.worldToLocalChunkCoordinates(new Point2(worldX, worldZ)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorldToLocalCoordinatesNegativeEntirety() {
|
||||
int chunkX = -42;
|
||||
int chunkZ = -3;
|
||||
for (int x = 0; x < GeneralUtilities.CHUNK_SIZE; x++) {
|
||||
for (int z = 0; z < GeneralUtilities.CHUNK_SIZE; z++) {
|
||||
int worldX = GeneralUtilities.CHUNK_SIZE * chunkX + x;
|
||||
int worldZ = GeneralUtilities.CHUNK_SIZE * chunkZ + z;
|
||||
assertEquals(new Point2(x, z), GeneralUtilities.worldToLocalChunkCoordinates(new Point2(worldX, worldZ)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,256 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.caching;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class CacheTest {
|
||||
private volatile Cache<Integer, String> integerCache;
|
||||
private final int LARGE_CACHE_SIZE = 262144;
|
||||
private final int[] answers = new int[LARGE_CACHE_SIZE];
|
||||
private final Random rand = new Random();
|
||||
Cache<Integer, Integer> lCache = new Cache<>(LARGE_CACHE_SIZE);
|
||||
|
||||
@BeforeAll
|
||||
public void setUp() {
|
||||
integerCache = new Cache<>(3);
|
||||
|
||||
for (int i = 0; i < answers.length; i++) {
|
||||
answers[i] = rand.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void cleanUp() {
|
||||
lCache.clearCache();
|
||||
integerCache.clearCache();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicCaching() {
|
||||
String val = integerCache.get(0);
|
||||
assertTrue(val == null);
|
||||
val = "first";
|
||||
integerCache.set(0, val);
|
||||
assertTrue(integerCache.get(0) != null);
|
||||
assertSame(val, integerCache.get(0));
|
||||
|
||||
val = integerCache.get(1);
|
||||
assertTrue(val == null);
|
||||
val = "second";
|
||||
integerCache.set(1, val);
|
||||
assertTrue(integerCache.get(1) != null);
|
||||
assertSame(val, integerCache.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageBasedClean() {
|
||||
integerCache.set(0, "first");
|
||||
integerCache.set(1, "second");
|
||||
integerCache.set(2, "third");
|
||||
|
||||
assertEquals("first", integerCache.get(0));
|
||||
|
||||
integerCache.set(3, "fourth");
|
||||
assertEquals("first", integerCache.get(0));
|
||||
|
||||
integerCache.set(4, "fifth");
|
||||
assertTrue(integerCache.get(3) != null);
|
||||
assertTrue(integerCache.get(0) != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageLargeData() {
|
||||
int amount = 1024;
|
||||
Random random = new Random();
|
||||
|
||||
Cache<Integer, Integer> largeCache = new Cache<>(amount / 2);
|
||||
|
||||
int[] values = new int[amount];
|
||||
for (int i = 0; i < amount; i++) {
|
||||
values[i] = random.nextInt();
|
||||
largeCache.set(i, values[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < amount / 2; i++) {
|
||||
assertEquals(null, largeCache.get(i), "Current accessor: " + i);
|
||||
}
|
||||
|
||||
for (int i = amount / 2; i < amount; i++) {
|
||||
assertEquals(values[i], largeCache.get(i), "Current accessor: " + i);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageLargeDataImportance() {
|
||||
int amount = 1024;
|
||||
Random random = new Random();
|
||||
|
||||
Cache<Integer, Integer> largeCache = new Cache<>(amount / 2);
|
||||
|
||||
int[] values = new int[amount];
|
||||
for (int i = 0; i < amount; i++) {
|
||||
values[i] = random.nextInt();
|
||||
largeCache.set(i, values[i]);
|
||||
largeCache.get(0);
|
||||
}
|
||||
|
||||
for (int i = 1; i < (amount / 2) + 1; i++) {
|
||||
assertEquals(null, largeCache.get(i), "Current accessor: " + i);
|
||||
}
|
||||
|
||||
for (int i = (amount / 2) + 1; i < amount; i++) {
|
||||
assertEquals(values[i], largeCache.get(i), "Current accessor: " + i);
|
||||
}
|
||||
|
||||
assertEquals(values[0], largeCache.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultithreadingWriteConsistency() {
|
||||
Runnable write = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
||||
lCache.set(i, answers[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread firstThread = new Thread(write);
|
||||
firstThread.start();
|
||||
Thread secondThread = new Thread(write);
|
||||
secondThread.start();
|
||||
Thread thirdThread = new Thread(write);
|
||||
thirdThread.start();
|
||||
|
||||
try {
|
||||
firstThread.join();
|
||||
secondThread.join();
|
||||
thirdThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
|
||||
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
||||
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultithreadingReadConsistency() {
|
||||
for (int i = 0; i < answers.length; i++) {
|
||||
lCache.set(i, answers[i]);
|
||||
}
|
||||
|
||||
Runnable read = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
||||
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread firstThread = new Thread(read);
|
||||
firstThread.start();
|
||||
Thread secondThread = new Thread(read);
|
||||
secondThread.start();
|
||||
Thread thirdThread = new Thread(read);
|
||||
thirdThread.start();
|
||||
|
||||
try {
|
||||
firstThread.join();
|
||||
secondThread.join();
|
||||
thirdThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMulthreadedReadWrite() {
|
||||
Runnable readWrite = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
||||
if (lCache.get(i) == null) {
|
||||
lCache.set(i, answers[i]);
|
||||
} else {
|
||||
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Runnable readAll = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
||||
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread firstThread = new Thread(readWrite);
|
||||
firstThread.start();
|
||||
Thread secondThread = new Thread(readWrite);
|
||||
secondThread.start();
|
||||
Thread thirdThread = new Thread(readAll);
|
||||
|
||||
try {
|
||||
firstThread.join();
|
||||
secondThread.join();
|
||||
thirdThread.start();
|
||||
thirdThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiThreadConsistency() {
|
||||
Runnable readWriteCheck = new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
||||
if (lCache.get(i) != null) {
|
||||
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
||||
} else {
|
||||
lCache.set(i, answers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(6);
|
||||
executorService.submit(readWriteCheck);
|
||||
executorService.submit(readWriteCheck);
|
||||
executorService.submit(readWriteCheck);
|
||||
executorService.submit(readWriteCheck);
|
||||
executorService.submit(readWriteCheck);
|
||||
executorService.submit(readWriteCheck);
|
||||
|
||||
try {
|
||||
executorService.shutdown();
|
||||
assertTrue(executorService.awaitTermination(1, TimeUnit.MINUTES), "Timed out.");
|
||||
} catch (InterruptedException e) {
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.drawing;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.utilities.pathfinding.CoordinateValidatable;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class FloodFillTest {
|
||||
public byte[][] mapA;
|
||||
public byte[][] mapB;
|
||||
|
||||
private class Flood implements CoordinateValidatable {
|
||||
private final byte[][] map;
|
||||
|
||||
public Flood(byte[][] map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Point2 point) {
|
||||
try {
|
||||
if (map[point.y][point.x] < 1) return false;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
map[point.y][point.x] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private byte[][] readMap(String filename) throws IOException {
|
||||
byte[][] map = null;
|
||||
InputStream stream = getClass().getClassLoader().getResourceAsStream((filename));
|
||||
Scanner scanner = new Scanner(stream);
|
||||
String line = null;
|
||||
ArrayList<byte[]> rows = new ArrayList<>();
|
||||
while (scanner.hasNextLine()) {
|
||||
line = scanner.nextLine();
|
||||
char[] chars = line.toCharArray();
|
||||
byte[] rowBytes = new byte[chars.length];
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
rowBytes[i] = (byte) Character.getNumericValue(chars[i]);
|
||||
}
|
||||
rows.add(rowBytes);
|
||||
}
|
||||
scanner.close();
|
||||
map = new byte[rows.size()][rows.get(0).length];
|
||||
for (int row = 0; row < rows.size(); row++) {
|
||||
map[row] = rows.get(row);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void reset() {
|
||||
try {
|
||||
mapA = readMap("DFSTestMapLargeA.txt");
|
||||
mapB = readMap("DFSTestMapLargeB.txt");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFillMapA() {
|
||||
Flooder flooder = new Flooder(new Point2(0, 0), new Flood(mapA));
|
||||
flooder.start();
|
||||
for (int y = 0; y < mapA.length; y++) {
|
||||
for (int x = 0; x < mapA[y].length; x++) {
|
||||
assertEquals(0, mapA[y][x], String.format("At: %d, %d", x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFillMapB() {
|
||||
Flooder flooder = new Flooder(new Point2(0, 0), new Flood(mapB));
|
||||
flooder.start();
|
||||
for (int y = 0; y < mapB.length; y++) {
|
||||
for (int x = 0; x < mapB[y].length; x++) {
|
||||
if (x > 21 && y > 15 && x < 27) {
|
||||
assertTrue(mapB[y][x] > 0, String.format("At: %d, %d", x, y));
|
||||
} else {
|
||||
assertEquals(0, mapB[y][x], String.format("At: %d, %d", x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFillMapBNonCorner() {
|
||||
Flooder flooder = new Flooder(new Point2(43, 11), new Flood(mapB));
|
||||
flooder.start();
|
||||
for (int y = 0; y < mapB.length; y++) {
|
||||
for (int x = 0; x < mapB[y].length; x++) {
|
||||
if (x > 21 && y > 15 && x < 27) {
|
||||
assertTrue(mapB[y][x] > 0, String.format("At: %d, %d", x, y));
|
||||
} else {
|
||||
assertEquals(0, mapB[y][x], String.format("At: %d, %d", x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.utilities.pathfinding;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class DepthFirstSearchTest {
|
||||
|
||||
private class Validator implements CoordinateValidatable {
|
||||
private byte[][] map;
|
||||
|
||||
public Validator(byte[][] map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Point2 point) {
|
||||
try {
|
||||
return map[point.y][point.x] >= 1;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TargetValidator implements CoordinateValidatable {
|
||||
private byte[][] map;
|
||||
|
||||
public TargetValidator(byte[][] map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Point2 point) {
|
||||
try {
|
||||
return map[point.y][point.x] == 2;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private byte[][] mapA;
|
||||
private byte[][] mapB;
|
||||
private byte[][] mapC;
|
||||
private byte[][] mapD;
|
||||
private byte[][] mapE;
|
||||
private byte[][] mapF;
|
||||
private byte[][] mapG;
|
||||
private byte[][] mapH;
|
||||
|
||||
@BeforeAll
|
||||
public void setUp() throws IOException {
|
||||
mapA = readMap("DFSTestMapSmallA.txt");
|
||||
mapB = readMap("DFSTestMapSmallB.txt");
|
||||
mapC = readMap("DFSTestMapSmallC.txt");
|
||||
mapD = readMap("DFSTestMapSmallD.txt");
|
||||
mapE = readMap("DFSTestMapSmallE.txt");
|
||||
|
||||
mapF = readMap("DFSTestMapLargeA.txt");
|
||||
mapG = readMap("DFSTestMapLargeB.txt");
|
||||
mapH = readMap("DFSTestMapLargeC.txt");
|
||||
}
|
||||
|
||||
private byte[][] readMap(String filename) throws IOException {
|
||||
byte[][] map = null;
|
||||
InputStream stream = getClass().getClassLoader().getResourceAsStream((filename));
|
||||
Scanner scanner = new Scanner(stream);
|
||||
String line = null;
|
||||
ArrayList<byte[]> rows = new ArrayList<>();
|
||||
while (scanner.hasNextLine()) {
|
||||
line = scanner.nextLine();
|
||||
char[] chars = line.toCharArray();
|
||||
byte[] rowBytes = new byte[chars.length];
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
rowBytes[i] = (byte) Character.getNumericValue(chars[i]);
|
||||
}
|
||||
rows.add(rowBytes);
|
||||
}
|
||||
scanner.close();
|
||||
map = new byte[rows.size()][rows.get(0).length];
|
||||
for (int row = 0; row < rows.size(); row++) {
|
||||
map[row] = rows.get(row);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSBuildPathToEndNodeMapAValid()
|
||||
{
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(1, 2), new Point2(1, 0));
|
||||
dfs.buildToGoal(new Validator(mapA), null);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSBuildPathToEndNodeMapBValid()
|
||||
{
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(3, 2));
|
||||
dfs.buildToGoal(new Validator(mapB), null);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSBuildPathToEndNodeMapDValid()
|
||||
{
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(0, 0), new Point2(0, 3));
|
||||
dfs.buildToGoal(new Validator(mapD), null);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSBuildPathToEndNodeMapCInvalid()
|
||||
{
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(3, 2));
|
||||
dfs.buildToGoal(new Validator(mapC), null);
|
||||
assertFalse(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSBuildPathToEndNodeMapEInvalid()
|
||||
{
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(3, 2));
|
||||
dfs.buildToGoal(new Validator(mapE), null);
|
||||
assertFalse(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapBValid() {
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(0, 0));
|
||||
Validator validator = new Validator(mapB);
|
||||
TargetValidator targetValidator = new TargetValidator(mapB);
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
assertEquals(1, dfs.getResult().x);
|
||||
assertEquals(2, dfs.getResult().y);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapDValid() {
|
||||
Validator validator = new Validator(mapD);
|
||||
TargetValidator targetValidator = new TargetValidator(mapD);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(0, 0), new Point2(0, 0));
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
assertEquals(0, dfs.getResult().x);
|
||||
assertEquals(3, dfs.getResult().y);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapHValid() {
|
||||
Validator validator = new Validator(mapH);
|
||||
TargetValidator targetValidator = new TargetValidator(mapH);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(0, 0));
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
|
||||
assertTrue(dfs.getResult() != null);
|
||||
assertEquals(95, dfs.getResult().x);
|
||||
assertEquals(49, dfs.getResult().y);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapHInvalidLimited() {
|
||||
Validator validator = new Validator(mapH);
|
||||
TargetValidator targetValidator = new TargetValidator(mapH);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(0, 0), null, 128);
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertFalse(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapEInvalid() {
|
||||
Validator validator = new Validator(mapE);
|
||||
TargetValidator targetValidator = new TargetValidator(mapE);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(0, 0), new Point2(0, 0), null, 128);
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertFalse(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapFValid() {
|
||||
Validator validator = new Validator(mapF);
|
||||
TargetValidator targetValidator = new TargetValidator(mapF);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(0, 0), new Point2(0, 0), null, 1024);
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
assertEquals(26, dfs.getResult().x);
|
||||
assertEquals(32, dfs.getResult().y);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapGInvalid() {
|
||||
Validator validator = new Validator(mapG);
|
||||
TargetValidator targetValidator = new TargetValidator(mapG);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(0, 0), new Point2(0, 0), null, 128);
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertFalse(dfs.getResult() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapHWithAssistValid() {
|
||||
Validator validator = new Validator(mapH);
|
||||
TargetValidator targetValidator = new TargetValidator(mapH);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(95, 49), null, 0);
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
assertEquals(95, dfs.getResult().x);
|
||||
assertEquals(49, dfs.getResult().y);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDFSFindEndNodeMapHWithoutAssistValid() {
|
||||
Validator validator = new Validator(mapH);
|
||||
TargetValidator targetValidator = new TargetValidator(mapH);
|
||||
DepthFirstSearch dfs = new DepthFirstSearch(new Point2(3, 0), new Point2(0, 0), null, 0);
|
||||
dfs.buildToGoal(validator, targetValidator);
|
||||
assertTrue(dfs.getResult() != null);
|
||||
assertEquals(95, dfs.getResult().x);
|
||||
assertEquals(49, dfs.getResult().y);
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class IslandWorldMapTest {
|
||||
public final int SEED = 102385923;
|
||||
public final int GRIDSIZE = 2048;
|
||||
public Random random = new Random(SEED);
|
||||
public IslandWorldMap mapper = new IslandWorldMap(random);
|
||||
public final double[][] answers = new double[GRIDSIZE][GRIDSIZE];
|
||||
|
||||
@BeforeAll
|
||||
public void setUp() {
|
||||
for (int x = 0; x < answers.length; x++) {
|
||||
for (int y = 0; y < answers[x].length; y++) {
|
||||
answers[x][y] = mapper.getWorldValue(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockValueConsistency() {
|
||||
for (int x = 0; x < answers.length; x++) {
|
||||
for (int y = 0; y < answers[x].length; y++) {
|
||||
assertEquals(answers[x][y], mapper.getWorldValue(x, y), String.format("Occurred at (%d, %d)", x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockValueConsistencyRandom() {
|
||||
for (int amount = 0; amount < GRIDSIZE; amount++) {
|
||||
int x = random.nextInt(answers.length);
|
||||
int y = random.nextInt(answers[x].length);
|
||||
assertEquals(answers[x][y], mapper.getWorldValue(x, y), String.format("Occurred at (%d, %d)", x, y));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValuesValidity() {
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
int x = random.nextInt();
|
||||
int y = random.nextInt();
|
||||
assertTrue((mapper.getWorldValue(x, y) <= 1));
|
||||
assertTrue((mapper.getWorldValue(x, y) >= -1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIslandOriginConsistency() {
|
||||
Point2 origin = null;
|
||||
for (int i = 0; i < GRIDSIZE; i++) {
|
||||
if (origin != null) {
|
||||
if (mapper.isSameIsland(origin, new Point2(i, 0))) {
|
||||
assertEquals(origin, mapper.findIslandOrigin(i, 0), String.format("Looking at (%d, 0)", i));
|
||||
} else {
|
||||
origin = null;
|
||||
}
|
||||
} else if (mapper.isIsland(i, 0)) {
|
||||
origin = mapper.findIslandOrigin(i, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIslandOriginConsistency2D() {
|
||||
int gridSize = 32;
|
||||
Point2 origin = null;
|
||||
for (int y = 0; y < gridSize; y++) {
|
||||
for (int x = 0; x < gridSize; x++) {
|
||||
if (origin != null) {
|
||||
if (mapper.isSameIsland(origin, new Point2(x, y))) {
|
||||
assertEquals(origin, mapper.findIslandOrigin(x, y), String.format("Looking at (%d, %d)", x, y));
|
||||
} else {
|
||||
origin = null;
|
||||
}
|
||||
} else if (mapper.isIsland(x, y)) {
|
||||
origin = mapper.findIslandOrigin(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
package net.reslate.islandsurvivalcraft.world.generation.biomes;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import net.reslate.islandsurvivalcraft.utilities.GeneralUtilities;
|
||||
import net.reslate.islandsurvivalcraft.utilities.biomes.BiomeInfo;
|
||||
import net.reslate.islandsurvivalcraft.utilities.caching.Cache;
|
||||
import net.reslate.islandsurvivalcraft.utilities.datatypes.Point2;
|
||||
import net.reslate.islandsurvivalcraft.world.BiomeMap;
|
||||
import net.reslate.islandsurvivalcraft.world.IslandWorldMap;
|
||||
import net.reslate.islandsurvivalcraft.world.TemperatureMap;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class UniqueBiomeGeneratorTest {
|
||||
private final int SEED = 249398015;
|
||||
private volatile Cache<Point2, BiomeInfo> biomeCache;
|
||||
private final BiomeMap biomeSelector = new BiomeMap(new Random(SEED));
|
||||
|
||||
|
||||
private class BiomeGenTask implements Runnable {
|
||||
private final int amount;
|
||||
private final int shift;
|
||||
|
||||
public BiomeGenTask(int amount, int shift) {
|
||||
this.shift = shift;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (int x = 0; x < amount; x++) {
|
||||
generateBiome(x, shift);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void generateBiome(int chunkX, int chunkZ) {
|
||||
Random random = new Random(SEED);
|
||||
IslandWorldMap mapper = new IslandWorldMap(random);
|
||||
TemperatureMap temperatureMapGenerator = new TemperatureMap(random);
|
||||
BiomeGenerator biomeGenerator = new UniqueBiomeGenerator();
|
||||
|
||||
BiomeInfo[][] biomes = new BiomeInfo[GeneralUtilities.CHUNK_SIZE][GeneralUtilities.CHUNK_SIZE];
|
||||
for (int localX = 0; localX < GeneralUtilities.CHUNK_SIZE; localX++) {
|
||||
for (int localZ = 0; localZ < GeneralUtilities.CHUNK_SIZE; localZ++) {
|
||||
if (biomes[localX][localZ] == null) {
|
||||
biomeGenerator.generateBiomeColumn(biomes, chunkX, chunkZ, localX, localZ, mapper,
|
||||
biomeSelector, temperatureMapGenerator, biomeCache);
|
||||
}
|
||||
if (biomes[localX][localZ] == null)
|
||||
throw new IllegalStateException("Biome was null.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public void setup() {
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void individualSetup() {
|
||||
biomeCache = new Cache<>(524288);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void individualCleanup() {
|
||||
biomeCache.clearCache();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread1608Chunks() {
|
||||
int chunksToDoEach = 268;
|
||||
Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
|
||||
Runnable g2 = new BiomeGenTask(chunksToDoEach, 1);
|
||||
Runnable g3 = new BiomeGenTask(chunksToDoEach, 2);
|
||||
Runnable g4 = new BiomeGenTask(chunksToDoEach, 3);
|
||||
Runnable g5 = new BiomeGenTask(chunksToDoEach, 4);
|
||||
Runnable g6 = new BiomeGenTask(chunksToDoEach, 5);
|
||||
|
||||
ExecutorService ex = Executors.newFixedThreadPool(6);
|
||||
LinkedList<Future<?>> tasks = new LinkedList<>();
|
||||
tasks.add(ex.submit(g1));
|
||||
tasks.add(ex.submit(g2));
|
||||
tasks.add(ex.submit(g3));
|
||||
tasks.add(ex.submit(g4));
|
||||
tasks.add(ex.submit(g5));
|
||||
tasks.add(ex.submit(g6));
|
||||
|
||||
while (!tasks.isEmpty()) {
|
||||
try {
|
||||
tasks.pop().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread1608ChunksSmallCache() {
|
||||
this.biomeCache = new Cache<>(1024);
|
||||
|
||||
int chunksToDoEach = 268;
|
||||
Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
|
||||
Runnable g2 = new BiomeGenTask(chunksToDoEach, 1);
|
||||
Runnable g3 = new BiomeGenTask(chunksToDoEach, 2);
|
||||
Runnable g4 = new BiomeGenTask(chunksToDoEach, 3);
|
||||
Runnable g5 = new BiomeGenTask(chunksToDoEach, 4);
|
||||
Runnable g6 = new BiomeGenTask(chunksToDoEach, 5);
|
||||
|
||||
ExecutorService ex = Executors.newFixedThreadPool(6);
|
||||
LinkedList<Future<?>> tasks = new LinkedList<>();
|
||||
tasks.add(ex.submit(g1));
|
||||
tasks.add(ex.submit(g2));
|
||||
tasks.add(ex.submit(g3));
|
||||
tasks.add(ex.submit(g4));
|
||||
tasks.add(ex.submit(g5));
|
||||
tasks.add(ex.submit(g6));
|
||||
|
||||
while (!tasks.isEmpty()) {
|
||||
try {
|
||||
tasks.pop().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationSingleThread1608Chunks() {
|
||||
Runnable g1 = new BiomeGenTask(1608, 0);
|
||||
g1.run();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread1608ChunksScatteredColumns() {
|
||||
int chunksToDoEach = 268;
|
||||
Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
|
||||
Runnable g2 = new BiomeGenTask(chunksToDoEach, 2);
|
||||
Runnable g3 = new BiomeGenTask(chunksToDoEach, 4);
|
||||
Runnable g4 = new BiomeGenTask(chunksToDoEach, 6);
|
||||
Runnable g5 = new BiomeGenTask(chunksToDoEach, 8);
|
||||
Runnable g6 = new BiomeGenTask(chunksToDoEach, 10);
|
||||
|
||||
ExecutorService ex = Executors.newFixedThreadPool(6);
|
||||
LinkedList<Future<?>> tasks = new LinkedList<>();
|
||||
tasks.add(ex.submit(g1));
|
||||
tasks.add(ex.submit(g2));
|
||||
tasks.add(ex.submit(g3));
|
||||
tasks.add(ex.submit(g4));
|
||||
tasks.add(ex.submit(g5));
|
||||
tasks.add(ex.submit(g6));
|
||||
|
||||
while (!tasks.isEmpty()) {
|
||||
try {
|
||||
tasks.pop().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread1608ChunksScatteredColumnsSmallCache() {
|
||||
this.biomeCache = new Cache<>(1024);
|
||||
int chunksToDoEach = 268;
|
||||
Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
|
||||
Runnable g2 = new BiomeGenTask(chunksToDoEach, 2);
|
||||
Runnable g3 = new BiomeGenTask(chunksToDoEach, 4);
|
||||
Runnable g4 = new BiomeGenTask(chunksToDoEach, 6);
|
||||
Runnable g5 = new BiomeGenTask(chunksToDoEach, 8);
|
||||
Runnable g6 = new BiomeGenTask(chunksToDoEach, 10);
|
||||
|
||||
ExecutorService ex = Executors.newFixedThreadPool(6);
|
||||
LinkedList<Future<?>> tasks = new LinkedList<>();
|
||||
tasks.add(ex.submit(g1));
|
||||
tasks.add(ex.submit(g2));
|
||||
tasks.add(ex.submit(g3));
|
||||
tasks.add(ex.submit(g4));
|
||||
tasks.add(ex.submit(g5));
|
||||
tasks.add(ex.submit(g6));
|
||||
|
||||
while (!tasks.isEmpty()) {
|
||||
try {
|
||||
tasks.pop().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread6000ChunksScatteredColumns() {
|
||||
int chunksToDoEach = 1000;
|
||||
Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
|
||||
Runnable g2 = new BiomeGenTask(chunksToDoEach, 3);
|
||||
Runnable g3 = new BiomeGenTask(chunksToDoEach, 6);
|
||||
Runnable g4 = new BiomeGenTask(chunksToDoEach, 9);
|
||||
Runnable g5 = new BiomeGenTask(chunksToDoEach, 12);
|
||||
Runnable g6 = new BiomeGenTask(chunksToDoEach, 15);
|
||||
|
||||
ExecutorService ex = Executors.newFixedThreadPool(6);
|
||||
LinkedList<Future<?>> tasks = new LinkedList<>();
|
||||
tasks.add(ex.submit(g1));
|
||||
tasks.add(ex.submit(g2));
|
||||
tasks.add(ex.submit(g3));
|
||||
tasks.add(ex.submit(g4));
|
||||
tasks.add(ex.submit(g5));
|
||||
tasks.add(ex.submit(g6));
|
||||
|
||||
while (!tasks.isEmpty()) {
|
||||
try {
|
||||
tasks.pop().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
public void testBiomeGenerationMultithread6000ChunksScatteredColumnsSmallCache() {
|
||||
this.biomeCache = new Cache<>(1024);
|
||||
|
||||
int chunksToDoEach = 1000;
|
||||
Runnable g1 = new BiomeGenTask(chunksToDoEach, 0);
|
||||
Runnable g2 = new BiomeGenTask(chunksToDoEach, 3);
|
||||
Runnable g3 = new BiomeGenTask(chunksToDoEach, 6);
|
||||
Runnable g4 = new BiomeGenTask(chunksToDoEach, 9);
|
||||
Runnable g5 = new BiomeGenTask(chunksToDoEach, 12);
|
||||
Runnable g6 = new BiomeGenTask(chunksToDoEach, 15);
|
||||
|
||||
ExecutorService ex = Executors.newFixedThreadPool(6);
|
||||
LinkedList<Future<?>> tasks = new LinkedList<>();
|
||||
tasks.add(ex.submit(g1));
|
||||
tasks.add(ex.submit(g2));
|
||||
tasks.add(ex.submit(g3));
|
||||
tasks.add(ex.submit(g4));
|
||||
tasks.add(ex.submit(g5));
|
||||
tasks.add(ex.submit(g6));
|
||||
|
||||
while (!tasks.isEmpty()) {
|
||||
try {
|
||||
tasks.pop().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
assertFalse(false, e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
11111111111111111111111111111111
|
||||
11111111111111111110000000000000
|
||||
11111111111111111111111111111111
|
||||
00000000000000000000000000111111
|
||||
00000000000000000000000000001111
|
||||
00000000000000000000000111111111
|
||||
11111111111111111111111111111111
|
||||
11111111111111111111111111111111
|
||||
11111111111110000000000000000000
|
||||
11111111111100000000000000000000
|
||||
11111111100000000000000000000000
|
||||
11111111110000000000000000000000
|
||||
11111111110000000000000000000000
|
||||
11111111110000000000000000000000
|
||||
11111111111000000000000000000000
|
||||
11111111111100000000000000000000
|
||||
11111111111110000000000000000000
|
||||
11111111111111000000000000000000
|
||||
11111111111111110000000000000000
|
||||
11111111111111111100000000000000
|
||||
11111111111111111111100000000000
|
||||
11111111111111111111111000000000
|
||||
11111111111111111111111100000000
|
||||
11111111111111111111111110000000
|
||||
11111111111111111111111110000000
|
||||
11111111111111111111111100000000
|
||||
11111111111111111111111100000000
|
||||
11111111111111111111111000000000
|
||||
11111111111111111111110000000000
|
||||
11111111111111111111100000000000
|
||||
11111111111111111111100000000000
|
||||
11111111111111111110000000000000
|
||||
11111111111111111111111111200000
|
@ -1,17 +0,0 @@
|
||||
1111111111111111111111111111111111111111111111111110000000000000
|
||||
1111111111111111111111111111111100000000000000000000000000111111
|
||||
0000000000000000000000000000111100000000000000000000000111111111
|
||||
1111111111111111111111111111111111111111111111111111111111111111
|
||||
1111111111111000000000000000000011111111111100000000000000000000
|
||||
1111111110000000000000000000000011111111110000000000000000000000
|
||||
1111111111000000000000000000000011111111110000000000000000000000
|
||||
1111111111100000000000000000000011111111111100000000000000000000
|
||||
1111111111111000000000000000000011111111111111000000000000000000
|
||||
1111111111111111000000000000000011111111111111111100000000000000
|
||||
1111111111111111111110000000000011111111111111111111111000000000
|
||||
1111111111111111111111110000000011111111111111111111111110000000
|
||||
1111111111111111111111111000000011111111111111111111111100000000
|
||||
1111111111111111111111110000000011111111111111111111111000000000
|
||||
1111111111111111111111000000000011111111111111111111100000000000
|
||||
1111111111111111111110000000000011111111111111111110000000000000
|
||||
1111111111111111111110111120000000000000000000000000000000000000
|
@ -1,50 +0,0 @@
|
||||
0011111111110101010101110111101101000001011110010110111010100111101111111010111000100010010110000100
|
||||
0011111110111001000011011101111001001100000011100110010000011101100111000110100001111110010101001101
|
||||
0011111010000110100011100110101101011101001101011100010101101011111111000100110011000101110000010111
|
||||
1011100000110001011101001111000100011001010110010000001111100111000010010101001111011011011000111101
|
||||
0011110001100010111110110100011110110010101011111010110000001101100111010011111101000001001010001110
|
||||
0111100010000011111100010110010010111111110001010001111001011110000100110101100011001001001111010010
|
||||
1111100101001010101001011101001000101100000011011101110011110111110001101011101010000011001111000111
|
||||
0111111111100001100101000100110001101000111110000111101111110111011001101111011010001100000001111101
|
||||
1111101101110111101000110010100000000000011101010110010100100100101001101001010001110101000110010110
|
||||
1011110000110110000001011011010010111011010010101000001101101101111100100000000000011000100111011111
|
||||
0101111111111111101001101111011111100011111110001111000110101001100110010010001011011111001010110111
|
||||
0011101101111101101101110000001001000000000001011010101100011011110010011111111110100010011101111111
|
||||
1111001011110110001100001110101000110111100100010110000010111001010111001101101101010101010111011111
|
||||
0111100111010010110010111011100010101101010111101001101011011100010010000100010111101100010101111110
|
||||
1011000101101100110111110010010110100100011100101000111101101010110111010100000100011000101010001110
|
||||
0101010001000101100111010100000010010011000011111000000000011100010011000110001010000100011110110011
|
||||
1100111001011111001011001110011111110010101100100100010100010110110000100101100001000001011000101010
|
||||
1010111101111111100011100011111001010000000111111010100011001100011001001000110100010010011010010010
|
||||
0111001100100111110010100101111111101100000001101101001011000000101111001101101010110001001010100001
|
||||
1110010000100011111111110000110110101001000111101101010010111001000111001101100010111010101100111101
|
||||
0010100010010101111111110010111011001101110001001100111001110100100000101011000011110101000100001110
|
||||
0000001100101000111111111110110001011110010011001111001000011010010010101001001100101011000100011111
|
||||
1101101111000101100100111111111111111000000011010000100101111000101011110110110110110010010111111010
|
||||
1110101010110100111110110111111110001101001001100110110111011101000111001011101010101010010110101000
|
||||
0100011000100110110101000000111111100100011110010011011011101001001111011101011001011110100000110010
|
||||
1100100100100000110101101110011111110101111111110111111011001000101010110110110001010001001010011000
|
||||
0101110110101011100100100100011111111111000101111110111110100101010101110101101000110010011111100101
|
||||
0111100001010100100101010101101001101110000111000100111111110000101000000111010001000111011011011010
|
||||
1011010100010010011101001011010110001110111101000110111111110101111101010000001111110110110111010000
|
||||
1011001011010101000110110001111011010111000001101001111011111111111011110001000100110100101110101110
|
||||
0011011010110111001110110110010110100101110000010010101100111111110101101111101010110101110110111000
|
||||
1001100100000101101000110011011010111110100001011100000101101001110001010001001011100010100010110011
|
||||
0110010101110110110111011010101000011010010000000110001110010101111010100011000011000100011100110000
|
||||
0111000111100001101110101110110011001100000010101001111111010110111111011101000100101000011110110011
|
||||
0100110001000001001111011011011101000101111001110101110010111011011110010011101101010100000110001101
|
||||
1111000110001111010011101100110001101101011111100101010001101001101111011111000010010110011100100101
|
||||
0011001101110010110001101001100100101101110010110100100110101101100111111001100101011101111010101010
|
||||
1001001101110111010000011000011100011011110011100011100111010110111101111111101011111100011100110101
|
||||
1000011000011101010100001010000101000010111010101011010101001110000010001111111111110111111011000000
|
||||
1011010011111010101001011001110011111110001000000111101110001001110000001111111111100011111001000110
|
||||
0110110111001100000001100101110111101011000011000111001100110111101000011110001011111111011110011101
|
||||
0000101101011000100110001111100101101100011111101001110000110111100010010101010101110100000100100000
|
||||
0011011100101110101000111110110011001101000110000110010010010000101001001111001111111111100011110001
|
||||
1011000011010010000100000010110000101001000101010000100011100110100111011010011000010111111101100101
|
||||
1001011000111111111010011010100001100111000111000001011111011110101100011000001110000111111011101101
|
||||
1110101001110011111110101110001110111100010100010110111001000100010100110011101001111101111110110100
|
||||
1010000100000100101101111001111101111110111001101000000110111100000110011111000001011011111110111001
|
||||
1010011010111001010111011101000011010100001001101101110011101100000110100011111011101001111111101101
|
||||
0011011110111000111101000110000111101000111101001011011100110011010000111011010000011110110111111101
|
||||
1100010110001111010011101000001011010011000011111010010011011000110101011000001110100000110111120011
|
@ -1,3 +0,0 @@
|
||||
11
|
||||
10
|
||||
11
|
@ -1,3 +0,0 @@
|
||||
1111
|
||||
1000
|
||||
1211
|
@ -1,3 +0,0 @@
|
||||
1111
|
||||
0000
|
||||
1111
|
@ -1,4 +0,0 @@
|
||||
1111
|
||||
0001
|
||||
1111
|
||||
2000
|
@ -1,4 +0,0 @@
|
||||
1111
|
||||
0000
|
||||
1111
|
||||
1020
|
@ -1,44 +0,0 @@
|
||||
# This is the main configuration file for Bukkit.
|
||||
# As you can see, there's actually not that much to configure without any plugins.
|
||||
# For a reference for any variable inside this file, check out the Bukkit Wiki at
|
||||
# https://www.spigotmc.org/go/bukkit-yml
|
||||
#
|
||||
# If you need help on this file, feel free to join us on irc or leave a message
|
||||
# on the forums asking for advice.
|
||||
#
|
||||
# IRC: #spigot @ irc.spi.gt
|
||||
# (If this means nothing to you, just go to https://www.spigotmc.org/go/irc )
|
||||
# Forums: https://www.spigotmc.org/
|
||||
# Bug tracker: https://www.spigotmc.org/go/bugs
|
||||
|
||||
|
||||
settings:
|
||||
allow-end: true
|
||||
warn-on-overload: true
|
||||
permissions-file: permissions.yml
|
||||
update-folder: update
|
||||
plugin-profiling: false
|
||||
connection-throttle: 4000
|
||||
query-plugins: true
|
||||
deprecated-verbose: default
|
||||
shutdown-message: Server closed
|
||||
minimum-api: none
|
||||
spawn-limits:
|
||||
water-ambient: 20
|
||||
monsters: 70
|
||||
animals: 10
|
||||
water-animals: 15
|
||||
ambient: 15
|
||||
chunk-gc:
|
||||
period-in-ticks: 600
|
||||
ticks-per:
|
||||
water-ambient-spawns: 1
|
||||
animal-spawns: 400
|
||||
monster-spawns: 1
|
||||
water-spawns: 1
|
||||
ambient-spawns: 1
|
||||
autosave: 6000
|
||||
aliases: now-in-commands.yml
|
||||
worlds:
|
||||
world:
|
||||
generator: IslandSurvivalCraft
|
@ -1,2 +0,0 @@
|
||||
write-Output "Deleting previous world if there was one..."
|
||||
remove-Item -Recurse world* -Force -ErrorAction Ignore
|
@ -1,9 +0,0 @@
|
||||
if (Test-Path ./test-server.pid) {
|
||||
$sID = Get-Item -Path ./test-server.pid | Get-Content -Tail 1
|
||||
if (Get-Process -Id $sID -ErrorAction SilentlyContinue) {
|
||||
Stop-Process -Id $sID
|
||||
}
|
||||
Remove-Item "./test-server.pid"
|
||||
} else {
|
||||
Write-Output "Couldn't find running server to stop."
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
New-Item -Path .\plugins -ItemType Directory -Force
|
||||
write-Output "Attempting to copy plugin jar to plugins folder..."
|
||||
copy-Item -Path "..\target\IslandSurvivalCraft*.jar" -Destination "plugins\IslandSurvivalCraft.jar"
|
@ -1 +0,0 @@
|
||||
Start-Process java -ArgumentList "-Xms512M", "-Xmx1G", "-jar", "paper.jar", "nogui"
|
@ -1,10 +0,0 @@
|
||||
if (!(Test-Path -Path "paper.jar" -PathType Leaf)) {
|
||||
Invoke-WebRequest -Uri "https://api.papermc.io/v2/projects/paper/versions/1.16.5/builds/794/downloads/paper-1.16.5-794.jar" -OutFile "paper.jar"
|
||||
}
|
||||
|
||||
write-Output "Attempting to start Paper test server."
|
||||
$SID = Start-Process java -ArgumentList "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=25566", "-Xms512M", "-Xmx1G", "-jar", "paper.jar", "nogui" -PassThru
|
||||
$SID = $SID.Id
|
||||
write-Output "Process started. PID is: $SID"
|
||||
|
||||
$SID | Out-File -FilePath "test-server.pid"
|
Loading…
Reference in New Issue
Block a user