Initial commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
dist/
|
||||
build/
|
||||
nbproject/private
|
||||
73
build.xml
Normal file
73
build.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="RealisticMinecraft" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project RealisticMinecraft.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="RealisticMinecraft-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
3
manifest.mf
Normal file
3
manifest.mf
Normal file
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
||||
1768
nbproject/build-impl.xml
Normal file
1768
nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
nbproject/genfiles.properties
Normal file
8
nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=384066bc
|
||||
build.xml.script.CRC32=61428c28
|
||||
build.xml.stylesheet.CRC32=f85dc8f2@1.91.1.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=384066bc
|
||||
nbproject/build-impl.xml.script.CRC32=6151eca2
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=3a2fa800@1.91.1.48
|
||||
102
nbproject/project.properties
Normal file
102
nbproject/project.properties
Normal file
@@ -0,0 +1,102 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
application.title=RealisticMinecraft
|
||||
application.vendor=NMerkelt
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.modulepath=\
|
||||
${run.modulepath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
debug.test.modulepath=\
|
||||
${run.test.modulepath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/RealisticMinecraft.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
dist.jlink.dir=${dist.dir}/jlink
|
||||
dist.jlink.output=${dist.jlink.dir}/RealisticMinecraft
|
||||
endorsed.classpath=
|
||||
excludes=
|
||||
file.reference.AnuraCore.jar=..\\libs\\AnuraCore.jar
|
||||
file.reference.LogBlock.jar=../libs/LogBlock.jar
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=\
|
||||
${libs.Spigot-Server.classpath}:\
|
||||
${file.reference.LogBlock.jar}:\
|
||||
${file.reference.AnuraCore.jar}
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.external.vm=true
|
||||
javac.modulepath=
|
||||
javac.processormodulepath=
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.8
|
||||
javac.target=1.8
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.modulepath=\
|
||||
${javac.modulepath}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.html5=false
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
# The jlink additional root modules to resolve
|
||||
jlink.additionalmodules=
|
||||
# The jlink additional command line parameters
|
||||
jlink.additionalparam=
|
||||
jlink.launcher=true
|
||||
jlink.launcher.name=RealisticMinecraft
|
||||
main.class=de.anura.realisticminecraft.RealisticMinecraft
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.modulepath=\
|
||||
${javac.modulepath}
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
run.test.modulepath=\
|
||||
${javac.test.modulepath}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
15
nbproject/project.xml
Normal file
15
nbproject/project.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>RealisticMinecraft</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
93
src/de/anura/realisticminecraft/RealisticMinecraft.java
Normal file
93
src/de/anura/realisticminecraft/RealisticMinecraft.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package de.anura.realisticminecraft;
|
||||
|
||||
import de.anura.core.AnuraThread;
|
||||
import de.anura.core.database.DB;
|
||||
import de.anura.core.msg.Msg;
|
||||
import de.anura.core.msg.Msg.PluginData;
|
||||
import de.anura.realisticminecraft.command.InfobarCmd;
|
||||
import de.anura.realisticminecraft.command.InfobarSetCmd;
|
||||
import de.anura.realisticminecraft.fishing.FishingChunk;
|
||||
import de.anura.realisticminecraft.infobar.InfobarUtil;
|
||||
import de.anura.realisticminecraft.listener.Chairs;
|
||||
import de.anura.realisticminecraft.util.ChairManager;
|
||||
import de.anura.realisticminecraft.infobar.ValueHolder;
|
||||
import de.anura.realisticminecraft.listener.Fishing;
|
||||
import de.anura.realisticminecraft.listener.Infobar;
|
||||
import de.anura.realisticminecraft.listener.Timber;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class RealisticMinecraft extends JavaPlugin {
|
||||
|
||||
private static RealisticMinecraft instance;
|
||||
public static final PluginData PLUGIN_DATA = new PluginData("RealisticMC", Msg.PluginType.SYSTEM);
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
DB.queryUpdate("CREATE TABLE IF NOT EXISTS `playerTemperature` ("
|
||||
+ " `playerId` INT(10) UNSIGNED NOT NULL,"
|
||||
+ " `value` DECIMAL(7,5) NOT NULL,"
|
||||
+ " `bar` BIT(1) NOT NULL DEFAULT b'0',"
|
||||
+ " PRIMARY KEY (`playerId`),"
|
||||
+ " INDEX `playerTemperature_playerId` (`playerId`),"
|
||||
+ " CONSTRAINT `playerTemperature_playerId` FOREIGN KEY (`playerId`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE"
|
||||
+ ") ENGINE=InnoDB COLLATE='utf8_general_ci' COMMENT='RealisticMinecraft | hibo98'");
|
||||
DB.queryUpdate("CREATE TABLE IF NOT EXISTS `playerThirst` ("
|
||||
+ " `playerId` INT(10) UNSIGNED NOT NULL,"
|
||||
+ " `value` INT(11) NOT NULL,"
|
||||
+ " `bar` BIT(1) NOT NULL DEFAULT b'0',"
|
||||
+ " PRIMARY KEY (`playerId`),"
|
||||
+ " INDEX `playerTemperature_playerId` (`playerId`),"
|
||||
+ " CONSTRAINT `playerThirst_playerId` FOREIGN KEY (`playerId`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE"
|
||||
+ ") ENGINE=InnoDB COLLATE='utf8_general_ci' COMMENT='RealisticMinecraft | hibo98'");
|
||||
DB.queryUpdate("CREATE TABLE IF NOT EXISTS `fishingChunks` ( "
|
||||
+ " `primeKey` INT(11) NOT NULL AUTO_INCREMENT, "
|
||||
+ " `x` INT(11) NOT NULL, "
|
||||
+ " `z` INT(11) NOT NULL, "
|
||||
+ " `world` VARCHAR(50) COLLATE latin1_german1_ci NOT NULL, "
|
||||
+ " `catched` INT(11) NOT NULL, "
|
||||
+ " `lastUpdated` INT(11) NOT NULL, "
|
||||
+ " PRIMARY KEY (`primeKey`) "
|
||||
+ ") ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci COMMENT='RealisticMinecraft | LukBukkit'");
|
||||
// Chairs
|
||||
Bukkit.getPluginManager().registerEvents(new Chairs(), instance);
|
||||
// Infobar
|
||||
AnuraThread.async(() -> Bukkit.getOnlinePlayers().stream().filter((p) -> p.getGameMode().equals(GameMode.SURVIVAL)).forEach(ValueHolder::new));
|
||||
InfobarCmd infobarCmd = new InfobarCmd();
|
||||
PluginCommand infobar = instance.getCommand("infobar");
|
||||
if (infobar != null) {
|
||||
infobar.setExecutor(infobarCmd);
|
||||
infobar.setTabCompleter(infobarCmd);
|
||||
}
|
||||
InfobarSetCmd infobarSetCmd = new InfobarSetCmd();
|
||||
PluginCommand infobarset = instance.getCommand("infobarset");
|
||||
if (infobarset != null) {
|
||||
infobarset.setExecutor(infobarSetCmd);
|
||||
infobarset.setTabCompleter(infobarSetCmd);
|
||||
}
|
||||
InfobarUtil.enableInfobarTasks();
|
||||
Bukkit.getPluginManager().registerEvents(new Infobar(), instance);
|
||||
// Fishing
|
||||
FishingChunk.init();
|
||||
Bukkit.getPluginManager().registerEvents(new Fishing(), instance);
|
||||
// Trees
|
||||
Bukkit.getPluginManager().registerEvents(new Timber(), instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
ValueHolder.destroyAll();
|
||||
ChairManager.destoryAll();
|
||||
}
|
||||
|
||||
public static RealisticMinecraft getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static boolean hasLogBlock() {
|
||||
return Bukkit.getServer().getPluginManager().getPlugin("LogBlock") != null;
|
||||
}
|
||||
}
|
||||
88
src/de/anura/realisticminecraft/command/InfobarCmd.java
Normal file
88
src/de/anura/realisticminecraft/command/InfobarCmd.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package de.anura.realisticminecraft.command;
|
||||
|
||||
import de.anura.core.msg.Msg;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import de.anura.realisticminecraft.infobar.TemperaturePlayer;
|
||||
import de.anura.realisticminecraft.infobar.ThirstPlayer;
|
||||
import de.anura.realisticminecraft.infobar.BarStatus;
|
||||
import de.anura.realisticminecraft.infobar.ValueHolder;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class InfobarCmd implements TabExecutor {
|
||||
|
||||
public InfobarCmd() {
|
||||
// new Help("infobar", "Konfigurieret die Anzeige der Infobars")
|
||||
// .addArgument("durst | temp", "Wählt Durst oder Temperatur aus")
|
||||
// .addArgument("an | standard", "Schaltet die Bar auf AN oder STANDARD")
|
||||
// .build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender cs, Command cmnd, String label, String[] args) {
|
||||
if (!(cs instanceof Player)) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "This is a player command!");
|
||||
return false;
|
||||
}
|
||||
if (args.length < 2 || args.length > 3) {
|
||||
return false;
|
||||
}
|
||||
if (!((HumanEntity) cs).getGameMode().equals(GameMode.SURVIVAL)) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Dieses Command kann nur im SURVIVAL Mode verwendet werden");
|
||||
return true;
|
||||
}
|
||||
BarStatus status;
|
||||
try {
|
||||
status = BarStatus.valueOf(args[1].toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
ValueHolder valueHolder = ValueHolder.getValueHolder((Player) cs);
|
||||
if (valueHolder == null) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Es ist einer interner Fehler aufgetreten (0)");
|
||||
return true;
|
||||
}
|
||||
ThirstPlayer thirstPlayer = valueHolder.getPlayer(ThirstPlayer.class);
|
||||
TemperaturePlayer temperaturePlayer = valueHolder.getPlayer(TemperaturePlayer.class);
|
||||
if (thirstPlayer == null || temperaturePlayer == null) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Es ist einer interner Fehler aufgetreten (1)");
|
||||
return true;
|
||||
}
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "durst":
|
||||
thirstPlayer.getBar().setBarStatus(status);
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.SUCCESS, "Die Durst Infobar wird dir nun" + (status.equals(BarStatus.STANDARD) ? " nicht " : " ") + "immer angezeigt!");
|
||||
return true;
|
||||
case "temp":
|
||||
case "temperatur":
|
||||
temperaturePlayer.getBar().setBarStatus(status);
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.SUCCESS, "Die Temperatur Infobar wird dir nun" + (status.equals(BarStatus.STANDARD) ? " nicht " : " ") + "immer angezeigt!");
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender cs, Command cmnd, String label, String[] args) {
|
||||
List<String> list = new ArrayList<>();
|
||||
switch (args.length) {
|
||||
case 1:
|
||||
list.add("durst");
|
||||
list.add("temp");
|
||||
break;
|
||||
case 2:
|
||||
list.add("an");
|
||||
list.add("standard");
|
||||
break;
|
||||
}
|
||||
return list.stream().filter((s) -> s.startsWith(args[args.length - 1].toLowerCase())).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
91
src/de/anura/realisticminecraft/command/InfobarSetCmd.java
Normal file
91
src/de/anura/realisticminecraft/command/InfobarSetCmd.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package de.anura.realisticminecraft.command;
|
||||
|
||||
import de.anura.core.msg.Msg;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import de.anura.realisticminecraft.infobar.TemperaturePlayer;
|
||||
import de.anura.realisticminecraft.infobar.ThirstPlayer;
|
||||
import de.anura.realisticminecraft.infobar.ValueHolder;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class InfobarSetCmd implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender cs, Command cmnd, String label, String[] args) {
|
||||
if (!cs.hasPermission("anura.realisticmc.infobarset")) {
|
||||
Msg.noPerms(cs);
|
||||
return true;
|
||||
}
|
||||
if (!(cs instanceof Player)) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "This is a player command!");
|
||||
return true;
|
||||
}
|
||||
if (args.length < 2 || args.length > 3) {
|
||||
return false;
|
||||
}
|
||||
if (!((HumanEntity) cs).getGameMode().equals(GameMode.SURVIVAL)) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Dieses Command kann nur im SURVIVAL Mode verwendet werden");
|
||||
return true;
|
||||
}
|
||||
ValueHolder valueHolder = ValueHolder.getValueHolder((Player) cs);
|
||||
if (valueHolder == null) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Es ist einer interner Fehler aufgetreten (0)");
|
||||
return true;
|
||||
}
|
||||
ThirstPlayer thirstPlayer = valueHolder.getPlayer(ThirstPlayer.class);
|
||||
TemperaturePlayer temperaturePlayer = valueHolder.getPlayer(TemperaturePlayer.class);
|
||||
if (thirstPlayer == null || temperaturePlayer == null) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Es ist einer interner Fehler aufgetreten (1)");
|
||||
return true;
|
||||
}
|
||||
Float value;
|
||||
try {
|
||||
value = Float.parseFloat(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "%s ist keine Zahl!", args[1]);
|
||||
return true;
|
||||
}
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "durst":
|
||||
if (thirstPlayer.getMIN() > value || thirstPlayer.getMAX() < value) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.SUCCESS, "Der Wert liegt außerhalb des Wertebereich.");
|
||||
return true;
|
||||
}
|
||||
thirstPlayer.setValue(value);
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.SUCCESS, "Der Durst wurde auf %i gesetzt!", value);
|
||||
return true;
|
||||
case "temp":
|
||||
case "temperatur":
|
||||
if (temperaturePlayer.getMIN() > value || temperaturePlayer.getMAX() < value) {
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.SUCCESS, "Der Wert liegt außerhalb des Wertebereich.");
|
||||
return true;
|
||||
}
|
||||
temperaturePlayer.setValue(value);
|
||||
Msg.send(cs, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.SUCCESS, "Die Temperatur wurde auf %i gesetzt!", value);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender cs, Command cmnd, String label, String[] args) {
|
||||
List<String> list = new ArrayList<>();
|
||||
switch (args.length) {
|
||||
case 1:
|
||||
list.add("durst");
|
||||
list.add("temp");
|
||||
break;
|
||||
case 2:
|
||||
return list;
|
||||
}
|
||||
return list.stream().filter((s) -> s.startsWith(args[args.length - 1])).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
135
src/de/anura/realisticminecraft/fishing/FishingChunk.java
Normal file
135
src/de/anura/realisticminecraft/fishing/FishingChunk.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package de.anura.realisticminecraft.fishing;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import de.anura.core.AnuraThread;
|
||||
import de.anura.core.database.DB;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
|
||||
public class FishingChunk {
|
||||
|
||||
private static final double CHUNK_REGENERATION = 9.0 / 60.0; // 1 per 7 minutes
|
||||
private static final int MAX_FISHES = 15; // within chunk
|
||||
|
||||
//////////////////
|
||||
private int id;
|
||||
private final Chunk chunk;
|
||||
private double catched;
|
||||
private long lastUpdated;
|
||||
|
||||
public FishingChunk(Chunk chunk) {
|
||||
this(chunk, 0, System.currentTimeMillis() / 1000, -1);
|
||||
}
|
||||
|
||||
public FishingChunk(Chunk chunk, int catched, long lastUpdated, int id) {
|
||||
this.id = id;
|
||||
this.chunk = chunk;
|
||||
this.catched = catched;
|
||||
this.lastUpdated = lastUpdated;
|
||||
}
|
||||
|
||||
public Chunk getChunk() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
long notUpdatedTime = System.currentTimeMillis() / 1000 - lastUpdated;
|
||||
long minutes = notUpdatedTime / 60;
|
||||
|
||||
catched -= minutes * CHUNK_REGENERATION;
|
||||
if (catched < 0) {
|
||||
catched = 0;
|
||||
}
|
||||
|
||||
this.lastUpdated = System.currentTimeMillis() / 1000 - (notUpdatedTime % 60);
|
||||
}
|
||||
|
||||
private int getFishes() {
|
||||
update();
|
||||
int fishes = MAX_FISHES - (int) Math.ceil(catched);
|
||||
if (fishes < 0) {
|
||||
fishes = 0;
|
||||
}
|
||||
return fishes;
|
||||
}
|
||||
|
||||
public boolean isOverfished() {
|
||||
return getFishes() == 0;
|
||||
}
|
||||
|
||||
public void addCatched() {
|
||||
catched += 1;
|
||||
save(true);
|
||||
}
|
||||
|
||||
public void save(boolean async) {
|
||||
update();
|
||||
if (id <= 0) {
|
||||
DB.queryUpdate(async, DB.getFirstKey((key) -> {
|
||||
id = key;
|
||||
}), "INSERT INTO fishingChunks (x, z, world, catched, lastUpdated) VALUES (?, ?, ?, ?, ?)",
|
||||
chunk.getX(), chunk.getZ(), chunk.getWorld().getName(), catched, lastUpdated);
|
||||
} else {
|
||||
DB.queryUpdate(async, "UPDATE fishingChunks SET catched = ?, lastUpdated = ? WHERE primeKey = ?",
|
||||
catched, lastUpdated, id);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
private static LoadingCache<Chunk, FishingChunk> FISHING_CACHE;
|
||||
private static final List<FishingTask> tasks = Collections.synchronizedList(new LinkedList<>());
|
||||
|
||||
public static void init() {
|
||||
CacheLoader<Chunk, FishingChunk> loader = new CacheLoader<Chunk, FishingChunk>() {
|
||||
@Override
|
||||
public FishingChunk load(Chunk chunk) throws Exception {
|
||||
ResultSet rs = DB.querySelect(
|
||||
"SELECT * FROM fishingChunks WHERE x = ? AND z = ? AND world = ?",
|
||||
chunk.getX(), chunk.getZ(), chunk.getWorld().getName()
|
||||
);
|
||||
if (!rs.first()) {
|
||||
return new FishingChunk(chunk);
|
||||
}
|
||||
return new FishingChunk(chunk, rs.getInt("catched"), rs.getInt("lastUpdated"), rs.getInt("primeKey"));
|
||||
}
|
||||
};
|
||||
|
||||
FISHING_CACHE = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||
.build(loader);
|
||||
|
||||
AnuraThread.add(Bukkit.getScheduler().runTaskTimerAsynchronously(RealisticMinecraft.getInstance(), () -> {
|
||||
synchronized (tasks) {
|
||||
Iterator<FishingTask> it = tasks.iterator();
|
||||
while (it.hasNext()) {
|
||||
FishingTask task = it.next();
|
||||
if (task.getTimestamp() < System.currentTimeMillis()) {
|
||||
task.getR().run();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 2, 2));
|
||||
}
|
||||
|
||||
public static FishingChunk get(Chunk chunk) {
|
||||
return FISHING_CACHE.getUnchecked(chunk);
|
||||
}
|
||||
|
||||
public static boolean contains(Chunk chunk) {
|
||||
return FISHING_CACHE.getIfPresent(chunk) != null;
|
||||
}
|
||||
|
||||
public static void queueTask(int secounds, Runnable r) {
|
||||
tasks.add(new FishingTask(System.currentTimeMillis() + (secounds * 1000), r));
|
||||
}
|
||||
}
|
||||
21
src/de/anura/realisticminecraft/fishing/FishingTask.java
Normal file
21
src/de/anura/realisticminecraft/fishing/FishingTask.java
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
package de.anura.realisticminecraft.fishing;
|
||||
|
||||
public class FishingTask {
|
||||
|
||||
private final long timestamp;
|
||||
private final Runnable r;
|
||||
|
||||
public FishingTask(long timestamp, Runnable r) {
|
||||
this.timestamp = timestamp;
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public Runnable getR() {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
6
src/de/anura/realisticminecraft/infobar/BarStatus.java
Normal file
6
src/de/anura/realisticminecraft/infobar/BarStatus.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
public enum BarStatus {
|
||||
STANDARD,
|
||||
AN;
|
||||
}
|
||||
79
src/de/anura/realisticminecraft/infobar/Infobar.java
Normal file
79
src/de/anura/realisticminecraft/infobar/Infobar.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import de.anura.core.AnuraThread;
|
||||
import java.util.Objects;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public abstract class Infobar<T extends RealisticPlayer> {
|
||||
|
||||
protected final T player;
|
||||
protected final BossBar bossbar;
|
||||
private BarStatus barstatus;
|
||||
private byte displaytime = 0;
|
||||
private BukkitTask task = null;
|
||||
|
||||
public Infobar(T p, String title, BarColor color, BarStyle style, BarStatus status) {
|
||||
Objects.requireNonNull(p);
|
||||
Objects.requireNonNull(status);
|
||||
player = p;
|
||||
bossbar = Bukkit.createBossBar(title, color, style);
|
||||
bossbar.addPlayer(player.getPlayer());
|
||||
barstatus = status;
|
||||
update();
|
||||
}
|
||||
|
||||
public BarStatus getBarStatus() {
|
||||
return barstatus;
|
||||
}
|
||||
|
||||
public void setBarStatus(BarStatus status) {
|
||||
Objects.requireNonNull(status);
|
||||
barstatus = status;
|
||||
update();
|
||||
player.updateDatabase(true);
|
||||
}
|
||||
|
||||
private void setBarVisible(boolean visible) {
|
||||
if (stayCondition()) {
|
||||
bossbar.setVisible(true);
|
||||
} else {
|
||||
bossbar.setVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
protected void destroy() {
|
||||
if (bossbar.getPlayers().contains(player.getPlayer())) {
|
||||
bossbar.removePlayer(player.getPlayer());
|
||||
}
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
bossbar.setProgress((player.getValue() - player.getMIN()) / (player.getMAX() - player.getMIN()));
|
||||
setBarVisible(true);
|
||||
startCountdown((byte) 5);
|
||||
}
|
||||
|
||||
protected boolean stayCondition() {
|
||||
return getBarStatus().equals(BarStatus.AN);
|
||||
}
|
||||
|
||||
protected void startCountdown(byte time) {
|
||||
displaytime = time;
|
||||
if (task == null) {
|
||||
task = Bukkit.getScheduler().runTaskTimerAsynchronously(RealisticMinecraft.getInstance(), () -> {
|
||||
if (displaytime > 0) {
|
||||
displaytime--;
|
||||
} else {
|
||||
setBarVisible(false);
|
||||
}
|
||||
}, 20, 20);
|
||||
AnuraThread.add(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
74
src/de/anura/realisticminecraft/infobar/InfobarUtil.java
Normal file
74
src/de/anura/realisticminecraft/infobar/InfobarUtil.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import de.anura.core.AnuraThread;
|
||||
import de.anura.core.msg.Message;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class InfobarUtil {
|
||||
|
||||
private static int round = 1;
|
||||
|
||||
public static void enableInfobarTasks() {
|
||||
JavaPlugin instance = RealisticMinecraft.getInstance();
|
||||
AnuraThread.add(Bukkit.getScheduler().runTaskTimerAsynchronously(instance, () -> {
|
||||
Bukkit.getOnlinePlayers().stream().filter((p) -> (p.getGameMode().equals(GameMode.SURVIVAL) && !p.isDead())).forEach((p) -> {
|
||||
ValueHolder vh = ValueHolder.getValueHolder(p);
|
||||
if (vh == null) {
|
||||
return;
|
||||
}
|
||||
ThirstPlayer thP = vh.getPlayer(ThirstPlayer.class);
|
||||
if (thP != null && vh.getPlayer(TemperaturePlayer.class) != null) {
|
||||
thP.calculateNewValue(p.getLocation());
|
||||
}
|
||||
if (round == 5) {
|
||||
TemperaturePlayer tempP = vh.getPlayer(TemperaturePlayer.class);
|
||||
if (tempP != null) {
|
||||
tempP.calculateNewValue(p.getLocation());
|
||||
if (tempP.isMIN()) {
|
||||
Message.sendActionBar(p, ChatColor.RED + "Dir ist zu kalt!");
|
||||
AnuraThread.queueSync(() -> p.damage(0.5));
|
||||
} else if (tempP.isMAX()) {
|
||||
Message.sendActionBar(p, ChatColor.RED + "Dir ist zu heiß!");
|
||||
AnuraThread.queueSync(() -> p.damage(0.5));
|
||||
}
|
||||
}
|
||||
if (thP != null) {
|
||||
if (thP.getValue() == 0) {
|
||||
Message.sendActionBar(p, ChatColor.RED + "Du bist durstig, trinke etwas!");
|
||||
if (p.getHealth() - 0.5 <= 0) {
|
||||
}
|
||||
AnuraThread.queueSync(() -> p.damage(0.5));
|
||||
} else if (thP.isThirsty() || thP.isWeak()) {
|
||||
Message.sendActionBar(p, ChatColor.YELLOW + "Du bist durstig, trinke etwas!");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (round == 5) {
|
||||
round = 0;
|
||||
}
|
||||
round++;
|
||||
}, 20, 20));
|
||||
|
||||
AnuraThread.add(Bukkit.getScheduler().runTaskTimerAsynchronously(instance, () -> {
|
||||
Bukkit.getOnlinePlayers().stream().filter((p) -> (p.getGameMode().equals(GameMode.SURVIVAL) && !p.isDead())).forEach((p) -> {
|
||||
ValueHolder vh = ValueHolder.getValueHolder(p);
|
||||
if (vh == null) {
|
||||
return;
|
||||
}
|
||||
TemperaturePlayer tmp = vh.getPlayer(TemperaturePlayer.class);
|
||||
if (tmp != null) {
|
||||
tmp.updateDatabase(false);
|
||||
}
|
||||
ThirstPlayer thp = vh.getPlayer(ThirstPlayer.class);
|
||||
if (thp != null) {
|
||||
thp.updateDatabase(false);
|
||||
}
|
||||
});
|
||||
}, 20 * 60, 20 * 60));
|
||||
}
|
||||
}
|
||||
101
src/de/anura/realisticminecraft/infobar/RealisticPlayer.java
Normal file
101
src/de/anura/realisticminecraft/infobar/RealisticPlayer.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import de.anura.core.database.DB;
|
||||
import java.util.Objects;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class RealisticPlayer {
|
||||
|
||||
protected final short MIN;
|
||||
protected final short MAX;
|
||||
protected final short DEFAULT;
|
||||
protected float value;
|
||||
protected final Player player;
|
||||
protected Infobar<? extends RealisticPlayer> bar;
|
||||
|
||||
protected RealisticPlayer(Player p, float value, short MIN, short MAX, short DEFAULT) {
|
||||
Objects.requireNonNull(p);
|
||||
player = p;
|
||||
this.MIN = MIN;
|
||||
this.MAX = MAX;
|
||||
this.DEFAULT = DEFAULT;
|
||||
if (value == -1) {
|
||||
this.value = DEFAULT;
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float getValue() {
|
||||
return ((int) (value * 10)) / 10f;
|
||||
}
|
||||
|
||||
public float setValue(float value) {
|
||||
boolean updated = this.value != value;
|
||||
if (updated) {
|
||||
changeValue(value);
|
||||
if (value > MAX) {
|
||||
this.value = MAX;
|
||||
} else if (value < MIN) {
|
||||
this.value = MIN;
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
bar.update();
|
||||
}
|
||||
return getValue();
|
||||
}
|
||||
|
||||
public float addValue(float modifier) {
|
||||
if (blockmodify() || modifier == 0) {
|
||||
return getValue();
|
||||
}
|
||||
return setValue(value + modifier);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public short getMIN() {
|
||||
return MIN;
|
||||
}
|
||||
|
||||
public boolean isMIN() {
|
||||
return value == MIN;
|
||||
}
|
||||
|
||||
public short getMAX() {
|
||||
return MAX;
|
||||
}
|
||||
|
||||
public boolean isMAX() {
|
||||
return value == MAX;
|
||||
}
|
||||
|
||||
public short getDEFAULT() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
public boolean isExtremeValue() {
|
||||
return isMIN() || isMAX();
|
||||
}
|
||||
|
||||
public Infobar<? extends RealisticPlayer> getBar() {
|
||||
return bar;
|
||||
}
|
||||
|
||||
protected void changeValue(float newValue) {
|
||||
}
|
||||
|
||||
protected abstract boolean blockmodify();
|
||||
|
||||
protected abstract float calculateNewValue(Location l);
|
||||
|
||||
protected void updateDatabase(boolean async) {
|
||||
DB.queryUpdate(async, "INSERT INTO " + getTableName() + " (`playerId`, `value`, `bar`) VALUES((SELECT id FROM players WHERE uuid = ?),?,?) ON DUPLICATE KEY UPDATE value = ?, bar = ?", player.getUniqueId().toString(), value, bar.getBarStatus().ordinal(), value, bar.getBarStatus().ordinal());
|
||||
}
|
||||
|
||||
public abstract String getTableName();
|
||||
}
|
||||
29
src/de/anura/realisticminecraft/infobar/TemperatureBar.java
Normal file
29
src/de/anura/realisticminecraft/infobar/TemperatureBar.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
|
||||
public class TemperatureBar extends Infobar<TemperaturePlayer> {
|
||||
|
||||
public TemperatureBar(TemperaturePlayer p, BarStatus status) {
|
||||
super(p, "Temperatur", BarColor.GREEN, BarStyle.SOLID, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
bossbar.setTitle("Temperatur (" + player.getValue() + "°M)");
|
||||
if (player.isExtremeValue()) {
|
||||
bossbar.setColor(BarColor.RED);
|
||||
} else if (player.isWarning()) {
|
||||
bossbar.setColor(BarColor.YELLOW);
|
||||
} else {
|
||||
bossbar.setColor(BarColor.GREEN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean stayCondition() {
|
||||
return super.stayCondition() || player.isWarning();
|
||||
}
|
||||
}
|
||||
221
src/de/anura/realisticminecraft/infobar/TemperatureModifier.java
Normal file
221
src/de/anura/realisticminecraft/infobar/TemperatureModifier.java
Normal file
@@ -0,0 +1,221 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import de.anura.core.selections.CuboidSelection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Furnace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public abstract class TemperatureModifier {
|
||||
|
||||
private static final float RAIN_MOD = -0.075f;
|
||||
private static final float WATER_MOD = -0.5f;
|
||||
private static final float FIRE_MOD = 0.5f;
|
||||
private static final float WARM_MOD = 0.2f;
|
||||
|
||||
public static final float DRINK_MOD = -1f;
|
||||
public static final float EAT_MOD = 2f;
|
||||
|
||||
public static float getModifier(Player p, Location l, TemperaturePlayer tp) {
|
||||
float modifier = Biome.getModifier(l.getBlock());
|
||||
if (modifier == 0) {
|
||||
if (tp.getValue() < tp.getDEFAULT()) {
|
||||
modifier += 0.1f;
|
||||
} else if (tp.getValue() > tp.getDEFAULT()) {
|
||||
modifier += -0.1f;
|
||||
}
|
||||
} else if (modifier > 0) {
|
||||
World w = l.getWorld();
|
||||
if (w != null && w.hasStorm() && tp.getValue() > tp.getDEFAULT() && tp.isWarning()) {
|
||||
modifier = 0;
|
||||
}
|
||||
}
|
||||
modifier += getRainModifier(l);
|
||||
modifier += getWaterModifier(l, tp);
|
||||
modifier += getFireModifier(p);
|
||||
modifier += getLavaModifer(l);
|
||||
modifier += getWarmModifier(l);
|
||||
modifier += Equipment.getModifier(p.getEquipment(), modifier);
|
||||
// if (TheTownAPI.isInWarriors() && WarriorsProvider.isNomaden(p)) {
|
||||
// if (tp.getValue() > tp.getDEFAULT() && modifier > 0
|
||||
// || tp.getValue() < tp.getDEFAULT() && modifier < 0) {
|
||||
// modifier *= 0.25f;
|
||||
// }
|
||||
// }
|
||||
return modifier;
|
||||
}
|
||||
|
||||
private static float getRainModifier(Location l) {
|
||||
World w = l.getWorld();
|
||||
return w != null && w.hasStorm() && l.getBlock().getRelative(BlockFace.UP).getLightFromSky() == 0xF ? RAIN_MOD : 0;
|
||||
}
|
||||
|
||||
private static float getWaterModifier(Location l, TemperaturePlayer tp) {
|
||||
if (l.getWorld() != null) {
|
||||
Block b = l.getBlock();
|
||||
if (b.getTemperature() >= 0.9f && tp.getValue() < tp.getDEFAULT()) {
|
||||
return 0f;
|
||||
}
|
||||
return b.getType().equals(Material.WATER) ? WATER_MOD : 0;
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
|
||||
private static float getFireModifier(Player p) {
|
||||
return p.getFireTicks() > 0 ? FIRE_MOD : 0;
|
||||
}
|
||||
|
||||
private static float getLavaModifer(Location l) {
|
||||
return new CuboidSelection(l.getBlock(), 3).getCount(Material.LAVA) > 0 ? FIRE_MOD : 0;
|
||||
}
|
||||
|
||||
private static float getWarmModifier(Location l) {
|
||||
CuboidSelection sel = new CuboidSelection(l.getBlock(), 3);
|
||||
ArrayList<Block> blocks = sel.getBlocks(Material.FURNACE);
|
||||
boolean lit_furnace = false;
|
||||
for (Block b : blocks) {
|
||||
BlockData bd = b.getBlockData();
|
||||
if (bd instanceof Furnace) {
|
||||
Furnace f = (Furnace) bd;
|
||||
if (f.isLit()) {
|
||||
lit_furnace = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lit_furnace || sel.getCount(Material.FIRE) > 0 ? WARM_MOD : 0;
|
||||
}
|
||||
|
||||
private static enum Biome {
|
||||
COLD(-1f, 0.5f, 1.5f, 1f, -0.05f, 0.5f),
|
||||
WARM(0.9f, 1f, 1.5f, 1f, 0.05f, 1f),
|
||||
HOT(1f, 2f, 2f, 1f, 0.05f, 1.5f);
|
||||
|
||||
private final float minTemp, maxTemp, daySkalar, nightSkalar, modifier, sunModifier;
|
||||
|
||||
private Biome(float min, float max, float day, float night, float modifier, float sun) {
|
||||
minTemp = min;
|
||||
maxTemp = max;
|
||||
daySkalar = day;
|
||||
nightSkalar = night;
|
||||
this.modifier = modifier;
|
||||
sunModifier = sun;
|
||||
}
|
||||
|
||||
public float getMinTemp() {
|
||||
return minTemp;
|
||||
}
|
||||
|
||||
public float getMaxTemp() {
|
||||
return maxTemp;
|
||||
}
|
||||
|
||||
public float getDaySkalar() {
|
||||
return daySkalar;
|
||||
}
|
||||
|
||||
public float getNightSkalar() {
|
||||
return nightSkalar;
|
||||
}
|
||||
|
||||
public float getModifier() {
|
||||
return modifier;
|
||||
}
|
||||
|
||||
public float getSunModifier() {
|
||||
return sunModifier;
|
||||
}
|
||||
|
||||
public static float getModifier(Block b) {
|
||||
float modifier = 0;
|
||||
for (Biome biome : values()) {
|
||||
if (b.getTemperature() >= biome.getMinTemp() && b.getTemperature() <= biome.getMaxTemp()) {
|
||||
if (isDay(b)) {
|
||||
if (b.getLightFromSky() == 0xF && !b.getWorld().hasStorm()) {
|
||||
modifier += biome.getModifier() * biome.getDaySkalar() * biome.getSunModifier();
|
||||
} else {
|
||||
modifier += biome.getModifier() * biome.getDaySkalar();
|
||||
}
|
||||
} else {
|
||||
modifier += biome.getModifier() * biome.getNightSkalar();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return modifier;
|
||||
}
|
||||
|
||||
public static boolean isDay(Block b) {
|
||||
return b.getWorld().getTime() > 500 && b.getWorld().getTime() < 11500;
|
||||
}
|
||||
}
|
||||
|
||||
private static enum Equipment {
|
||||
LEATHER_BHL(5, Material.LEATHER_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_LEGGINGS),
|
||||
LEATHER_C(15, Material.LEATHER_CHESTPLATE),
|
||||
IRON_BHL(7.5f, Material.IRON_BOOTS, Material.IRON_HELMET, Material.IRON_LEGGINGS),
|
||||
IRON_C(17.5f, Material.IRON_CHESTPLATE),
|
||||
GOLD_BHL(10, Material.GOLDEN_BOOTS, Material.GOLDEN_HELMET, Material.GOLDEN_LEGGINGS),
|
||||
GOLD_C(20, Material.GOLDEN_CHESTPLATE),
|
||||
DIAMOND_BHL(12.5f, Material.DIAMOND_BOOTS, Material.DIAMOND_HELMET, Material.DIAMOND_LEGGINGS),
|
||||
DIAMOND_C(22.5f, Material.DIAMOND_CHESTPLATE);
|
||||
|
||||
private Equipment(float percentage, Material... mat) {
|
||||
this.percentage = percentage;
|
||||
this.material = Arrays.asList(mat);
|
||||
}
|
||||
|
||||
private final List<Material> material;
|
||||
private final float percentage;
|
||||
|
||||
private boolean contains(Material m) {
|
||||
return material.contains(m);
|
||||
}
|
||||
|
||||
private float getPercentage() {
|
||||
return percentage;
|
||||
}
|
||||
|
||||
private float getModifier(float tempModifier) {
|
||||
return tempModifier * getPercentage() / 100;
|
||||
}
|
||||
|
||||
private static float getModifier(Material m, float tempModifier) {
|
||||
for (Equipment e : values()) {
|
||||
if (e.contains(m)) {
|
||||
return e.getModifier(tempModifier);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static float getModifier(EntityEquipment ee, float tempModifier) {
|
||||
float modifier = 0;
|
||||
ItemStack boots = ee.getBoots();
|
||||
if (boots != null) {
|
||||
modifier += getModifier(boots.getType(), tempModifier);
|
||||
}
|
||||
ItemStack chestplate = ee.getChestplate();
|
||||
if (chestplate != null) {
|
||||
modifier += getModifier(chestplate.getType(), tempModifier);
|
||||
}
|
||||
ItemStack helmet = ee.getHelmet();
|
||||
if (helmet != null) {
|
||||
modifier += getModifier(helmet.getType(), tempModifier);
|
||||
}
|
||||
ItemStack leggins = ee.getLeggings();
|
||||
if (leggins != null) {
|
||||
modifier += getModifier(leggins.getType(), tempModifier);
|
||||
}
|
||||
return modifier * -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class TemperaturePlayer extends RealisticPlayer {
|
||||
|
||||
private static final short MIN_TEMP_WARNING = 20;
|
||||
private static final short MAX_TEMP_WARNING = 40;
|
||||
private static final short MIN_TEMP = 15;
|
||||
private static final short MAX_TEMP = 45;
|
||||
private static final short DEFAULT_TEMP = 30;
|
||||
|
||||
private static final short MIN_TEMP_DRINK = 30;
|
||||
private static final short MAX_TEMP_EAT = 35;
|
||||
|
||||
public TemperaturePlayer(Player p) {
|
||||
this(p, -1, BarStatus.STANDARD);
|
||||
}
|
||||
|
||||
public TemperaturePlayer(Player p, float temp, BarStatus status) {
|
||||
super(p, temp, MIN_TEMP, MAX_TEMP, DEFAULT_TEMP);
|
||||
bar = new TemperatureBar(this, status);
|
||||
}
|
||||
|
||||
public boolean isWarning() {
|
||||
return value >= MAX_TEMP_WARNING || value <= MIN_TEMP_WARNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float calculateNewValue(Location l) {
|
||||
float modifier = TemperatureModifier.getModifier(player, l, this);
|
||||
float returnField = modifier == 0 ? getValue() : addValue(modifier);
|
||||
if (value >= MAX_TEMP_WARNING) {
|
||||
ValueHolder vh = ValueHolder.getValueHolder(player);
|
||||
if (vh != null) {
|
||||
ThirstPlayer tp = vh.getPlayer(ThirstPlayer.class);
|
||||
if (tp != null) {
|
||||
tp.addValue(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnField;
|
||||
}
|
||||
|
||||
public float drink() {
|
||||
return value > MIN_TEMP_DRINK ? addValue(TemperatureModifier.DRINK_MOD) : getValue();
|
||||
}
|
||||
|
||||
public float eatSoup() {
|
||||
return value < MAX_TEMP_EAT ? addValue(TemperatureModifier.EAT_MOD) : getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean blockmodify() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return getStaticTableName();
|
||||
}
|
||||
|
||||
public static String getStaticTableName() {
|
||||
return "playerTemperature";
|
||||
}
|
||||
}
|
||||
16
src/de/anura/realisticminecraft/infobar/ThirstBar.java
Normal file
16
src/de/anura/realisticminecraft/infobar/ThirstBar.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
|
||||
public class ThirstBar extends Infobar<ThirstPlayer> {
|
||||
|
||||
public ThirstBar(ThirstPlayer p, BarStatus status) {
|
||||
super(p, "Durst", BarColor.BLUE, BarStyle.SOLID, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean stayCondition() {
|
||||
return super.stayCondition() || player.isNoSprint();
|
||||
}
|
||||
}
|
||||
118
src/de/anura/realisticminecraft/infobar/ThirstPlayer.java
Normal file
118
src/de/anura/realisticminecraft/infobar/ThirstPlayer.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import de.anura.core.tools.Potions;
|
||||
import de.anura.core.tools.Potions.CustomPotion;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public class ThirstPlayer extends RealisticPlayer {
|
||||
|
||||
private static final CustomPotion POTION_THIRSTY = new CustomPotion(new PotionEffect(PotionEffectType.CONFUSION, 0, 0), true);
|
||||
private static final CustomPotion POTION_WEAK_I = new CustomPotion(new PotionEffect(PotionEffectType.WEAKNESS, 0, 0), true);
|
||||
private static final CustomPotion POTION_WEAK_II = new CustomPotion(new PotionEffect(PotionEffectType.SLOW, 0, 0), true);
|
||||
|
||||
private static final short THIRSTY = 5;
|
||||
private static final short WEAK = 10;
|
||||
private static final short NO_SPRINT = 20;
|
||||
|
||||
private static final short MIN_V = 0;
|
||||
private static final short MAX_V = 100;
|
||||
|
||||
private static final float BASIC_MOD = -0.015f;
|
||||
private static final float DRINK_MOD = 10f;
|
||||
private static final float RAIN_MOD = 1f;
|
||||
private static final float FOODLEVEL_MOD = -1f;
|
||||
|
||||
private static final float NOMADEN_MOD = 0.25f;
|
||||
|
||||
public ThirstPlayer(Player p) {
|
||||
this(p, -1, BarStatus.STANDARD);
|
||||
}
|
||||
|
||||
public ThirstPlayer(Player p, float thirst, BarStatus status) {
|
||||
super(p, thirst, MIN_V, MAX_V, MAX_V);
|
||||
bar = new ThirstBar(this, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean blockmodify() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isThirsty() {
|
||||
return value <= THIRSTY;
|
||||
}
|
||||
|
||||
public boolean isWeak() {
|
||||
return value <= WEAK;
|
||||
}
|
||||
|
||||
public boolean isNoSprint() {
|
||||
return value <= NO_SPRINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float calculateNewValue(Location l) {
|
||||
float mod = BASIC_MOD;
|
||||
// if (TheTownAPI.isInWarriors() && WarriorsProvider.isNomaden(player)) {
|
||||
// mod *= NOMADEN_MOD;
|
||||
// }
|
||||
World w = l.getWorld();
|
||||
if (w != null && w.hasStorm() && l.getPitch() < -75 && l.getBlock().getRelative(BlockFace.UP).getLightFromSky() == 0xF) {
|
||||
mod += RAIN_MOD;
|
||||
}
|
||||
return addValue(mod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void changeValue(float newValue) {
|
||||
if (!isWeak() && newValue <= WEAK) {
|
||||
Potions.addCustomPotion(player, POTION_WEAK_I);
|
||||
Potions.addCustomPotion(player, POTION_WEAK_II);
|
||||
} else if (isWeak() && newValue > WEAK) {
|
||||
Potions.removeCustomPotion(player, POTION_WEAK_I);
|
||||
Potions.removeCustomPotion(player, POTION_WEAK_II);
|
||||
}
|
||||
if (!isThirsty() && newValue <= THIRSTY) {
|
||||
Potions.addCustomPotion(player, POTION_THIRSTY);
|
||||
} else if (isThirsty() && newValue > THIRSTY) {
|
||||
Potions.removeCustomPotion(player, POTION_THIRSTY);
|
||||
}
|
||||
}
|
||||
|
||||
public float drink() {
|
||||
return addValue(DRINK_MOD);
|
||||
}
|
||||
|
||||
public float foodLevelChange() {
|
||||
// if (TheTownAPI.isInWarriors() && WarriorsProvider.isNomaden(player)) {
|
||||
// return addValue(FOODLEVEL_MOD * NOMADEN_MOD);
|
||||
// }
|
||||
return addValue(FOODLEVEL_MOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return getStaticTableName();
|
||||
}
|
||||
|
||||
public static String getStaticTableName() {
|
||||
return "playerThirst";
|
||||
}
|
||||
|
||||
public static boolean isOcean(Biome b) {
|
||||
switch (b) {
|
||||
case OCEAN:
|
||||
case DEEP_OCEAN:
|
||||
case FROZEN_OCEAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
90
src/de/anura/realisticminecraft/infobar/ValueHolder.java
Normal file
90
src/de/anura/realisticminecraft/infobar/ValueHolder.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package de.anura.realisticminecraft.infobar;
|
||||
|
||||
import de.anura.core.database.DB;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ValueHolder {
|
||||
|
||||
private static final List<Class<? extends RealisticPlayer>> PLAYERS = Arrays.asList(TemperaturePlayer.class, ThirstPlayer.class);
|
||||
private static final Map<Player, ValueHolder> ALL = new ConcurrentHashMap<>();
|
||||
private final Map<Class<? extends RealisticPlayer>, RealisticPlayer> values = new ConcurrentHashMap<>();
|
||||
private final Player player;
|
||||
|
||||
public ValueHolder(Player p) {
|
||||
Objects.requireNonNull(p);
|
||||
ALL.put(p, this);
|
||||
player = p;
|
||||
PLAYERS.forEach(this::createPlayer);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public <T extends RealisticPlayer> T getPlayer(Class<T> clazz) {
|
||||
return (T) values.get(clazz);
|
||||
}
|
||||
|
||||
public Collection<RealisticPlayer> getPlayersList() {
|
||||
return values.values();
|
||||
}
|
||||
|
||||
private <T extends RealisticPlayer> void createPlayer(Class<T> clazz) {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
rs = DB.querySelect("SELECT value, bar FROM " + clazz.getDeclaredMethod("getStaticTableName").invoke(null) + " WHERE playerId = (SELECT id FROM players WHERE uuid = ?)", player.getUniqueId().toString());
|
||||
if (rs.next()) {
|
||||
T rp = clazz.getConstructor(Player.class, float.class, BarStatus.class).newInstance(player, rs.getFloat("value"), BarStatus.values()[rs.getInt("bar")]);
|
||||
values.put(clazz, rp);
|
||||
} else {
|
||||
values.put(clazz, clazz.getConstructor(Player.class).newInstance(player));
|
||||
}
|
||||
} catch (SQLException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException ex) {
|
||||
Logger.getLogger(ValueHolder.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
DB.closeRessources(rs);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends RealisticPlayer> void resetPlayer(Class<T> clazz) {
|
||||
values.get(clazz).setValue(values.get(clazz).getDEFAULT());
|
||||
}
|
||||
|
||||
public void resetHoldings() {
|
||||
PLAYERS.forEach(this::resetPlayer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ValueHolder getValueHolder(Player p) {
|
||||
return ALL.get(p);
|
||||
}
|
||||
|
||||
public static void removeValueHolder(Player p) {
|
||||
remove(ALL.remove(p));
|
||||
}
|
||||
|
||||
public static void destroyAll() {
|
||||
ALL.values().forEach(ValueHolder::remove);
|
||||
ALL.clear();
|
||||
}
|
||||
|
||||
private static void remove(ValueHolder vh) {
|
||||
if (vh != null) {
|
||||
vh.getPlayersList().forEach((rp) -> {
|
||||
rp.updateDatabase(false);
|
||||
rp.getBar().destroy();
|
||||
rp.changeValue(rp.getDEFAULT());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
105
src/de/anura/realisticminecraft/listener/Chairs.java
Normal file
105
src/de/anura/realisticminecraft/listener/Chairs.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package de.anura.realisticminecraft.listener;
|
||||
|
||||
import de.anura.core.events.AnuraLeaveEvent;
|
||||
import de.anura.core.msg.Msg;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import de.anura.realisticminecraft.util.ChairManager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.Bisected.Half;
|
||||
import org.bukkit.block.data.type.Stairs;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.spigotmc.event.entity.EntityDismountEvent;
|
||||
|
||||
public class Chairs implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
if (e.getBlock().getBlockData() instanceof Stairs && ChairManager.isSittingAnyone(e.getBlock())) {
|
||||
ChairManager.playerStandUp(e.getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDismount(EntityDismountEvent e) {
|
||||
if (e.getEntity() instanceof Player && e.getDismounted() instanceof ArmorStand) {
|
||||
Player p = (Player) e.getEntity();
|
||||
if (ChairManager.isSitting(p)) {
|
||||
ChairManager.playerStandUp(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockInteract(PlayerInteractEvent e) {
|
||||
final Player p = e.getPlayer();
|
||||
EquipmentSlot eq = e.getHand();
|
||||
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK) && !p.isSneaking() && eq != null && eq.equals(EquipmentSlot.HAND)) {
|
||||
final Block b = e.getClickedBlock();
|
||||
if (b != null && b.getBlockData() instanceof Stairs) {
|
||||
Stairs s = (Stairs) b.getBlockData();
|
||||
if (s.getHalf().equals(Half.BOTTOM)) {
|
||||
e.setCancelled(true);
|
||||
Material above = b.getLocation().add(0, 1, 0).getBlock().getType();
|
||||
if (!cloudAbove(above) && above.isSolid()) {
|
||||
Msg.send(p, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Da ist kein Platz zum Sitzen!");
|
||||
} else if (ChairManager.isSittingAnyone(b)) {
|
||||
if (!ChairManager.isSittingPlayer(b, p)) {
|
||||
Msg.send(p, RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, "Hier sitzt bereits jemand!");
|
||||
}
|
||||
} else if (ChairManager.isSitting(p)) {
|
||||
ChairManager.playerStandUp(p);
|
||||
ChairManager.playerSitDown(p, s, b);
|
||||
} else {
|
||||
ChairManager.playerSitDown(p, s, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerLeave(AnuraLeaveEvent e) {
|
||||
if (ChairManager.isSitting(e.getPlayer())) {
|
||||
ChairManager.playerStandUp(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean cloudAbove(Material m) {
|
||||
switch(m) {
|
||||
case BLACK_WALL_BANNER:
|
||||
case BLUE_WALL_BANNER:
|
||||
case BROWN_WALL_BANNER:
|
||||
case CYAN_WALL_BANNER:
|
||||
case GRAY_WALL_BANNER:
|
||||
case GREEN_WALL_BANNER:
|
||||
case LIGHT_BLUE_WALL_BANNER:
|
||||
case LIGHT_GRAY_WALL_BANNER:
|
||||
case LIME_WALL_BANNER:
|
||||
case MAGENTA_WALL_BANNER:
|
||||
case ORANGE_WALL_BANNER:
|
||||
case PINK_WALL_BANNER:
|
||||
case PURPLE_WALL_BANNER:
|
||||
case RED_WALL_BANNER:
|
||||
case WHITE_WALL_BANNER:
|
||||
case YELLOW_WALL_BANNER:
|
||||
case ACACIA_WALL_SIGN:
|
||||
case BIRCH_WALL_SIGN:
|
||||
case DARK_OAK_WALL_SIGN:
|
||||
case JUNGLE_WALL_SIGN:
|
||||
case OAK_WALL_SIGN:
|
||||
case SPRUCE_WALL_SIGN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/de/anura/realisticminecraft/listener/Fishing.java
Normal file
67
src/de/anura/realisticminecraft/listener/Fishing.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package de.anura.realisticminecraft.listener;
|
||||
|
||||
import de.anura.core.msg.Message;
|
||||
import de.anura.core.msg.Msg;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import de.anura.realisticminecraft.fishing.FishingChunk;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
|
||||
public class Fishing implements Listener {
|
||||
|
||||
private static final String FAILED_HOOK_NAME = ChatColor.DARK_RED + "✖✖✖";
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onFish(PlayerFishEvent ev) {
|
||||
|
||||
FishHook hook = ev.getHook();
|
||||
Chunk chunk = hook.getLocation().getChunk();
|
||||
|
||||
|
||||
switch (ev.getState()) {
|
||||
case FISHING: {
|
||||
if (!FishingChunk.contains(chunk)) {
|
||||
FishingChunk.queueTask(0, () -> FishingChunk.get(chunk));
|
||||
}
|
||||
// Wir warten 5 Sekunden, da dieser State (FISHING) direkt aufgerufen wird, wenn man die Angel auswirft.
|
||||
FishingChunk.queueTask(5 , () -> {
|
||||
if (hook.isDead() || !hook.isValid()) return;
|
||||
|
||||
FishingChunk newHookChunk = FishingChunk.get(hook.getLocation().getChunk());
|
||||
if (!newHookChunk.isOverfished()) return;
|
||||
|
||||
Message.sendActionBar(ev.getPlayer(), Msg.getMsg(RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, true, "Dieser Teil des Gewässer scheint überfischt zu sein!"));
|
||||
|
||||
hook.setCustomName(FAILED_HOOK_NAME);
|
||||
hook.setCustomNameVisible(true);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case BITE: {
|
||||
FishingChunk fishingChunk = FishingChunk.get(chunk);
|
||||
if (fishingChunk.isOverfished()) {
|
||||
Message.sendActionBar(ev.getPlayer(), Msg.getMsg(RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, true, "Dieser Teil des Gewässer scheint überfischt zu sein!"));
|
||||
hook.setCustomName(FAILED_HOOK_NAME);
|
||||
hook.setCustomNameVisible(true);
|
||||
ev.setCancelled(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CAUGHT_FISH: {
|
||||
FishingChunk fishingChunk = FishingChunk.get(chunk);
|
||||
if (fishingChunk.isOverfished()) {
|
||||
Message.sendActionBar(ev.getPlayer(), Msg.getMsg(RealisticMinecraft.PLUGIN_DATA, Msg.MsgType.ERROR, true, "Dieser Teil des Gewässer scheint überfischt zu sein!"));
|
||||
ev.setCancelled(true);
|
||||
ev.setExpToDrop(0);
|
||||
} else {
|
||||
fishingChunk.addCatched();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
132
src/de/anura/realisticminecraft/listener/Infobar.java
Normal file
132
src/de/anura/realisticminecraft/listener/Infobar.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package de.anura.realisticminecraft.listener;
|
||||
|
||||
import de.anura.core.AnuraThread;
|
||||
import de.anura.core.events.AnuraLeaveEvent;
|
||||
import de.anura.core.tools.Potions;
|
||||
import de.anura.core.tools.Potions.CustomPotion;
|
||||
import de.anura.realisticminecraft.infobar.TemperaturePlayer;
|
||||
import de.anura.realisticminecraft.infobar.ThirstPlayer;
|
||||
import de.anura.realisticminecraft.infobar.ValueHolder;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
import org.bukkit.event.player.PlayerItemConsumeEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSprintEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public class Infobar implements Listener {
|
||||
|
||||
private static final CustomPotion POTION_HUNGER_I = new CustomPotion(new PotionEffect(PotionEffectType.SLOW_DIGGING, 0, 0), true);
|
||||
private static final CustomPotion POTION_HUNGER_II = new CustomPotion(new PotionEffect(PotionEffectType.SLOW, 0, 0), true);
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
if (e.getEntity().getHealth() <= 0) {
|
||||
AnuraThread.async(() -> {
|
||||
final ValueHolder vh = ValueHolder.getValueHolder(e.getEntity());
|
||||
if (vh != null) {
|
||||
vh.resetHoldings();
|
||||
}
|
||||
Potions.removeCustomPotion(e.getEntity(), POTION_HUNGER_I);
|
||||
Potions.removeCustomPotion(e.getEntity(), POTION_HUNGER_II);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onItemConsume(PlayerItemConsumeEvent e) {
|
||||
final ValueHolder vh = ValueHolder.getValueHolder(e.getPlayer());
|
||||
if (vh == null) {
|
||||
return;
|
||||
}
|
||||
final TemperaturePlayer tp = vh.getPlayer(TemperaturePlayer.class);
|
||||
final ThirstPlayer thp = vh.getPlayer(ThirstPlayer.class);
|
||||
switch (e.getItem().getType()) {
|
||||
case MILK_BUCKET:
|
||||
case POTION:
|
||||
if (tp != null) {
|
||||
tp.drink();
|
||||
}
|
||||
if (thp != null) {
|
||||
thp.drink();
|
||||
}
|
||||
break;
|
||||
case MUSHROOM_STEW:
|
||||
if (tp != null) {
|
||||
tp.eatSoup();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onFoodLevelChange(FoodLevelChangeEvent e) {
|
||||
if (e.getEntity() instanceof Player) {
|
||||
Player p = (Player) e.getEntity();
|
||||
if (e.getFoodLevel() < p.getFoodLevel()) {
|
||||
final ValueHolder vh = ValueHolder.getValueHolder(p);
|
||||
if (vh != null) {
|
||||
ThirstPlayer tP = vh.getPlayer(ThirstPlayer.class);
|
||||
if (tP != null) {
|
||||
tP.foodLevelChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e.getFoodLevel() < 4) {
|
||||
Potions.addCustomPotion(p, POTION_HUNGER_I);
|
||||
Potions.addCustomPotion(p, POTION_HUNGER_II);
|
||||
} else {
|
||||
Potions.removeCustomPotion(p, POTION_HUNGER_I);
|
||||
Potions.removeCustomPotion(p, POTION_HUNGER_II);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onLogin(PlayerJoinEvent e) {
|
||||
if (e.getPlayer().getGameMode().equals(GameMode.SURVIVAL)) {
|
||||
AnuraThread.async(() -> new ValueHolder(e.getPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onChangeGameMode(PlayerGameModeChangeEvent e) {
|
||||
AnuraThread.async(() -> {
|
||||
if (e.getNewGameMode().equals(GameMode.SURVIVAL)) {
|
||||
new ValueHolder(e.getPlayer());
|
||||
if (e.getPlayer().getFoodLevel() < 4) {
|
||||
Potions.addCustomPotion(e.getPlayer(), POTION_HUNGER_I);
|
||||
Potions.addCustomPotion(e.getPlayer(), POTION_HUNGER_II);
|
||||
}
|
||||
} else {
|
||||
ValueHolder.removeValueHolder(e.getPlayer());
|
||||
Potions.removeCustomPotion(e.getPlayer(), POTION_HUNGER_I);
|
||||
Potions.removeCustomPotion(e.getPlayer(), POTION_HUNGER_II);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSprint(PlayerToggleSprintEvent e) {
|
||||
if (e.isSprinting()) {
|
||||
ValueHolder vh = ValueHolder.getValueHolder(e.getPlayer());
|
||||
if (vh != null) {
|
||||
ThirstPlayer tp = vh.getPlayer(ThirstPlayer.class);
|
||||
if (tp != null) {
|
||||
e.setCancelled(tp.isNoSprint());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDisconnect(AnuraLeaveEvent e) {
|
||||
AnuraThread.async(() -> ValueHolder.removeValueHolder(e.getPlayer()));
|
||||
}
|
||||
}
|
||||
83
src/de/anura/realisticminecraft/listener/Timber.java
Normal file
83
src/de/anura/realisticminecraft/listener/Timber.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package de.anura.realisticminecraft.listener;
|
||||
|
||||
import de.anura.core.AnuraThread;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import de.anura.realisticminecraft.timber.TreeFeller;
|
||||
import de.anura.realisticminecraft.timber.parser.TreeParser;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Orientable;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
|
||||
public class Timber implements Listener {
|
||||
|
||||
private static final Map<Player, BlockFace> LAST_INTERACT = new WeakHashMap<>();
|
||||
|
||||
public static BlockFace getLastInteract(Player p) {
|
||||
return LAST_INTERACT.get(p);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
if (isInOwnRegion() == e.getPlayer().isSneaking()) {
|
||||
return;
|
||||
}
|
||||
if (isTimberLog(e.getBlock().getType())) {
|
||||
EntityEquipment eq = e.getPlayer().getEquipment();
|
||||
if (e.getPlayer().getGameMode().equals(GameMode.SURVIVAL)
|
||||
&& eq != null && TreeFeller.isAxe(eq.getItemInMainHand().getType())
|
||||
&& ((Orientable) e.getBlock().getBlockData()).getAxis().equals(Axis.Y)) {
|
||||
e.setCancelled(true);
|
||||
AnuraThread.async(() -> {
|
||||
TreeParser treeParser = TreeParser.newTreeParser(e.getBlock());
|
||||
new TreeFeller(e.getPlayer(), treeParser.parse(getLastInteract(e.getPlayer())))
|
||||
.cut(eq.getItemInMainHand());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockInteract(PlayerInteractEvent e) {
|
||||
final Player p = e.getPlayer();
|
||||
if (e.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
|
||||
if (!p.getGameMode().equals(GameMode.SURVIVAL)) {
|
||||
return;
|
||||
}
|
||||
Block clickedBlock = e.getClickedBlock();
|
||||
if (clickedBlock != null && isTimberLog(clickedBlock.getType())) {
|
||||
LAST_INTERACT.put(p, e.getBlockFace());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInOwnRegion() {
|
||||
return false;//TODO: Get from region management
|
||||
}
|
||||
|
||||
public static boolean isTimberLog(Material m) {
|
||||
switch (m) {
|
||||
case ACACIA_LOG:
|
||||
case BIRCH_LOG:
|
||||
case DARK_OAK_LOG:
|
||||
case JUNGLE_LOG:
|
||||
case OAK_LOG:
|
||||
case SPRUCE_LOG:
|
||||
//@TODO: Check BARK
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
88
src/de/anura/realisticminecraft/timber/Tree.java
Normal file
88
src/de/anura/realisticminecraft/timber/Tree.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package de.anura.realisticminecraft.timber;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
public class Tree {
|
||||
|
||||
private final HashSet<Block> logList;
|
||||
private final HashSet<Block> leaveList;
|
||||
private final Block lowestLog;
|
||||
private Block highestBlock;
|
||||
private final BlockFace direction;
|
||||
private final Material wood;
|
||||
private final Material leave;
|
||||
private final TreeSpecies species;
|
||||
|
||||
public Tree(Block first, HashSet<Block> logs, HashSet<Block> leaves, BlockFace fallDirection, Material wood, Material leave, TreeSpecies species) {
|
||||
this.logList = logs;
|
||||
this.leaveList = leaves;
|
||||
this.lowestLog = first;
|
||||
this.wood = wood;
|
||||
this.leave = leave;
|
||||
this.species = species;
|
||||
if (fallDirection == null || fallDirection.equals(BlockFace.UP) || fallDirection.equals(BlockFace.DOWN)) {
|
||||
direction = BlockFace.values()[new Random().nextInt(4)];
|
||||
} else {
|
||||
direction = fallDirection.getOppositeFace();
|
||||
}
|
||||
Location loc = first.getLocation();
|
||||
loc.setY(0);
|
||||
highestBlock = loc.getBlock();
|
||||
logs.forEach((b) -> {
|
||||
if (b.getLocation().getY() > highestBlock.getLocation().getY()) {
|
||||
highestBlock = b;
|
||||
}
|
||||
});
|
||||
leaves.forEach((b) -> {
|
||||
if (b.getLocation().getY() > highestBlock.getLocation().getY()) {
|
||||
highestBlock = b;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HashSet<Block> getLogs() {
|
||||
return logList;
|
||||
}
|
||||
|
||||
public HashSet<Block> getLeaves() {
|
||||
return leaveList;
|
||||
}
|
||||
|
||||
public int getHeigth() {
|
||||
return highestBlock.getLocation().getBlockY() - lowestLog.getLocation().getBlockY();
|
||||
}
|
||||
|
||||
public Block getLowestLog() {
|
||||
return lowestLog;
|
||||
}
|
||||
|
||||
public Location getLowestLogLoc() {
|
||||
return lowestLog.getLocation();
|
||||
}
|
||||
|
||||
public BlockFace getFallDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public boolean isCuttable() {
|
||||
return leaveList.size() > 5;
|
||||
}
|
||||
|
||||
public Material getWood() {
|
||||
return wood;
|
||||
}
|
||||
|
||||
public Material getLeave() {
|
||||
return leave;
|
||||
}
|
||||
|
||||
public TreeSpecies getSpecies() {
|
||||
return species;
|
||||
}
|
||||
}
|
||||
212
src/de/anura/realisticminecraft/timber/TreeFeller.java
Normal file
212
src/de/anura/realisticminecraft/timber/TreeFeller.java
Normal file
@@ -0,0 +1,212 @@
|
||||
package de.anura.realisticminecraft.timber;
|
||||
|
||||
import de.anura.core.AnuraThread;
|
||||
import java.util.Random;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import de.anura.realisticminecraft.timber.event.AppleDropEvent;
|
||||
import de.anura.realisticminecraft.timber.event.TreeCutEvent;
|
||||
import de.anura.realisticminecraft.util.LogBlockProvider;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Orientable;
|
||||
import org.bukkit.block.data.type.Leaves;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class TreeFeller {
|
||||
|
||||
private final Tree t;
|
||||
private final Player p;
|
||||
private TreeCutEvent treeCutEvent;
|
||||
|
||||
public TreeFeller(Player p, Tree t) {
|
||||
this.p = p;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
public void cut(ItemStack axe) {
|
||||
if (!t.isCuttable()) {
|
||||
AnuraThread.queueSync(() -> {
|
||||
t.getLowestLogLoc().getBlock().breakNaturally(axe);
|
||||
});
|
||||
calculateDamage(axe, 1);
|
||||
p.getInventory().setItemInMainHand(axe);
|
||||
return;
|
||||
}
|
||||
treeCutEvent = new TreeCutEvent(p, t.getLowestLog());
|
||||
Bukkit.getPluginManager().callEvent(treeCutEvent);
|
||||
if (treeCutEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
calculateDamage(axe, 5);
|
||||
p.getInventory().setItemInMainHand(axe);
|
||||
World w = t.getLowestLogLoc().getWorld();
|
||||
if (w != null) {
|
||||
w.playSound(t.getLowestLogLoc(), Sound.BLOCK_GRASS_BREAK, 1, 0.1f);
|
||||
}
|
||||
for (int i = 0; i <= t.getHeigth(); i++) {
|
||||
cutLog(i);
|
||||
cutLeaves(i);
|
||||
}
|
||||
}
|
||||
|
||||
private void cutLog(int stage) {
|
||||
BlockData log = getLogOrientation();
|
||||
t.getLogs().stream().filter(b -> b.getLocation().getBlockY() == t.getLowestLogLoc().getBlockY() + stage).forEach(b -> {
|
||||
AnuraThread.queueSync(() -> {
|
||||
queueBlockBreak(p, b);
|
||||
b.setType(Material.AIR);
|
||||
Location pLocation = getPossibleLocation(b, stage);
|
||||
FallingBlock spawnFallingBlock = b.getWorld().spawnFallingBlock(pLocation.add(0.5, 0, 0.5), log);
|
||||
spawnFallingBlock.setDropItem(false);
|
||||
queueFallingBlock(p, pLocation, log);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void cutLeaves(int stage) {
|
||||
BlockData ld = getLeavesData();
|
||||
Random r = new Random();
|
||||
short appleCount = 0;
|
||||
for (Block b : t.getLeaves()) {
|
||||
if (b.getLocation().getBlockY() == t.getLowestLogLoc().getBlockY() + stage) {
|
||||
if (r.nextBoolean()) {
|
||||
ItemStack is;
|
||||
if (treeCutEvent.getSaplingDropChance() > 0 && r.nextInt(treeCutEvent.getSaplingDropChance()) == 0) {
|
||||
is = new ItemStack(getSaplingMaterial());
|
||||
} else if (treeCutEvent.getAppleDropChance() > 0 && r.nextInt(treeCutEvent.getAppleDropChance()) == 0) {
|
||||
is = new ItemStack(Material.APPLE);
|
||||
appleCount++;
|
||||
} else if (treeCutEvent.getLeavesDropChance() > 0 && r.nextInt(treeCutEvent.getLeavesDropChance()) == 0) {
|
||||
is = new ItemStack(t.getLeave());
|
||||
} else {
|
||||
AnuraThread.queueSync(() -> {
|
||||
queueBlockBreak(p, b);
|
||||
b.setType(Material.AIR);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
AnuraThread.queueSync(() -> {
|
||||
b.getWorld().dropItemNaturally(getPossibleLocation(b, stage).add(0.5, 0, 0.5), is);
|
||||
queueBlockBreak(p, b);
|
||||
b.setType(Material.AIR);
|
||||
});
|
||||
} else {
|
||||
AnuraThread.queueSync(() -> {
|
||||
queueBlockBreak(p, b);
|
||||
b.setType(Material.AIR);
|
||||
Location pLocation = getPossibleLocation(b, stage);
|
||||
b.getWorld().spawnFallingBlock(pLocation.add(0.5, 0, 0.5), ld);
|
||||
queueFallingBlock(p, pLocation, ld);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (appleCount > 0) {
|
||||
Bukkit.getPluginManager().callEvent(new AppleDropEvent(p, appleCount));
|
||||
}
|
||||
}
|
||||
|
||||
private static void calculateDamage(ItemStack is, int damage) {
|
||||
ItemMeta im = is.getItemMeta();
|
||||
if (!(im instanceof Damageable)) {
|
||||
return;
|
||||
}
|
||||
Damageable d = (Damageable) im;
|
||||
if (is.getType().getMaxDurability() - d.getDamage() - damage < 0) {
|
||||
is.setType(Material.AIR);
|
||||
} else {
|
||||
d.setDamage((short) (d.getDamage() + damage));
|
||||
}
|
||||
}
|
||||
|
||||
private BlockData getLogOrientation() {
|
||||
Orientable o = (Orientable) t.getWood().createBlockData();
|
||||
o.setAxis(convertDirection(t.getFallDirection()));
|
||||
return o;
|
||||
}
|
||||
|
||||
private BlockData getLeavesData() {
|
||||
Leaves l = (Leaves) t.getLeave().createBlockData();
|
||||
l.setPersistent(true);//@TODO: Check if needed
|
||||
return l;
|
||||
}
|
||||
|
||||
private Material getSaplingMaterial() {
|
||||
switch (t.getWood()) {
|
||||
case BIRCH_LOG:
|
||||
return Material.BIRCH_SAPLING;
|
||||
case SPRUCE_LOG:
|
||||
return Material.SPRUCE_SAPLING;
|
||||
case JUNGLE_LOG:
|
||||
return Material.JUNGLE_SAPLING;
|
||||
case ACACIA_LOG:
|
||||
return Material.ACACIA_SAPLING;
|
||||
case DARK_OAK_LOG:
|
||||
return Material.DARK_OAK_SAPLING;
|
||||
case OAK_LOG:
|
||||
default:
|
||||
return Material.OAK_SAPLING;
|
||||
}
|
||||
}
|
||||
|
||||
private Location getPossibleLocation(Block start, int stage) {
|
||||
if (stage != 0) {
|
||||
for (int i = 1; i <= stage; i++) {
|
||||
Block b = start.getRelative(t.getFallDirection(), i);
|
||||
if (b.getType().isSolid() && !t.getLogs().contains(b) && !t.getLeaves().contains(b)) {
|
||||
return start.getRelative(t.getFallDirection(), i - 1).getLocation();
|
||||
}
|
||||
}
|
||||
return start.getRelative(t.getFallDirection(), stage).getLocation();
|
||||
}
|
||||
return start.getLocation();
|
||||
}
|
||||
|
||||
private static Axis convertDirection(BlockFace bf) {
|
||||
switch (bf) {
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
return Axis.Z;
|
||||
case EAST:
|
||||
case WEST:
|
||||
default:
|
||||
return Axis.X;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isAxe(Material mat) {
|
||||
switch (mat) {
|
||||
case WOODEN_AXE:
|
||||
case STONE_AXE:
|
||||
case IRON_AXE:
|
||||
case GOLDEN_AXE:
|
||||
case DIAMOND_AXE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void queueBlockBreak(Player p, Block b) {
|
||||
if (RealisticMinecraft.hasLogBlock()) {
|
||||
LogBlockProvider.queueBlockBreak(p, b);
|
||||
}
|
||||
}
|
||||
|
||||
public static void queueFallingBlock(Player p, Location l, BlockData bd) {
|
||||
if (RealisticMinecraft.hasLogBlock()) {
|
||||
LogBlockProvider.queueFalling(p, l, bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package de.anura.realisticminecraft.timber.event;
|
||||
|
||||
import de.anura.core.events.AnuraPlayerEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class AppleDropEvent extends AnuraPlayerEvent {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final short amount;
|
||||
|
||||
public AppleDropEvent(Player p, short amount) {
|
||||
super(p, true);
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package de.anura.realisticminecraft.timber.event;
|
||||
|
||||
import de.anura.core.events.AnuraPlayerEvent;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class TreeCutEvent extends AnuraPlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final Block block;
|
||||
private boolean cancel = false;
|
||||
private short saplingDropChance = 25;
|
||||
private short appleDropChance = 110;
|
||||
private short leavesDropChance = 45;
|
||||
|
||||
public TreeCutEvent(Player p, Block b) {
|
||||
super(p, true);
|
||||
this.block = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
public short getSaplingDropChance() {
|
||||
return saplingDropChance;
|
||||
}
|
||||
|
||||
public void setSaplingDropChance(short dropChance) {
|
||||
this.saplingDropChance = dropChance;
|
||||
}
|
||||
|
||||
public short getAppleDropChance() {
|
||||
return appleDropChance;
|
||||
}
|
||||
|
||||
public void setAppleDropChance(short dropChance) {
|
||||
this.appleDropChance = dropChance;
|
||||
}
|
||||
|
||||
public short getLeavesDropChance() {
|
||||
return leavesDropChance;
|
||||
}
|
||||
|
||||
public void setLeavesDropChance(short dropChance) {
|
||||
this.leavesDropChance = dropChance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class AcaciaTreeParser extends TreeParser {
|
||||
|
||||
protected AcaciaTreeParser(Block first) {
|
||||
super(first);
|
||||
wood = Material.ACACIA_LOG;
|
||||
leave = Material.ACACIA_LEAVES;
|
||||
species = TreeSpecies.ACACIA;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Sets.newHashSet(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0),
|
||||
new Vector(1, 1, 1), new Vector(-1, 1, -1), new Vector(-1, 1, 1), new Vector(1, 1, -1),
|
||||
new Vector(0, 1, 1), new Vector(0, 1, -1), new Vector(-1, 1, 0), new Vector(1, 1, 0),
|
||||
new Vector(0, 1, 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class BigBirchTreeParser extends BirchTreeParser {
|
||||
|
||||
protected BigBirchTreeParser(Block first) {
|
||||
super(first);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Sets.newHashSet(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class BigJungleTreeParser extends JungleTreeParser {
|
||||
|
||||
protected BigJungleTreeParser(Block first) {
|
||||
super(first);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Sets.newHashSet(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0),
|
||||
new Vector(1, 1, 1), new Vector(-1, 1, -1), new Vector(-1, 1, 1), new Vector(1, 1, -1),
|
||||
new Vector(1, 0, 1), new Vector(-1, 0, -1), new Vector(-1, 0, 1), new Vector(1, 0, -1),
|
||||
new Vector(0, 1, 1), new Vector(0, 1, -1), new Vector(-1, 1, 0), new Vector(1, 1, 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class BigOakTreeParser extends OakTreeParser {
|
||||
|
||||
protected BigOakTreeParser(Block first) {
|
||||
super(first);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Sets.newHashSet(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class BigSpruceTreeParser extends SpruceTreeParser {
|
||||
|
||||
public BigSpruceTreeParser(Block first) {
|
||||
super(first);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Sets.newHashSet(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0),
|
||||
new Vector(0, 1, 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class BirchTreeParser extends TreeParser {
|
||||
|
||||
protected BirchTreeParser(Block first) {
|
||||
super(first);
|
||||
wood = Material.BIRCH_LOG;
|
||||
leave = Material.BIRCH_LEAVES;
|
||||
species = TreeSpecies.BIRCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class DarkOakTreeParser extends TreeParser {
|
||||
|
||||
protected DarkOakTreeParser(Block first) {
|
||||
super(first);
|
||||
wood = Material.DARK_OAK_LOG;
|
||||
leave = Material.DARK_OAK_LEAVES;
|
||||
species = TreeSpecies.DARK_OAK;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Sets.newHashSet(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0),
|
||||
new Vector(1, 0, 1), new Vector(-1, 0, -1), new Vector(-1, 0, 1), new Vector(1, 0, -1),
|
||||
new Vector(0, 1, 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class JungleTreeParser extends TreeParser {
|
||||
|
||||
protected JungleTreeParser(Block first) {
|
||||
super(first);
|
||||
wood = Material.JUNGLE_LOG;
|
||||
leave = Material.JUNGLE_LEAVES;
|
||||
species = TreeSpecies.JUNGLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import java.util.HashSet;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class LeaveParser {
|
||||
|
||||
private final Block firstBlock;
|
||||
private final TreeParser tp;
|
||||
private final HashSet<Block> leaveList = new HashSet<>();
|
||||
|
||||
protected LeaveParser(TreeParser tp, Block firstBlock) {
|
||||
this.tp = tp;
|
||||
this.firstBlock = firstBlock;
|
||||
}
|
||||
|
||||
protected HashSet<Block> parse() {
|
||||
tp.getDirsLeaves().stream()
|
||||
.map((v) -> firstBlock.getRelative(v.getBlockX(), v.getBlockY(), v.getBlockZ()))
|
||||
.forEach(this::parseLeaves);
|
||||
return leaveList;
|
||||
}
|
||||
|
||||
private void parseLeaves(Block b) {
|
||||
if (leaveList.contains(b) ||
|
||||
TreeParser.isDistanceBiggerThan(firstBlock.getLocation(), b.getLocation(), tp.getMaxLeavesDistance())) {
|
||||
return;
|
||||
}
|
||||
if (isLeaves(b)) {
|
||||
leaveList.add(b);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
tp.getDirsLeaves().stream().map((v) -> b.getRelative(v.getBlockX(), v.getBlockY(), v.getBlockZ()))
|
||||
.filter((r) -> (r.getLocation().getBlockY() >= firstBlock.getLocation().getBlockY()))
|
||||
.forEach(this::parseLeaves);
|
||||
}
|
||||
|
||||
private boolean isLeaves(Block b) {
|
||||
return b.getType().equals(tp.leave);
|
||||
}
|
||||
}
|
||||
54
src/de/anura/realisticminecraft/timber/parser/LogParser.java
Normal file
54
src/de/anura/realisticminecraft/timber/parser/LogParser.java
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class LogParser {
|
||||
|
||||
private final Block firstBlock;
|
||||
private final TreeParser tp;
|
||||
private final HashSet<Block> logList = new HashSet<>();
|
||||
|
||||
protected LogParser(TreeParser tp, Block firstBlock) {
|
||||
this.tp = tp;
|
||||
this.firstBlock = firstBlock;
|
||||
}
|
||||
|
||||
protected HashSet<Block> parse() {
|
||||
tp.getDirsLog().stream()
|
||||
.map((v) -> firstBlock.getRelative(v.getBlockX(), v.getBlockY(), v.getBlockZ()))
|
||||
.forEach(this::parseLog);
|
||||
return logList;
|
||||
}
|
||||
|
||||
private void parseLog(Block b) {
|
||||
if (logList.contains(b) ||
|
||||
TreeParser.isDistanceBiggerThan(firstBlock.getLocation(), b.getLocation(), tp.getMaxLogDistance())) {
|
||||
return;
|
||||
}
|
||||
if (isWood(b)) {
|
||||
logList.add(b);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
tp.getDirsLog().stream().map((v) -> b.getRelative(v.getBlockX(), v.getBlockY(), v.getBlockZ()))
|
||||
.forEach(this::parseLog);
|
||||
}
|
||||
|
||||
private boolean isWood(Block b) {
|
||||
try {
|
||||
return b.getType().equals(tp.wood);
|
||||
} catch (ConcurrentModificationException ex) {
|
||||
try {
|
||||
Thread.sleep(2);
|
||||
} catch (InterruptedException ex1) {
|
||||
Logger.getLogger(LogParser.class.getName()).log(Level.SEVERE, null, ex1);
|
||||
}
|
||||
return isWood(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class OakTreeParser extends TreeParser {
|
||||
|
||||
protected OakTreeParser(Block first) {
|
||||
super(first);
|
||||
wood = Material.OAK_LOG;
|
||||
leave = Material.OAK_LEAVES;
|
||||
species = TreeSpecies.GENERIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Sets.newHashSet(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0),
|
||||
new Vector(1, 1, 1), new Vector(-1, 1, -1), new Vector(-1, 1, 1), new Vector(1, 1, -1),
|
||||
new Vector(1, 0, 1), new Vector(-1, 0, -1), new Vector(-1, 0, 1), new Vector(1, 0, -1),
|
||||
new Vector(1, 1, 0), new Vector(-1, 1, 0), new Vector(0, 1, 1), new Vector(0, 1, -1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class SpruceTreeParser extends TreeParser {
|
||||
|
||||
SpruceTreeParser(Block first) {
|
||||
super(first);
|
||||
wood = Material.SPRUCE_LOG;
|
||||
leave = Material.SPRUCE_LEAVES;
|
||||
species = TreeSpecies.REDWOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLeavesDistance() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxLogDistance() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxTrunkSize() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
128
src/de/anura/realisticminecraft/timber/parser/TreeParser.java
Normal file
128
src/de/anura/realisticminecraft/timber/parser/TreeParser.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package de.anura.realisticminecraft.timber.parser;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import de.anura.realisticminecraft.listener.Timber;
|
||||
import de.anura.realisticminecraft.timber.Tree;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeSpecies;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public abstract class TreeParser {
|
||||
|
||||
private final HashSet<Block> logList = new HashSet<>();
|
||||
private final HashSet<Block> leaveList = new HashSet<>();
|
||||
private final Block firstBlock;
|
||||
protected Material wood;
|
||||
protected Material leave;
|
||||
protected TreeSpecies species;
|
||||
|
||||
protected TreeParser(Block first) {
|
||||
firstBlock = first;
|
||||
}
|
||||
|
||||
public Tree parse(BlockFace bf) {
|
||||
parseTrunk(firstBlock);
|
||||
if (getMaxTrunkSize() > 0) {
|
||||
getDirsStamm().stream().map((v) -> firstBlock.getRelative(v.getBlockX(), v.getBlockY(), v.getBlockZ()))
|
||||
.forEach(this::parseTrunk);
|
||||
}
|
||||
new HashSet<>(logList).forEach((b) -> {
|
||||
logList.addAll(new LogParser(this, b).parse());
|
||||
});
|
||||
logList.forEach((b) -> {
|
||||
leaveList.addAll(new LeaveParser(this, b).parse());
|
||||
});
|
||||
return new Tree(firstBlock, logList, leaveList, bf, wood, leave, species);
|
||||
}
|
||||
|
||||
private void parseTrunk(Block b) {
|
||||
if (logList.size() > 1 && logList.contains(b) || TreeParser.isDistanceBiggerThan(firstBlock.getLocation(), b.getLocation(), getMaxTrunkSize())) {
|
||||
return;
|
||||
}
|
||||
if (isWood(b)) {
|
||||
logList.add(b);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
parseTrunk(b.getRelative(BlockFace.UP));
|
||||
}
|
||||
|
||||
private boolean isWood(Block b) {
|
||||
return b.getType().equals(wood);
|
||||
}
|
||||
|
||||
protected Collection<Vector> getDirsLog() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
protected Collection<Vector> getDirsStamm() {
|
||||
return Arrays.asList(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0),
|
||||
new Vector(1, 0, 1), new Vector(-1, 0, 1), new Vector(-1, 0, -1), new Vector(1, 0, -1));
|
||||
}
|
||||
|
||||
protected Collection<Vector> getDirsLeaves() {
|
||||
return Arrays.asList(new Vector(0, 1, 0), new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1),
|
||||
new Vector(-1, 0, 0));
|
||||
}
|
||||
|
||||
protected abstract int getMaxLeavesDistance();
|
||||
|
||||
protected abstract int getMaxLogDistance();
|
||||
|
||||
protected abstract int getMaxTrunkSize();
|
||||
|
||||
protected static boolean isDistanceBiggerThan(Location l1, Location l2, int distance) {
|
||||
int loc1 = l1.getBlockX();
|
||||
int loc2 = l2.getBlockX();
|
||||
int loc3 = l1.getBlockZ();
|
||||
int loc4 = l2.getBlockZ();
|
||||
return (Math.max(loc1, loc2) - Math.min(loc1, loc2)) > distance || (Math.max(loc3, loc4) - Math.min(loc3, loc4)) > distance;
|
||||
}
|
||||
|
||||
public static TreeParser newTreeParser(Block b) {
|
||||
if (!Timber.isTimberLog(b.getType())) {
|
||||
return null;
|
||||
}
|
||||
boolean fourLog = false;
|
||||
for (Vector v : Arrays.asList(new Vector(0, 0, -1), new Vector(1, 0, 0), new Vector(0, 0, 1), new Vector(-1, 0, 0))) {
|
||||
if (b.getRelative(v.getBlockX(), v.getBlockY(), v.getBlockZ()).getType().equals(b.getType())) {
|
||||
fourLog = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (b.getType()) {
|
||||
case DARK_OAK_LOG:
|
||||
return new DarkOakTreeParser(b);
|
||||
case ACACIA_LOG:
|
||||
return new AcaciaTreeParser(b);
|
||||
case JUNGLE_LOG:
|
||||
if (fourLog) {
|
||||
return new BigJungleTreeParser(b);
|
||||
}
|
||||
return new JungleTreeParser(b);
|
||||
case SPRUCE_LOG:
|
||||
if (fourLog) {
|
||||
return new BigSpruceTreeParser(b);
|
||||
}
|
||||
return new SpruceTreeParser(b);
|
||||
case BIRCH_LOG:
|
||||
if (fourLog) {
|
||||
return new BigBirchTreeParser(b);
|
||||
}
|
||||
return new BirchTreeParser(b);
|
||||
case OAK_LOG:
|
||||
if (fourLog) {
|
||||
return new BigOakTreeParser(b);
|
||||
}
|
||||
return new OakTreeParser(b);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
105
src/de/anura/realisticminecraft/util/ChairManager.java
Normal file
105
src/de/anura/realisticminecraft/util/ChairManager.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package de.anura.realisticminecraft.util;
|
||||
|
||||
import de.anura.core.util.Blocks;
|
||||
import de.anura.core.util.Util;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import net.minecraft.server.v1_14_R1.EntityArmorStand;
|
||||
import net.minecraft.server.v1_14_R1.PlayerConnection;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.type.Stairs;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
|
||||
public abstract class ChairManager {
|
||||
|
||||
private static final Map<Player, ArmorStand> SITTING_PLAYERS = new WeakHashMap<>();
|
||||
private static final Map<Player, Block> SITTING_BLOCKS = new WeakHashMap<>();
|
||||
private static Field f;
|
||||
|
||||
static {
|
||||
try {
|
||||
f = PlayerConnection.class.getDeclaredField("B");
|
||||
f.setAccessible(true);
|
||||
} catch (NoSuchFieldException | SecurityException ex) {
|
||||
Logger.getLogger(ChairManager.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void playerSitDown(Player p, Stairs s, Block b) {
|
||||
Objects.requireNonNull(p);
|
||||
Objects.requireNonNull(s);
|
||||
Objects.requireNonNull(b);
|
||||
//Anti Fly-Kick
|
||||
try {
|
||||
f.set(((CraftPlayer) p).getHandle().playerConnection, false);
|
||||
} catch (SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
Logger.getLogger(ChairManager.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
//ArmorStand creation
|
||||
Location loc = b.getLocation().add(0.5, 0.25, 0.5);
|
||||
loc.setYaw(Blocks.faceToYaw(s.getFacing()));
|
||||
World w = loc.getWorld();
|
||||
if (w != null) {
|
||||
CraftWorld cw = (CraftWorld) w;
|
||||
EntityArmorStand nms_as = new EntityArmorStand(cw.getHandle(), loc.getX(), loc.getY(), loc.getZ());
|
||||
nms_as.setInvisible(true);
|
||||
nms_as.setMarker(true);
|
||||
ArmorStand as = (ArmorStand) cw.addEntity(nms_as, SpawnReason.CUSTOM);
|
||||
as.setGravity(false);
|
||||
AttributeInstance maxHealth = as.getAttribute(Attribute.GENERIC_MAX_HEALTH);
|
||||
if (maxHealth != null) {
|
||||
maxHealth.setBaseValue(0);
|
||||
}
|
||||
as.teleport(loc);
|
||||
as.addPassenger(p);
|
||||
SITTING_PLAYERS.put(p, as);
|
||||
SITTING_BLOCKS.put(p, b);
|
||||
}
|
||||
}
|
||||
|
||||
public static void playerStandUp(Player p) {
|
||||
Objects.requireNonNull(p);
|
||||
ArmorStand as = SITTING_PLAYERS.remove(p);
|
||||
as.removePassenger(p);
|
||||
as.remove();
|
||||
SITTING_BLOCKS.remove(p);
|
||||
}
|
||||
|
||||
public static void playerStandUp(Block b) {
|
||||
Objects.requireNonNull(b);
|
||||
playerStandUp(Util.getKeyByValue(SITTING_BLOCKS, b));
|
||||
}
|
||||
|
||||
public static boolean isSittingAnyone(Block b) {
|
||||
Objects.requireNonNull(b);
|
||||
return SITTING_BLOCKS.containsValue(b);
|
||||
}
|
||||
|
||||
public static boolean isSittingPlayer(Block b, Player p) {
|
||||
Objects.requireNonNull(p);
|
||||
Objects.requireNonNull(b);
|
||||
return SITTING_BLOCKS.containsValue(b) && Util.getKeyByValue(SITTING_BLOCKS, b).equals(p);
|
||||
}
|
||||
|
||||
public static boolean isSitting(Player p) {
|
||||
Objects.requireNonNull(p);
|
||||
return SITTING_PLAYERS.containsKey(p);
|
||||
}
|
||||
|
||||
public static void destoryAll() {
|
||||
new HashSet<>(SITTING_PLAYERS.keySet()).stream().forEach(ChairManager::playerStandUp);
|
||||
}
|
||||
}
|
||||
91
src/de/anura/realisticminecraft/util/LogBlockProvider.java
Normal file
91
src/de/anura/realisticminecraft/util/LogBlockProvider.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package de.anura.realisticminecraft.util;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import de.anura.core.AnuraThread;
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.util.BukkitUtils;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import de.anura.realisticminecraft.RealisticMinecraft;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class LogBlockProvider {
|
||||
|
||||
private static final LogBlock plugin = (LogBlock) Bukkit.getServer().getPluginManager().getPlugin("LogBlock");
|
||||
private static final Cache<Location, Object> cache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(15, TimeUnit.SECONDS).build();
|
||||
private static final Queue<Runnable> queue = new ConcurrentLinkedQueue<>();
|
||||
private static final Object value = new Object();
|
||||
private static boolean queueStarted = false;
|
||||
|
||||
private static Actor getActor(Player p) {
|
||||
return new Actor(p.getName(), p.getUniqueId());
|
||||
}
|
||||
|
||||
public static void queueFalling(Player p, Location l, BlockData bd) {
|
||||
startQueue();
|
||||
Actor a = getActor(p);
|
||||
queue.add(() -> queueFallingBlock(a, l, bd));
|
||||
}
|
||||
|
||||
private static void queueFallingBlock(Actor a, Location l, BlockData bd) {
|
||||
Location loc = l;
|
||||
int x = loc.getBlockX();
|
||||
int y = loc.getBlockY();
|
||||
int z = loc.getBlockZ();
|
||||
// Blocks only fall if they have a chance to start a velocity
|
||||
if (l.getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR) {
|
||||
while (y > 0 && canFall(loc.getWorld(), x, (y - 1), z)) {
|
||||
y--;
|
||||
}
|
||||
}
|
||||
// If y is 0 then the sand block fell out of the world :(
|
||||
if (y != 0) {
|
||||
Location finalLoc = new Location(loc.getWorld(), x, y, z);
|
||||
Block finalBlock = finalLoc.getBlock();
|
||||
// Run this check to avoid false positives
|
||||
if (!BukkitUtils.getFallingEntityKillers().contains(finalBlock.getType())) {
|
||||
cache.put(finalLoc, value);
|
||||
if (finalBlock.getType() == Material.AIR || finalLoc.equals(l)) {
|
||||
plugin.getConsumer().queueBlockPlace(a, finalLoc, bd);
|
||||
} else {
|
||||
plugin.getConsumer().queueBlockReplace(a, finalLoc, finalBlock.getBlockData(), bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void queueBlockBreak(Player p, Block b) {
|
||||
plugin.getConsumer().queueBlockBreak(getActor(p), b.getState());
|
||||
}
|
||||
|
||||
public static boolean canFall(World w, int x, int y, int z) {
|
||||
return BukkitUtils.canFallIn(w, x, (y - 1), z) && cache.getIfPresent(new Location(w, x, y, z)) == null;
|
||||
}
|
||||
|
||||
public static void startQueue() {
|
||||
if (queueStarted) {
|
||||
return;
|
||||
}
|
||||
queueStarted = true;
|
||||
AnuraThread.add(Bukkit.getScheduler().runTaskTimerAsynchronously(RealisticMinecraft.getInstance(), () -> {
|
||||
for (int i = 0; i < 200; i++) {
|
||||
Runnable poll = queue.poll();
|
||||
if (poll == null) {
|
||||
continue;
|
||||
}
|
||||
poll.run();//TODO: Check SYNC
|
||||
}
|
||||
}, 10, 10));
|
||||
}
|
||||
}
|
||||
15
src/plugin.yml
Normal file
15
src/plugin.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
# Maven Generated Properties
|
||||
name: RealisticMinecraft
|
||||
version: 0.1
|
||||
author: hibo98
|
||||
# Custom Properties
|
||||
main: de.anura.realisticminecraft.RealisticMinecraft
|
||||
depend: [Core]
|
||||
api-version: 1.14
|
||||
commands:
|
||||
infobar:
|
||||
description: Konfigurieret die Infobars
|
||||
usage: §c/infobar <durst|temp(eratur)> <an|standard>
|
||||
infobarset:
|
||||
description: Setzt Werte für die Infobar
|
||||
usage: §c/infobarset <durst|temp(eratur)> <value>
|
||||
Reference in New Issue
Block a user