diff --git a/CHANGELOG/kelp-v0.4.0.md b/CHANGELOG/kelp-v0.4.0.md
new file mode 100644
index 00000000..fa8ab9f1
--- /dev/null
+++ b/CHANGELOG/kelp-v0.4.0.md
@@ -0,0 +1,25 @@
+# v0.4.0
+> Release date: 24.05.2021
+
+**The entity update**:
+
+* Make methods of `StringUtils` and `ReflectionUtil` static.
+* You can now invoke methods using `ReflectionUtils.invokeMethod(Object, String, Object...)` and `ReflectionUtils.invokeStaticMethod(Class>, String name, Object... parameters)`
+* Move `isInWater` and `isInCobweb` method from `KelpPlayer` to `KelpEntity` as this is a more general method that can be applied to all entities.
+* `KelpPlayer` is now an interface instead of a class for better integration into the entity system
+ * Although it has ever been a sub-type of `LivingKelpEntity`, it was not handled as such. The `EntityTypeVersionTemplate` could not convert it. Now it is exactly handled as an entity with the only logical exceptions that you cannot create/spawn new ones (use `KelpNpc`), and you cannot remove players from the server (kick them instead).
+* Complete rework of the entity library:
+ * Old entity classes and methods are not supported anymore. They have been removed from the code.
+ * Entities are now represented as interfaces in the core module instead of classes.
+ * Those interfaces are implemented by the version modules - similar to bukkit. All entity types for MC1.8 have been implemented
+ * Add new entity types to `KelpEntityType` enum that have been added in 1.15 and 1.16.
+* With the entity rework, other features that entities depend on had to be implemented as well:
+ * Add potion API allowing you to add potion effects
+ * Add `@MinecraftPotion` annotation, and a class for each potion effect type. The Kelp-Binder can now check for custom implementations of a potion effect type: If you run a 1.8 server, but want to use the levitation effect, this is no problem because the levitation effect can be reproduced by Kelp (just as you would create a version template and implementation). However, no effect has been emulated yet - only the mechanics exist and have been tested.
+ * Add entity constants for all entities that exist in 1.8. You can now convert horse types, villager professions, etc. across different versions
+ * Add `StorageInventory` interface, which represents a general inventory just like bukkit's `Inventory` interface.
+ * Add `HorseInventory` and `AbstractHorseInventory` allowing you to easily access a horse's saddle or armor.
+ * `PlayerInventory` now also is a subtype of `StorageInventory` and has been converted to an interface as well.
+* Add 1.16-1.16.5 versions to `KelpVersion` enum
+* Add `getEntities()` method to `KelpWorld` returning a list of all entities in the given world.
+* Fix bug that entities could not be damaged by left click interaction when Kelp was installed. This was due to a bug that when an interaction packet was intercepted, it was not passed on to the server afterwards.
diff --git a/core/pom.xml b/core/pom.xml
index baa4a4af..a2d96ad2 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -5,7 +5,7 @@
com.github.pxav.kelp
parent
- 0.3.4
+ 0.4.0
4.0.0
@@ -141,6 +141,17 @@
+
+
+
+ .
+ true
+ ${basedir}/src/main/resources/
+
+ *
+
+
+
diff --git a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java
index 28ddf818..614d83f7 100644
--- a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java
+++ b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java
@@ -36,9 +36,6 @@
*
* @author pxav
*/
-@Plugin(name = "Kelp", version = "0.3.3")
-@Author("pxav")
-@Description("A cross version spigot framework.")
@Singleton
public class KelpPlugin extends JavaPlugin {
diff --git a/core/src/main/java/de/pxav/kelp/core/application/inject/VersionBinderModule.java b/core/src/main/java/de/pxav/kelp/core/application/inject/VersionBinderModule.java
index 366701eb..9aafa68f 100644
--- a/core/src/main/java/de/pxav/kelp/core/application/inject/VersionBinderModule.java
+++ b/core/src/main/java/de/pxav/kelp/core/application/inject/VersionBinderModule.java
@@ -1,12 +1,15 @@
package de.pxav.kelp.core.application.inject;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
import com.google.inject.AbstractModule;
import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.application.KelpApplication;
import de.pxav.kelp.core.application.KelpApplicationRepository;
import de.pxav.kelp.core.application.KelpVersionTemplate;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
import de.pxav.kelp.core.version.KelpVersion;
import de.pxav.kelp.core.version.VersionImplementation;
import de.pxav.kelp.core.version.Versioned;
@@ -14,6 +17,7 @@
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.annotation.*;
+import org.bukkit.Bukkit;
import java.io.DataInputStream;
import java.io.File;
@@ -125,7 +129,9 @@ protected void configure() {
* @see KelpVersionTemplate
*/
private Collection detectVersionTemplates(String... packages) {
+ KelpVersion serverVersion = KelpVersion.withBukkitVersion(Bukkit.getBukkitVersion());
Collection output = Lists.newArrayList();
+
try (ScanResult scanResult =
new ClassGraph()
.enableAnnotationInfo()
@@ -140,6 +146,27 @@ private Collection detectVersionTemplates(String... packages) {
if (annotationInfo.getName().equalsIgnoreCase(KelpVersionTemplate.class.getName())) {
output.add(current.loadClass());
}
+
+ // next to normal version templates, search for potion templates that - unlike general
+ // version templates - don't have to be implemented in every server version. On an 1.8
+ // server, the Levitation effect has to be implemented, while on an 1.14 server not.
+ if (annotationInfo.getName().equalsIgnoreCase(MinecraftPotion.class.getName())) {
+
+ // the annotation only has a single parameter: The version since when it existed.
+ for (AnnotationParameterValue parameter : annotationInfo.getParameterValues()) {
+ // fetch the version since when the potion exists in the game
+ AnnotationEnumValue enumValue = (AnnotationEnumValue) parameter.getValue();
+ KelpVersion potionVersion = KelpVersion.valueOf(enumValue.getValueName());
+
+ // check if the current server version is lower than the version since when the
+ // potion existed, because in that case it has to be implemented and therefore
+ // be added to the template list.
+ if (potionVersion.isHigherThan(serverVersion)) {
+ output.add(current.loadClass());
+ }
+ }
+ }
+
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/command/KelpConsoleSender.java b/core/src/main/java/de/pxav/kelp/core/command/KelpConsoleSender.java
index eb090624..9f5562bc 100644
--- a/core/src/main/java/de/pxav/kelp/core/command/KelpConsoleSender.java
+++ b/core/src/main/java/de/pxav/kelp/core/command/KelpConsoleSender.java
@@ -2,7 +2,6 @@
import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.command.version.KelpConsoleSenderVersionTemplate;
-import de.pxav.kelp.core.player.KelpPlayer;
import org.bukkit.command.CommandSender;
/**
diff --git a/core/src/main/java/de/pxav/kelp/core/common/MathUtils.java b/core/src/main/java/de/pxav/kelp/core/common/MathUtils.java
index 64b03a37..f1399871 100644
--- a/core/src/main/java/de/pxav/kelp/core/common/MathUtils.java
+++ b/core/src/main/java/de/pxav/kelp/core/common/MathUtils.java
@@ -10,7 +10,7 @@
*/
public class MathUtils {
- private static final int[] values = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
+ private static final int[] values = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
private static final String[] romanLiterals = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
/**
@@ -37,23 +37,27 @@ public static boolean isOdd(int number) {
/**
* Randomly calculates whether a certain chance has been
- * fulfilled. If your {@code chance} is set to {@code 50},
+ * fulfilled. If your {@code chance} is set to {@code 0.5},
* there will be a 50% chance that this method will return
- * {@code true}. If it is {@code 5}, then there will be a
+ * {@code true}. If it is {@code 0.05}, then there will be a
* {@code 5} per cent chance that this method will return
* {@code true}.
*
* @param chance The chance to use for random calculation.
+ * This number may range from 0.0 (always false, 0% change)
+ * and 1.0 (always true, 100% chance), where 0.01 is equal to
+ * 1%.
* @return Either true or false depending on your luck and the provided chance.
*/
- public static boolean perCentChance(int chance) {
- if (chance == 100) {
+ public static boolean perCentChance(double chance) {
+ if (chance >= 1.0d) {
return true;
}
- if (chance == 0) {
+ if (chance <= 0.0d) {
return false;
}
- return ThreadLocalRandom.current().nextInt(0, 101) < chance;
+
+ return Math.random() < chance;
}
public static String getRomanNumber(int number) {
diff --git a/core/src/main/java/de/pxav/kelp/core/common/StringUtils.java b/core/src/main/java/de/pxav/kelp/core/common/StringUtils.java
index 1949a8f3..0071ecbb 100644
--- a/core/src/main/java/de/pxav/kelp/core/common/StringUtils.java
+++ b/core/src/main/java/de/pxav/kelp/core/common/StringUtils.java
@@ -14,17 +14,16 @@
*
* @author pxav
*/
-@Singleton
public class StringUtils {
// an array containing all color codes in alphabetical order.
- private char[] colorCodes = new char[] {
+ private static char[] colorCodes = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'
};
// an array containing all style codes in alphabetical order.
- private char[] styleCodes = new char[] {
+ private static char[] styleCodes = new char[] {
'k', 'l', 'm', 'n', 'o', 'r'
};
@@ -34,7 +33,7 @@ public class StringUtils {
* @param text The text you want to remove the char of.
* @return The given text without the last char.
*/
- public String removeLastChar(String text) {
+ public static String removeLastChar(String text) {
// build a substring excluding the last char.
return text.substring(0, text.length() - 1);
}
@@ -47,7 +46,7 @@ public String removeLastChar(String text) {
* @param text The text you want to remove the color codes of.
* @return The final string without color codes.
*/
- public String removeFormattingCodes(String text) {
+ public static String removeFormattingCodes(String text) {
List codes = extractFormattingCodes(text);
for (String current : codes) {
text = text.replace(current, "");
@@ -62,10 +61,10 @@ public String removeFormattingCodes(String text) {
* @param text The text you want to get the color codes of.
* @return The color codes in chronological order.
*/
- public List extractColorCodes(String text) {
+ public static List extractColorCodes(String text) {
List output = Lists.newArrayList();
for (int i = 0; i < text.length(); i++) {
- if (text.charAt(i) == '§' && this.isColorCode(text.charAt(i + 1))) {
+ if (text.charAt(i) == '§' && isColorCode(text.charAt(i + 1))) {
output.add("§" + text.charAt(i + 1));
}
}
@@ -79,10 +78,10 @@ public List extractColorCodes(String text) {
* @param text The text you want to get the style codes of.
* @return The style codes in chronological order.
*/
- public List extractStyleCodes(String text) {
+ public static List extractStyleCodes(String text) {
List output = Lists.newArrayList();
for (int i = 0; i < text.length(); i++) {
- if (text.charAt(i) == '§' && this.isStyleCode(text.charAt(i + 1))) {
+ if (text.charAt(i) == '§' && isStyleCode(text.charAt(i + 1))) {
output.add("§" + text.charAt(i + 1));
}
}
@@ -96,7 +95,7 @@ public List extractStyleCodes(String text) {
* @param text The text you want to get the codes of.
* @return The formatting codes in chronological order.
*/
- public List extractFormattingCodes(String text) {
+ public static List extractFormattingCodes(String text) {
List output = Lists.newArrayList();
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) != '§') {
@@ -107,8 +106,8 @@ public List extractFormattingCodes(String text) {
break;
}
- if (this.isStyleCode(text.charAt(i + 1))
- || this.isColorCode(text.charAt(i + 1))) {
+ if (isStyleCode(text.charAt(i + 1))
+ || isColorCode(text.charAt(i + 1))) {
output.add("§" + text.charAt(i + 1));
}
}
@@ -136,7 +135,7 @@ public List extractFormattingCodes(String text) {
* @param text The text you want to check.
* @return The last color and style codes.
*/
- public String lastFormattingCodesOf(String text) {
+ public static String lastFormattingCodesOf(String text) {
// get all formatting codes of the text and reverse their order.
List reversed = extractFormattingCodes(text);
Collections.reverse(reversed);
@@ -193,13 +192,13 @@ public String lastFormattingCodesOf(String text) {
* @param text The text you want to check.
* @return The last color and style codes.
*/
- public String lastFullFormattingCodesOf(String text) {
+ public static String lastFullFormattingCodesOf(String text) {
// check if the color codes have a single '§' at the end.
// this has to be removed as we only want to have full
// color codes.
- if (this.lastFormattingCodesOf(text).endsWith("§")) {
- String colorCodes = this.lastFormattingCodesOf(text);
- return this.removeLastChar(colorCodes);
+ if (lastFormattingCodesOf(text).endsWith("§")) {
+ String colorCodes = lastFormattingCodesOf(text);
+ return removeLastChar(colorCodes);
}
return lastFormattingCodesOf(text);
}
@@ -215,7 +214,7 @@ public String lastFullFormattingCodesOf(String text) {
* e. g. '1' for dark blue
* @return {@code true} if the given indicator is
*/
- public boolean isColorCode(char indicator) {
+ public static boolean isColorCode(char indicator) {
for (char current : colorCodes) {
if (current == indicator) {
return true;
@@ -234,7 +233,7 @@ public boolean isColorCode(char indicator) {
* e. g. 'l' for bold
* @return {@code true} if the given indicator is a style code.
*/
- public boolean isStyleCode(char indicator) {
+ public static boolean isStyleCode(char indicator) {
for (char current : styleCodes) {
if (current == indicator) {
return true;
@@ -252,7 +251,7 @@ public boolean isStyleCode(char indicator) {
* @param formattingCode The formatting code to be converted.
* @return The corresponding md_5 chat color.
*/
- public ChatColor getChatColor(char formattingCode) {
+ public static ChatColor getChatColor(char formattingCode) {
return isFormattingCode(formattingCode)
? ChatColor.getByChar(formattingCode)
: ChatColor.WHITE;
@@ -267,7 +266,7 @@ public ChatColor getChatColor(char formattingCode) {
* @param formattingCode The formatting code to be converted.
* @return The corresponding bukkit chat color.
*/
- public org.bukkit.ChatColor getBukkitChatColor(char formattingCode) {
+ public static org.bukkit.ChatColor getBukkitChatColor(char formattingCode) {
return isFormattingCode(formattingCode)
? org.bukkit.ChatColor.getByChar(formattingCode)
: org.bukkit.ChatColor.WHITE;
@@ -283,7 +282,7 @@ public org.bukkit.ChatColor getBukkitChatColor(char formattingCode) {
* @return The final {@link ChatColor} to be returned. {@code null} if the
* color was not found.
*/
- public ChatColor getChatColor(String formattingCode) {
+ public static ChatColor getChatColor(String formattingCode) {
char code = formattingCode.charAt(1);
return isFormattingCode(code) && formattingCode.charAt(0) == '§'
? ChatColor.getByChar(code)
@@ -299,7 +298,7 @@ public ChatColor getChatColor(String formattingCode) {
* @param formattingCode The formatting code to be converted.
* @return The final {@link org.bukkit.ChatColor} to be returned.
*/
- public org.bukkit.ChatColor getBukkitChatColor(String formattingCode) {
+ public static org.bukkit.ChatColor getBukkitChatColor(String formattingCode) {
char code = formattingCode.charAt(1);
return isFormattingCode(code) && formattingCode.charAt(0) == '§'
? org.bukkit.ChatColor.getByChar(code)
@@ -314,7 +313,7 @@ public org.bukkit.ChatColor getBukkitChatColor(String formattingCode) {
* @return The last color code of the text. {@code null} if there
* was no color code to be detected.
*/
- public String endsWithColorCode(String text) {
+ public static String endsWithColorCode(String text) {
if (text.length() < 2) {
return null;
}
@@ -335,7 +334,7 @@ public String endsWithColorCode(String text) {
* @return The last formatting code of the text. {@code null} if there
* was no color code to be detected.
*/
- public String endsWithFormattingCode(String text) {
+ public static String endsWithFormattingCode(String text) {
// if the text is less than 2 chars long there can
// be no formatting code, so return immediately.
if (text.length() < 2) {
@@ -356,7 +355,7 @@ public String endsWithFormattingCode(String text) {
*
* @return Any random bukkit color code.
*/
- public char randomColorCode() {
+ public static char randomColorCode() {
return colorCodes[ThreadLocalRandom.current().nextInt(colorCodes.length - 1)];
}
@@ -366,7 +365,7 @@ public char randomColorCode() {
*
* @return
*/
- public char randomStyleCode() {
+ public static char randomStyleCode() {
return styleCodes[ThreadLocalRandom.current().nextInt(colorCodes.length - 1)];
}
@@ -376,7 +375,7 @@ public char randomStyleCode() {
*
* @return Any random foramtting code without {@code '§'} in front.
*/
- public char randomFormattingCode() {
+ public static char randomFormattingCode() {
return ThreadLocalRandom.current().nextBoolean() ? randomColorCode() : randomStyleCode();
}
@@ -384,7 +383,7 @@ public char randomFormattingCode() {
* @param indicator The indicator of the code you want to check.
* @return {@code true} if the either a color code or a style code.
*/
- public boolean isFormattingCode(char indicator) {
+ public static boolean isFormattingCode(char indicator) {
return isColorCode(indicator) || isStyleCode(indicator);
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/KelpEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/KelpEntity.java
index 58ea851d..4fe7d09c 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/KelpEntity.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/KelpEntity.java
@@ -1,132 +1,57 @@
package de.pxav.kelp.core.entity;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
import de.pxav.kelp.core.world.KelpLocation;
import de.pxav.kelp.core.world.KelpWorld;
-import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.entity.Entity;
-import org.bukkit.event.player.PlayerTeleportEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.util.Vector;
import java.util.List;
import java.util.UUID;
-/**
- * A class description goes here.
- *
- * @author pxav
- */
-public class KelpEntity {
-
- private Object minecraftEntity;
- private KelpEntityType entityType;
- private Location initialLocation;
- private int entityId;
- private EntityVersionTemplate entityVersionTemplate;
-
- public KelpEntity(Object minecraftEntity,
- KelpEntityType entityType,
- Location initialLocation,
- int entityId,
- EntityVersionTemplate entityVersionTemplate) {
- this.minecraftEntity = minecraftEntity;
- this.entityType = entityType;
- this.initialLocation = initialLocation;
- this.entityId = entityId;
- this.entityVersionTemplate = entityVersionTemplate;
- }
-
- public KelpEntity(EntityVersionTemplate entityVersionTemplate) {
- this.entityVersionTemplate = entityVersionTemplate;
- }
-
- public KelpEntity() {}
-
- public Object getMinecraftEntity() {
- return minecraftEntity;
- }
-
- public KelpEntity minecraftEntity(Object minecraftEntity) {
- this.minecraftEntity = minecraftEntity;
- return this;
- }
-
- public KelpEntityType getEntityType() {
- return entityType;
- }
-
- public KelpEntity entityType(KelpEntityType entityType) {
- this.entityType = entityType;
- return this;
- }
-
- public Location getInitialBukkitLocation() {
- return initialLocation;
- }
-
- public KelpLocation getInitialLocation() {
- return KelpLocation.from(initialLocation);
- }
-
- public KelpEntity initialLocation(KelpLocation currentLocation) {
- this.initialLocation = currentLocation.getBukkitLocation();
- return this;
- }
-
- public KelpEntity initialLocation(Location location) {
- this.initialLocation = location;
- return this;
- }
-
- public int getEntityId() {
- return entityId;
- }
-
- public KelpEntity entityId(int entityId) {
- this.entityId = entityId;
- return this;
- }
+public interface KelpEntity> {
- public KelpEntity versionTemplate(EntityVersionTemplate entityVersionTemplate) {
- this.entityVersionTemplate = entityVersionTemplate;
- return this;
+ static KelpEntity> create(KelpEntityType entityType, KelpLocation location) {
+ return KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).newKelpEntity(entityType, location.getBukkitLocation());
}
- public KelpEntity spawn() {
- entityVersionTemplate.spawnEntity(this);
- return this;
+ static KelpEntity> from(Entity bukkitEntity) {
+ return KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).getKelpEntity(bukkitEntity);
}
/**
- * Converts the current {@code KelpEntity} to a normal
- * bukkit entity.
+ * Gets the unique id of this entity in its world.
*
- * @return The bukkit entity of the current KelpEntity.
+ * Every entity is assigned an id when spawned to a world,
+ * which can be used to identify this entity when sending packets
+ * for example.
+ *
+ * Entity ids are incremental in a range
+ * from 0 to 2000, which usually is the maximum id used
+ * by bukkit.
+ *
+ * @return The id of this entity.
*/
- public Entity toBukkitEntity() {
- return entityVersionTemplate.toBukkitEntity(this.minecraftEntity);
- }
+ int getEntityId();
/**
- * Gets the current entity's location in the world.
+ * Spawns the entity to the given initial location and makes it visible
+ * for all players on the world.
*
- * @return The current location of the current entity.
+ * @return An instance of the entity for fluent builder design.
*/
- public KelpLocation getLocation() {
- return entityVersionTemplate.getLocation(toBukkitEntity());
- }
+ T spawn();
/**
* Sets the entity's velocity to the given vector.
*
- * @param vector The vector of the velocity you want to set.
+ * @param velocity The vector of the velocity you want to set.
* @see Vector
*/
- public KelpEntity setVelocity(Vector vector) {
- entityVersionTemplate.setVelocity(toBukkitEntity(), vector);
- return this;
- }
+ T setVelocity(Vector velocity);
/**
* Gets the velocity of the desired entity.
@@ -134,131 +59,109 @@ public KelpEntity setVelocity(Vector vector) {
* @return The velocity of the given entity.
* @see Vector
*/
- public Vector getVelocity() {
- return entityVersionTemplate.getVelocity(toBukkitEntity());
- }
+ Vector getVelocity();
/**
- * Gets the height of an entity. In older versions
+ * Gets the height of an entity's model. In older versions
* this property was called 'length' of an entity.
*
* @return The height of the given entity.
*/
- public double getEntityHeight() {
- return entityVersionTemplate.getHeight(toBukkitEntity());
- }
+ double getEntityHeight();
/**
- * Gets the width of the given entity.
+ * Gets the width of the given entity's model.
*
* @return The entity's width.
*/
- public double getEntityWidth() {
- return entityVersionTemplate.getWidth(toBukkitEntity());
- }
+ double getEntityWidth();
/**
- * Checks if the entity is currently on the ground.
+ * Gets the exact {@link KelpEntityType type} of this entity such as ZOMBIE, SHEEP, CREEPER, etc.
*
- * @return {@code true} if the entity is currently on ground.
+ * @return The type of this entity.
*/
- public boolean isOnGround() {
- return entityVersionTemplate.isOnGround(toBukkitEntity());
- }
+ KelpEntityType getType();
/**
- * Gets the current world of the entity.
+ * Gets the current entity's location in the world.
*
- * @return The world where the entity is currently located.
+ * @return The current location of the current entity.
*/
- public KelpWorld getWorld() {
- return KelpWorld.from(getLocation().getWorldName());
- }
+ KelpLocation getLocation();
+
+ boolean isInWater();
+
+ boolean isInCobweb();
/**
- * Sets the rotation of the given entity. This does not
- * affect the location x, y and z axes.
+ * Converts the current {@code KelpEntity} to a normal
+ * bukkit entity.
*
- * @param yaw The yaw value of the desired rotation.
- * @param pitch The pitch value of the desired rotation.
+ * @return The bukkit entity of the current KelpEntity.
*/
- public KelpEntity setRotation(float yaw, float pitch) {
- entityVersionTemplate.setRotation(toBukkitEntity(), yaw, pitch);
- return this;
- }
+ Entity getBukkitEntity();
/**
- * Teleports the entity to the given location.
+ * Checks if the entity is currently on the ground.
*
- * @param to The location you want the entity to be teleported to.
+ * @return {@code true} if the entity is currently on ground.
*/
- public KelpEntity teleport(KelpLocation to) {
- entityVersionTemplate.teleport(toBukkitEntity(), to, PlayerTeleportEvent.TeleportCause.PLUGIN);
- return this;
- }
+ boolean isOnGround();
/**
- * Teleports the entity to the location at the given
- * coordinates. As there is no world passed, this method
- * will use the current world of the entity.
+ * Teleports the entity to the ground level of the
+ * current coordinates. This is useful when the entity
+ * is suspected to be stuck in an underground block.
*
- * @param x The exact value of the location's x axis.
- * @param y The exact value of the location's y axis.
- * @param z The exact value of the location's z axis.
+ * This method will then search for the highest non-passable block
+ * at the entities x and z coordinates and teleport it there.
+ *
+ * @return An instance of the current entity for fluent builder design.
*/
- public KelpEntity teleport(double x, double y, double z) {
- KelpLocation to = KelpLocation.from(getWorld(), x, y, z);
- teleport(to);
- return this;
- }
+ T setOnGround(boolean onGround);
/**
- * Teleports the entity to the location at the given
- * coordinates. As there is no world passed, this method
- * will use the current world of the entity.
+ * Gets the current world of the entity.
*
- * @param x The exact value of the location's x axis.
- * @param y The exact value of the location's y axis.
- * @param z The exact value of the location's z axis.
- * @param yaw The yaw rotation of the entity.
- * @param pitch The location's pitch
+ * @return The world where the entity is currently located.
*/
- public KelpEntity teleport(double x, double y, double z, float yaw, float pitch) {
- KelpLocation to = KelpLocation.from(getWorld(), x, y, z, yaw, pitch);
- teleport(to);
- return this;
- }
+ KelpWorld getWorld();
/**
- * Teleports the entity to the location at the given
- * coordinates.
+ * Sets the rotation of the given entity. This does not
+ * affect the location x, y and z axes.
*
- * @param world The world where the entity should be teleported to.
- * @param x The exact value of the location's x axis.
- * @param y The exact value of the location's y axis.
- * @param z The exact value of the location's z axis.
- * @param yaw The yaw rotation of the entity.
- * @param pitch The location's pitch
+ * @param yaw The yaw value of the desired rotation.
+ * @param pitch The pitch value of the desired rotation.
+ * @return An instance of the current entity for fluent builder design.
*/
- public KelpEntity teleport(KelpWorld world, double x, double y, double z, float yaw, float pitch) {
- KelpLocation to = KelpLocation.from(world, x, y, z, yaw, pitch);
- teleport(to);
- return this;
- }
+ T setRotation(float yaw, float pitch);
/**
- * Teleports the entity to the location at the given
- * coordinates.
+ * Makes the entity look to the given location. So it
+ * rotates its head to the given target location.
*
- * @param world The world where the entity should be teleported to.
- * @param x The exact value of the location's x axis.
- * @param y The exact value of the location's y axis.
- * @param z The exact value of the location's z axis.
+ * @param target The location where the entity should look to.
+ * @return An instance of the current entity object for fluent builder design.
*/
- public KelpEntity teleport(KelpWorld world, double x, double y, double z) {
- KelpLocation to = KelpLocation.from(world, x, y, z);
- teleport(to);
- return this;
+ default T lookTo(KelpLocation target) {
+ KelpLocation location = getLocation();
+ double xDiff = target.getX() - location.getX();
+ double yDiff = target.getY() - location.getY();
+ double zDiff = target.getZ() - location.getZ();
+
+ double distanceXZ = Math.sqrt(xDiff * xDiff + zDiff * zDiff);
+ double distanceY = Math.sqrt(distanceXZ * distanceXZ + yDiff * yDiff);
+
+ double yaw = Math.toDegrees(Math.acos(xDiff / distanceXZ));
+ double pitch = Math.toDegrees(Math.acos(yDiff / distanceY)) - 90.0D;
+ if (zDiff < 0.0D) {
+ yaw += Math.abs(180.0D - yaw) * 2.0D;
+ }
+
+ setRotation((float) yaw - 90.0F, (float) pitch);
+ return (T) this;
}
/**
@@ -272,44 +175,46 @@ public KelpEntity teleport(KelpWorld world, double x, double y, double z) {
* @param yaw The yaw rotation of the entity.
* @param pitch The location's pitch
*/
- public KelpEntity teleport(String worldName, double x, double y, double z, float yaw, float pitch) {
- KelpLocation to = KelpLocation.from(worldName, x, y, z, yaw, pitch);
- teleport(to);
- return this;
+ T teleport(String worldName, double x, double y, double z, float yaw, float pitch);
+
+ /**
+ * Teleports the entity to the given location.
+ *
+ * @param to The location you want the entity to be teleported to.
+ */
+ default T teleport(KelpLocation to) {
+ teleport(to.getWorldName(), to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
+ return (T) this;
}
/**
* Teleports the entity to the location at the given
- * coordinates.
+ * coordinates. As there is no world passed, this method
+ * will use the current world of the entity.
*
- * @param worldName The name of the world where the entity should be teleported to.
- * @param x The exact value of the location's x axis.
- * @param y The exact value of the location's y axis.
- * @param z The exact value of the location's z axis.
+ * @param x The exact value of the location's x axis.
+ * @param y The exact value of the location's y axis.
+ * @param z The exact value of the location's z axis.
*/
- public KelpEntity teleport(String worldName, double x, double y, double z) {
- KelpLocation to = KelpLocation.from(worldName, x, y, z);
- teleport(to);
- return this;
+ default T teleport(double x, double y, double z) {
+ teleport(getWorld().getName(), x, y, z, 0, 0);
+ return (T) this;
}
/**
- * Gets the id of the given entity.
- *
- * The entity id is a unique integer id, which is given
- * to each entity when it is created by the server. It is
- * used to identify entities during the server runtime.
- *
- * In contrast to the other {@code #getEntityId} method,
- * this method uses the method provided by bukkit and not
- * the Kelp-internal id. However, in most server versions these
- * ids should be the same as an entity id is immutable
- * for the same entity.
+ * Teleports the entity to the location at the given
+ * coordinates. As there is no world passed, this method
+ * will use the current world of the entity.
*
- * @return the entity's id provided by bukkit.
+ * @param x The exact value of the location's x axis.
+ * @param y The exact value of the location's y axis.
+ * @param z The exact value of the location's z axis.
+ * @param yaw The yaw rotation of the entity.
+ * @param pitch The location's pitch
*/
- public int getEntityIdBukkit() {
- return entityVersionTemplate.getEntityId(toBukkitEntity());
+ default T teleport(double x, double y, double z, float yaw, float pitch) {
+ teleport(getWorld().getName(), x, y, z, yaw, pitch);
+ return (T) this;
}
/**
@@ -323,9 +228,7 @@ public int getEntityIdBukkit() {
*
* @return The amount of fire ticks.
*/
- public int getFireTicks() {
- return entityVersionTemplate.getFireTicks(toBukkitEntity());
- }
+ int getFireTicks();
/**
* Sets the current amount of fire ticks for the given
@@ -338,46 +241,33 @@ public int getFireTicks() {
*
* @param fireTicks The amount of fire ticks you want to set.
*/
- public KelpEntity setFireTicks(int fireTicks) {
- entityVersionTemplate.setFireTicks(toBukkitEntity(), fireTicks);
- return this;
- }
+ T setFireTicks(int fireTicks);
/**
- * Gets the amount of the maximum fire ticks of the given entity.
+ * Sets the amount of the maximum fire ticks of the given entity.
*
- * @return The amount of maximum fire ticks of the given entity.
+ * @param maxFireTicks The amount of maximum fire ticks to set.
*/
- public int getMaxFireTicks() {
- return entityVersionTemplate.getMaxFireTicks(toBukkitEntity());
- }
+ T setMaxFireTicks(int maxFireTicks);
/**
- * Sets the amount of the maximum fire ticks of the given entity.
+ * Gets the amount of the maximum fire ticks of the given entity.
*
- * @param maxFireTicks The amount of maximum fire ticks to set.
+ * @return The amount of maximum fire ticks of the given entity.
*/
- public KelpEntity setMaxFireTicks(int maxFireTicks) {
- entityVersionTemplate.setFireTicks(toBukkitEntity(), maxFireTicks);
- return this;
- }
+ int getMaxFireTicks();
/**
* Removes the entity from the world.
*/
- public KelpEntity remove() {
- entityVersionTemplate.remove(toBukkitEntity());
- return this;
- }
+ T remove();
/**
* Checks if the given entity is dead.
*
* @return {@code true} if the entity is dead.
*/
- public boolean isDead() {
- return entityVersionTemplate.isDead(toBukkitEntity());
- }
+ boolean isDead();
/**
* Checks if the entity is valid.
@@ -387,18 +277,14 @@ public boolean isDead() {
*
* @return {@code true} if the entity is 'valid'.
*/
- public boolean isValid() {
- return entityVersionTemplate.isValid(toBukkitEntity());
- }
+ boolean isValid();
/**
* Gets the current server containing the entity.
*
* @return The server instance.
*/
- public Server getServer() {
- return entityVersionTemplate.getServer(toBukkitEntity());
- }
+ Server getServer();
/**
* Gets the passenger of the current entity.
@@ -414,13 +300,7 @@ public Server getServer() {
*
* @return The first or only passenger of the entity. {@code null} if there is no passenger.
*/
- public Entity getPassenger() {
- List passengers = entityVersionTemplate.getPassengers(toBukkitEntity());
- if (passengers != null && !passengers.isEmpty()) {
- return passengers.get(0);
- }
- return null;
- }
+ KelpEntity> getPassenger();
/**
* Returns a list of all passengers currently riding
@@ -434,9 +314,7 @@ public Entity getPassenger() {
* @return A list of all passengers of the given entity.
* {@code null} if there are no passengers.
*/
- public List getPassengers() {
- return entityVersionTemplate.getPassengers(toBukkitEntity());
- }
+ List> getPassengers();
/**
* Adds a new passenger to the given entity.
@@ -448,10 +326,7 @@ public List getPassengers() {
* @param passenger The passenger you want to add.
* @return {@code true} if the action was successful.
*/
- public KelpEntity addPassenger(Entity passenger) {
- entityVersionTemplate.addPassenger(toBukkitEntity(), passenger);
- return this;
- }
+ T addPassenger(KelpEntity> passenger);
/**
* Adds multiple passengers to the given entity.
@@ -463,20 +338,14 @@ public KelpEntity addPassenger(Entity passenger) {
* @param passengers The passengers you want to add.
* @return {@code true} if the action was successful.
*/
- public KelpEntity addPassenger(List passengers) {
- passengers.forEach(this::addPassenger);
- return this;
- }
+ T addPassenger(List> passengers);
/**
* Removes a passenger from the given entity.
*
- * @param toRemove The passenger you want to remove.
+ * @param passenger The passenger you want to remove.
*/
- public KelpEntity removePassenger(Entity toRemove) {
- entityVersionTemplate.removePassenger(toBukkitEntity(), toRemove);
- return this;
- }
+ T removePassenger(KelpEntity> passenger);
/**
* Checks if the current entity is empty. An empty
@@ -484,27 +353,22 @@ public KelpEntity removePassenger(Entity toRemove) {
*
* @return {@code true} if the entity is empty.
*/
- public boolean isEmpty() {
- return entityVersionTemplate.isEmpty(toBukkitEntity());
- }
+ boolean isEmpty();
/**
* Checks if the current entity has any passengers.
*
* @return {@code true} if there are any passengers.
*/
- public boolean hasAnyPassengers() {
- return !entityVersionTemplate.isEmpty(toBukkitEntity());
+ default boolean hasAnyPassengers() {
+ return !isEmpty();
}
/**
* Ejects any passenger currently riding on the
* given entity.
*/
- public KelpEntity ejectPassengers() {
- entityVersionTemplate.eject(toBukkitEntity());
- return this;
- }
+ T ejectPassengers();
/**
* Sets the current fall distance of the current entity.
@@ -516,10 +380,7 @@ public KelpEntity ejectPassengers() {
*
* @param fallDistance The new fall distance you want to set.
*/
- public KelpEntity setFallDistance(float fallDistance) {
- entityVersionTemplate.setFallDistance(toBukkitEntity(), fallDistance);
- return this;
- }
+ T setFallDistance(float fallDistance);
/**
* Gets the current fall distance of the current entity.
@@ -531,9 +392,7 @@ public KelpEntity setFallDistance(float fallDistance) {
*
* @return The current fall distance of the entity.
*/
- public float getFallDistance() {
- return entityVersionTemplate.getFallDistance(toBukkitEntity());
- }
+ float getFallDistance();
/**
* Returns a unique as well as persistent id for
@@ -542,9 +401,7 @@ public float getFallDistance() {
*
* @return The UUID of the given entity.
*/
- public UUID getUUID() {
- return entityVersionTemplate.getUniqueId(toBukkitEntity());
- }
+ UUID getUUID();
/**
* Gets the amount of ticks the entity has been alive.
@@ -552,9 +409,7 @@ public UUID getUUID() {
*
* @return The age of the entity.
*/
- public int getTicksLived() {
- return entityVersionTemplate.getTicksLived(toBukkitEntity());
- }
+ int getTicksLived();
/**
* Gets the amount of ticks the entity has been alive.
@@ -563,27 +418,19 @@ public int getTicksLived() {
* @param ticksLived The amount of ticks you want to set.
* May not be less than one tick.
*/
- public KelpEntity setTicksLived(int ticksLived) {
- entityVersionTemplate.setTicksLived(toBukkitEntity(), ticksLived);
- return this;
- }
+ T setTicksLived(int ticksLived);
/**
* Returns true if the entity is currently inside a vehicle.
*
* @return {@code true} if the entity is inside a vehicle.
*/
- public boolean isInsideVehicle() {
- return entityVersionTemplate.isInsideVehicle(toBukkitEntity());
- }
+ boolean isInsideVehicle();
/**
* Makes the entity leave its current vehicle.
*/
- public KelpEntity leaveVehicle() {
- entityVersionTemplate.leaveVehicle(toBukkitEntity());
- return this;
- }
+ T leaveVehicle();
/**
* Gets the current vehicle of the given entity.
@@ -591,8 +438,64 @@ public KelpEntity leaveVehicle() {
* @return The vehicle of the entity. If the entity
* has no vehicle, null will be returned.
*/
- public Entity getVehicle() {
- return entityVersionTemplate.getVehicle(toBukkitEntity());
+ KelpEntity> getVehicle();
+
+ boolean isGlowing();
+
+ T setGlowing(boolean glowing);
+
+ /**
+ * Sets the custom name of an entity visible or invisible
+ * for the clients.
+ *
+ * @param visible {@code true} if it should be visible
+ * {@code false} if it should not be visible.
+ */
+ T customNameVisible(boolean visible);
+
+ T customName(String customName);
+
+ /**
+ * Checks if the custom name of the given entity is
+ * currently visible.
+ *
+ * @return {@code true} if the custom name is visible.
+ */
+ boolean isCustomNameVisible();
+
+ /**
+ * Gets the last damage cause. If the entity has not been damaged
+ * so far, it will return null.
+ *
+ * @return The last damage event instance containing the last
+ * damage cause.
+ */
+ EntityDamageEvent getLastDamageCause();
+
+ /**
+ * Sets the last damage cause the entity has suffered.
+ *
+ * @param damageCause The instance of the last entity damage event containing
+ * the last damage cause.
+ */
+ void setLastDamageCause(EntityDamageEvent damageCause);
+
+ /**
+ * Gets all entities within the given radius centered around
+ * the given entity.
+ *
+ * @param radiusX the radius for the x axis
+ * (1/2 the size of the box along x axis)
+ * @param radiusY the radius for the y axis
+ * (1/2 the size of the box along y axis)
+ * @param radiusZ the radius for the z axis
+ * (1/2 the size of the box along z axis)
+ * @return A list of all nearby entities within the given radius.
+ */
+ List> getNearbyEntities(double radiusX, double radiusY, double radiusZ);
+
+ default List> getNearbyEntities(double radius) {
+ return getNearbyEntities(radius, radius, radius);
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/KelpEntityType.java b/core/src/main/java/de/pxav/kelp/core/entity/KelpEntityType.java
index b125499b..7fc12fff 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/KelpEntityType.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/KelpEntityType.java
@@ -1,13 +1,14 @@
package de.pxav.kelp.core.entity;
-import de.pxav.kelp.core.entity.type.DroppedItemEntity;
-import de.pxav.kelp.core.entity.type.ElderGuardianEntity;
-import de.pxav.kelp.core.entity.type.GuardianEntity;
-import de.pxav.kelp.core.entity.type.ZombieEntity;
+import de.pxav.kelp.core.entity.type.*;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.version.KelpVersion;
+import org.bukkit.entity.EntityType;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Set;
/**
* A class description goes here.
@@ -17,113 +18,207 @@
public enum KelpEntityType {
DROPPED_ITEM(KelpVersion.MC_1_8_0, DroppedItemEntity.class),
- EXPERIENCE_ORB(KelpVersion.MC_1_8_0, null),
- AREA_EFFECT_CLOUD(KelpVersion.MC_1_9_0, null),
- ELDER_GUARDIAN(KelpVersion.MC_1_8_0, ElderGuardianEntity.class),
- WITHER_SKELETON(KelpVersion.MC_1_8_0, null),
- STRAY(KelpVersion.MC_1_10_0, null),
- EGG(KelpVersion.MC_1_8_0, null),
- LEASH_HITCH(KelpVersion.MC_1_8_0, null),
- PAINTING(KelpVersion.MC_1_8_0, null),
- ARROW(KelpVersion.MC_1_8_0, null),
- SNOWBALL(KelpVersion.MC_1_8_0, null),
- FIREBALL(KelpVersion.MC_1_8_0, null),
- SMALL_FIREBALL(KelpVersion.MC_1_8_0, null),
- ENDER_PEARL(KelpVersion.MC_1_8_0, null),
- ENDER_SIGNAL(KelpVersion.MC_1_8_0, null),
- SPLASH_POTION(KelpVersion.MC_1_8_0, null),
- THROWN_EXP_BOTTLE(KelpVersion.MC_1_8_0, null),
- ITEM_FRAME(KelpVersion.MC_1_8_0, null),
- WITHER_SKULL(KelpVersion.MC_1_8_0, null),
- PRIMED_TNT(KelpVersion.MC_1_8_0, null),
- FALLING_BLOCK(KelpVersion.MC_1_8_0, null),
- FIREWORK(KelpVersion.MC_1_8_0, null),
- HUSK(KelpVersion.MC_1_10_0, null),
- SPECTRAL_ARROW(KelpVersion.MC_1_9_0, null),
- SHULKER_BULLET(KelpVersion.MC_1_9_0, null),
- DRAGON_FIREBALL(KelpVersion.MC_1_9_0, null),
- ZOMBIE_VILLAGER(KelpVersion.MC_1_8_0, null),
- SKELETON_HORSE(KelpVersion.MC_1_8_0, null),
- ZOMBIE_HORSE(KelpVersion.MC_1_8_0, null),
- ARMOR_STAND(KelpVersion.MC_1_8_0, null),
- DONKEY(KelpVersion.MC_1_8_0, null),
- MULE(KelpVersion.MC_1_8_0, null),
- EVOKER_FANGS(KelpVersion.MC_1_11_0, null),
- EVOKER(KelpVersion.MC_1_11_0, null),
- VEX(KelpVersion.MC_1_11_0, null),
- VINDICATOR(KelpVersion.MC_1_11_0, null),
- ILLUSIONER(KelpVersion.MC_1_12_0, null),
- MINECART_COMMAND(KelpVersion.MC_1_8_0, null),
- BOAT(KelpVersion.MC_1_8_0, null),
- MINECART(KelpVersion.MC_1_8_0, null),
- MINECART_CHEST(KelpVersion.MC_1_8_0, null),
- MINECART_FURNACE(KelpVersion.MC_1_8_0, null),
- MINECART_TNT(KelpVersion.MC_1_8_0, null),
- MINECART_HOPPER(KelpVersion.MC_1_8_0, null),
- MINECART_MOB_SPAWNER(KelpVersion.MC_1_8_0, null),
- CREEPER(KelpVersion.MC_1_8_0, null),
- SKELETON(KelpVersion.MC_1_8_0, null),
- SPIDER(KelpVersion.MC_1_8_0, null),
- GIANT(KelpVersion.MC_1_8_0, null),
- ZOMBIE(KelpVersion.MC_1_8_0, ZombieEntity.class),
- SLIME(KelpVersion.MC_1_8_0, null),
- GHAST(KelpVersion.MC_1_8_0, null),
- PIG_ZOMBIE(KelpVersion.MC_1_8_0, null),
- ENDERMAN(KelpVersion.MC_1_8_0, null),
- CAVE_SPIDER(KelpVersion.MC_1_8_0, null),
- SILVERFISH(KelpVersion.MC_1_8_0, null),
- BLAZE(KelpVersion.MC_1_8_0, null),
- MAGMA_CUBE(KelpVersion.MC_1_8_0, null),
- ENDER_DRAGON(KelpVersion.MC_1_8_0, null),
- WITHER(KelpVersion.MC_1_8_0, null),
- BAT(KelpVersion.MC_1_8_0, null),
- WITCH(KelpVersion.MC_1_8_0, null),
- ENDERMITE(KelpVersion.MC_1_8_0, null),
- GUARDIAN(KelpVersion.MC_1_8_0, GuardianEntity.class),
- SHULKER(KelpVersion.MC_1_9_0, null),
- PIG(KelpVersion.MC_1_8_0, null),
- SHEEP(KelpVersion.MC_1_8_0, null),
- COW(KelpVersion.MC_1_8_0, null),
- CHICKEN(KelpVersion.MC_1_8_0, null),
- SQUID(KelpVersion.MC_1_8_0, null),
- WOLF(KelpVersion.MC_1_8_0, null),
- MUSHROOM_COW(KelpVersion.MC_1_8_0, null),
- SNOWMAN(KelpVersion.MC_1_8_0, null),
- OCELOT(KelpVersion.MC_1_8_0, null),
- IRON_GOLEM(KelpVersion.MC_1_8_0, null),
- HORSE(KelpVersion.MC_1_8_0, null),
- RABBIT(KelpVersion.MC_1_8_0, null),
- POLAR_BEAR(KelpVersion.MC_1_10_0, null),
- LLAMA(KelpVersion.MC_1_11_0, null),
- LLAMA_SPIT(KelpVersion.MC_1_11_0, null),
- PARROT(KelpVersion.MC_1_12_0, null),
- VILLAGER(KelpVersion.MC_1_8_0, null),
- ENDER_CRYSTAL(KelpVersion.MC_1_8_0, null),
- TURTLE(KelpVersion.MC_1_13_0, null),
- PHANTOM(KelpVersion.MC_1_13_0, null),
- TRIDENT(KelpVersion.MC_1_13_0, null),
- COD(KelpVersion.MC_1_13_0, null),
- SALMON(KelpVersion.MC_1_13_0, null),
- PUFFERFISH(KelpVersion.MC_1_13_0, null),
- TROPICAL_FISH(KelpVersion.MC_1_13_0, null),
- DROWNED(KelpVersion.MC_1_13_0, null),
- DOLPHIN(KelpVersion.MC_1_13_0, null),
- CAT(KelpVersion.MC_1_8_0, null),
- PANDA(KelpVersion.MC_1_14_0, null),
- PILLAGER(KelpVersion.MC_1_14_0, null),
- RAVAGER(KelpVersion.MC_1_14_0, null),
- TRADER_LLAMA(KelpVersion.MC_1_14_0, null),
- WANDERING_TRADER(KelpVersion.MC_1_14_0, null),
- FOX(KelpVersion.MC_1_14_0, null),
- FISHING_HOOK(KelpVersion.MC_1_8_0, null),
- LIGHTNING(KelpVersion.MC_1_8_0, null),
- PLAYER(KelpVersion.MC_1_8_0, null),
+ EXPERIENCE_ORB(KelpVersion.MC_1_8_0, ExperienceOrbEntity.class),
+ AREA_EFFECT_CLOUD(KelpVersion.MC_1_9_0, AreaEffectCloudEntity.class),
+ ELDER_GUARDIAN(KelpVersion.MC_1_8_0, ElderGuardianEntity.class) {
+ public boolean isHostile() { return true; }
+ public boolean isAquatic() { return true; }
+ },
+ WITHER_SKELETON(KelpVersion.MC_1_8_0, WitherSkeletonEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isHostile() { return true; }
+ },
+ STRAY_SKELETON(KelpVersion.MC_1_10_0, StraySkeletonEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isHostile() { return true; }
+ },
+ CHICKEN_EGG(KelpVersion.MC_1_8_0, ThrownChickenEggEntity.class),
+ LEASH_HITCH(KelpVersion.MC_1_8_0, LeashHitchEntity.class),
+ PAINTING(KelpVersion.MC_1_8_0, PaintingEntity.class),
+ ARROW(KelpVersion.MC_1_8_0, ArrowEntity.class),
+ SNOWBALL(KelpVersion.MC_1_8_0, ThrownSnowballEntity.class),
+ FIREBALL(KelpVersion.MC_1_8_0, ThrownFireballEntity.class),
+ SMALL_FIREBALL(KelpVersion.MC_1_8_0, SmallFireballEntity.class),
+ ENDER_PEARL(KelpVersion.MC_1_8_0, ThrownEnderPearlEntity.class),
+ ENDER_SIGNAL(KelpVersion.MC_1_8_0, EnderSignalEntity.class),
+ SPLASH_POTION(KelpVersion.MC_1_8_0, ThrownPotionEntity.class),
+ THROWN_EXP_BOTTLE(KelpVersion.MC_1_8_0, ThrownExperienceBottleEntity.class),
+ ITEM_FRAME(KelpVersion.MC_1_8_0, ItemFrameEntity.class),
+ WITHER_SKULL(KelpVersion.MC_1_8_0, ThrownWitherSkullEntity.class),
+ PRIMED_TNT(KelpVersion.MC_1_8_0, PrimedTntEntity.class),
+ FALLING_BLOCK(KelpVersion.MC_1_8_0, FallingBlockEntity.class),
+ FIREWORK(KelpVersion.MC_1_8_0, FireworkEntity.class),
+ HUSK(KelpVersion.MC_1_10_0, HuskEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isHostile() { return true; }
+ },
+ SPECTRAL_ARROW(KelpVersion.MC_1_9_0, SpectralArrowEntity.class),
+ SHULKER_BULLET(KelpVersion.MC_1_9_0, ShulkerBulletEntity.class),
+ DRAGON_FIREBALL(KelpVersion.MC_1_9_0, DragonFireballEntity.class),
+ ZOMBIE_VILLAGER(KelpVersion.MC_1_8_0, ZombieVillagerEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isHostile() { return true; }
+ },
+ SKELETON_HORSE(KelpVersion.MC_1_8_0, SkeletonHorseEntity.class) {
+ public boolean isUndead() { return true; }
+ },
+ ZOMBIE_HORSE(KelpVersion.MC_1_8_0, ZombieHorse.class) {
+ public boolean isUndead() { return true; }
+ },
+ ARMOR_STAND(KelpVersion.MC_1_8_0, ArmorStandEntity.class),
+ DONKEY(KelpVersion.MC_1_8_0, DonkeyEntity.class),
+ MULE(KelpVersion.MC_1_8_0, MuleEntity.class),
+ EVOKER_FANGS(KelpVersion.MC_1_11_0, EvokerFangEntity.class),
+ EVOKER(KelpVersion.MC_1_11_0, EvokerEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ VEX(KelpVersion.MC_1_11_0, VexEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ VINDICATOR(KelpVersion.MC_1_11_0, VindicatorEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ ILLUSIONER(KelpVersion.MC_1_12_0, IllusionerEntity.class),
+ MINECART_COMMAND(KelpVersion.MC_1_8_0, CommandMinecartEntity.class),
+ BOAT(KelpVersion.MC_1_8_0, BoatEntity.class),
+ MINECART(KelpVersion.MC_1_8_0, RideableMinecart.class),
+ MINECART_CHEST(KelpVersion.MC_1_8_0, StorageMinecart.class),
+ MINECART_FURNACE(KelpVersion.MC_1_8_0, PoweredMinecart.class),
+ MINECART_TNT(KelpVersion.MC_1_8_0, ExplosiveMinecart.class),
+ MINECART_HOPPER(KelpVersion.MC_1_8_0, HopperMinecart.class),
+ MINECART_MOB_SPAWNER(KelpVersion.MC_1_8_0, SpawnerMinecart.class),
+ CREEPER(KelpVersion.MC_1_8_0, CreeperEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ SKELETON(KelpVersion.MC_1_8_0, SkeletonEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isHostile() { return true; }
+ },
+ SPIDER(KelpVersion.MC_1_8_0, SpiderEntity.class),
+ ZOMBIE_GIANT(KelpVersion.MC_1_8_0, ZombieGiant.class) {
+ public boolean isUndead() { return true; }
+ },
+ ZOMBIE(KelpVersion.MC_1_8_0, ZombieEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isHostile() { return true; }
+ },
+ SLIME(KelpVersion.MC_1_8_0, SlimeEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ GHAST(KelpVersion.MC_1_8_0, GhastEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ PIG_ZOMBIE(KelpVersion.MC_1_8_0, PigZombie.class) {
+ public boolean isUndead() { return true; }
+ },
+ ENDERMAN(KelpVersion.MC_1_8_0, EndermanEntity.class),
+ CAVE_SPIDER(KelpVersion.MC_1_8_0, CaveSpiderEntity.class),
+ SILVERFISH(KelpVersion.MC_1_8_0, SilverfishEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ BLAZE(KelpVersion.MC_1_8_0, BlazeEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ MAGMA_CUBE(KelpVersion.MC_1_8_0, MagmaCubeEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ ENDER_DRAGON(KelpVersion.MC_1_8_0, EnderDragonEntity.class) {
+ public boolean isBoss() { return true; }
+ },
+ WITHER(KelpVersion.MC_1_8_0, WitherEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isBoss() { return true; }
+ },
+ BAT(KelpVersion.MC_1_8_0, BatEntity.class),
+ WITCH(KelpVersion.MC_1_8_0, WitchEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ ENDERMITE(KelpVersion.MC_1_8_0, EndermiteEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ GUARDIAN(KelpVersion.MC_1_8_0, GuardianEntity.class) {
+ public boolean isHostile() { return true; }
+ public boolean isAquatic() { return true; }
+ },
+ SHULKER(KelpVersion.MC_1_9_0, ShulkerEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ PIG(KelpVersion.MC_1_8_0, PigEntity.class),
+ SHEEP(KelpVersion.MC_1_8_0, SheepEntity.class),
+ COW(KelpVersion.MC_1_8_0, CowEntity.class),
+ CHICKEN(KelpVersion.MC_1_8_0, ChickenEntity.class),
+ SQUID(KelpVersion.MC_1_8_0, SquidEntity.class) {
+ public boolean isAquatic() { return true; }
+ },
+ WOLF(KelpVersion.MC_1_8_0, WolfEntity.class),
+ MUSHROOM_COW(KelpVersion.MC_1_8_0, MushroomCowEntity.class),
+ SNOWMAN(KelpVersion.MC_1_8_0, SnowmanEntity.class),
+ OCELOT(KelpVersion.MC_1_8_0, OcelotEntity.class),
+ IRON_GOLEM(KelpVersion.MC_1_8_0, IronGolemEntity.class),
+ HORSE(KelpVersion.MC_1_8_0, HorseEntity.class),
+ RABBIT(KelpVersion.MC_1_8_0, RabbitEntity.class),
+ KILLER_BUNNY(KelpVersion.MC_1_8_0, KillerBunnyEntity.class),
+ POLAR_BEAR(KelpVersion.MC_1_10_0, PolarBear.class),
+ LLAMA(KelpVersion.MC_1_11_0, LlamaEntity.class),
+ LLAMA_SPIT(KelpVersion.MC_1_11_0, LlamaSpitEntity.class),
+ PARROT(KelpVersion.MC_1_12_0, ParrotEntity.class),
+ VILLAGER(KelpVersion.MC_1_8_0, VillagerEntity.class),
+ ENDER_CRYSTAL(KelpVersion.MC_1_8_0, EnderCrystalEntity.class),
+ TURTLE(KelpVersion.MC_1_13_0, TurtleEntity.class) {
+ public boolean isAquatic() { return true; }
+ },
+ PHANTOM(KelpVersion.MC_1_13_0, PhantomEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ TRIDENT(KelpVersion.MC_1_13_0, ThrownTridentEntity.class),
+ COD(KelpVersion.MC_1_13_0, CodEntity.class) {
+ public boolean isAquatic() { return true; }
+ },
+ SALMON(KelpVersion.MC_1_13_0, SalmonEntity.class) {
+ public boolean isAquatic() { return true; }
+ },
+ PUFFERFISH(KelpVersion.MC_1_13_0, PufferfishEntity.class) {
+ public boolean isAquatic() { return true; }
+ },
+ TROPICAL_FISH(KelpVersion.MC_1_13_0, TropicalFishEntity.class) {
+ public boolean isAquatic() { return true; }
+ },
+ DROWNED(KelpVersion.MC_1_13_0, DrownedEntity.class) {
+ public boolean isUndead() { return true; }
+ public boolean isHostile() { return true; }
+ },
+ DOLPHIN(KelpVersion.MC_1_13_0, DolphinEntity.class) {
+ public boolean isAquatic() { return true; }
+ },
+ CAT(KelpVersion.MC_1_8_0, CatEntity.class),
+ PANDA(KelpVersion.MC_1_14_0, PandaEntity.class),
+ PILLAGER(KelpVersion.MC_1_14_0, PillagerEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ RAVAGER(KelpVersion.MC_1_14_0, RavagerEntity.class) {
+ public boolean isHostile() { return true; }
+ },
+ TRADER_LLAMA(KelpVersion.MC_1_14_0, TraderLlamaEntity.class),
+ WANDERING_TRADER(KelpVersion.MC_1_14_0, WanderingTraderEntity.class),
+ FOX(KelpVersion.MC_1_14_0, FoxEntity.class),
+ FISHING_HOOK(KelpVersion.MC_1_8_0, FishHookEntity.class),
+ LIGHTNING(KelpVersion.MC_1_8_0, LightningEntity.class),
+ PLAYER(KelpVersion.MC_1_8_0, KelpPlayer.class),
+
+ BEE(KelpVersion.MC_1_15_0, BeeEntity.class),
+ ZOGLIN(KelpVersion.MC_1_16_0, ZoglinEntity.class),
+ PIGLIN(KelpVersion.MC_1_16_0, PiglinEntity.class),
+ PIGLIN_BRUTE(KelpVersion.MC_1_16_0, PiglinBruteEntity.class),
+ LARGE_FIREBALL(KelpVersion.MC_1_8_0, LargeFireball.class),
+ HOGLIN(KelpVersion.MC_1_8_0, HoglinEntity.class),
+ STRIDER(KelpVersion.MC_1_16_0, StriderEntity.class),
+
UNKNOWN(KelpVersion.MC_1_8_0, null);
private KelpVersion since;
- private Class extends KelpEntity> entityClass;
+ private Class extends KelpEntity>> entityClass;
- KelpEntityType(KelpVersion since, Class extends KelpEntity> entityClass) {
+ KelpEntityType(KelpVersion since, Class extends KelpEntity>> entityClass) {
this.since = since;
this.entityClass = entityClass;
}
@@ -132,7 +227,7 @@ public KelpVersion since() {
return since;
}
- public Class extends KelpEntity> getEntityClass() {
+ public Class> getEntityClass() {
return entityClass;
}
@@ -140,6 +235,27 @@ public static boolean isLivingEntity(KelpEntityType entityType) {
return entityType == KelpEntityType.ZOMBIE;
}
+ public boolean isUndead() {
+ return false;
+ }
+
+ public boolean isAquatic() {
+ return false;
+ }
+
+ // TODO IMPLEMENT!!!!
+ public boolean isArthropod() {
+ return false;
+ }
+
+ public boolean isBoss() {
+ return false;
+ }
+
+ public boolean isHostile() {
+ return false;
+ }
+
public static Collection aboveVersion(KelpVersion version) {
Collection output = new ArrayList<>();
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/LivingKelpEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/LivingKelpEntity.java
index 7dab04a2..57b0a98f 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/LivingKelpEntity.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/LivingKelpEntity.java
@@ -1,51 +1,43 @@
package de.pxav.kelp.core.entity;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
-import de.pxav.kelp.core.entity.version.LivingEntityVersionTemplate;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import de.pxav.kelp.core.entity.type.general.DamageableEntity;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffect;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.inventory.type.SimpleEntityEquipment;
import de.pxav.kelp.core.world.KelpLocation;
-import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
-/**
- * A class description goes here.
- *
- * @author pxav
- */
-public class LivingKelpEntity extends KelpEntity {
-
- protected LivingEntityVersionTemplate livingEntityVersionTemplate;
- protected LivingEntity bukkitLivingEntity;
-
- public LivingKelpEntity(Object minecraftEntity,
- KelpEntityType entityType,
- Location initialLocation,
- int entityId,
- EntityVersionTemplate entityVersionTemplate,
- LivingEntityVersionTemplate livingEntityVersionTemplate,
- LivingEntity bukkitLivingEntity) {
- super(minecraftEntity, entityType, initialLocation, entityId, entityVersionTemplate);
- this.livingEntityVersionTemplate = livingEntityVersionTemplate;
- this.bukkitLivingEntity = bukkitLivingEntity;
- }
+import java.util.Collection;
+import java.util.Set;
- public LivingKelpEntity() {}
+public interface LivingKelpEntity> extends KelpEntity, DamageableEntity {
- public LivingKelpEntity bukkitLivingEntity(LivingEntity bukkitLivingEntity) {
- this.bukkitLivingEntity = bukkitLivingEntity;
- return this;
- }
+ T addPotionEffect(KelpPotionEffect potionEffect);
- public LivingKelpEntity livingEntityVersionTemplate(LivingEntityVersionTemplate livingEntityVersionTemplate) {
- this.livingEntityVersionTemplate = livingEntityVersionTemplate;
- return this;
- }
+ Collection getActivePotionEffects();
- public LivingEntity toBukkitLivingEntity() {
- return bukkitLivingEntity;
+ default Collection getActivePotionEffectTypes() {
+ Set output = Sets.newHashSet();
+ for (KelpPotionEffect effect : getActivePotionEffects()) {
+ output.add(effect.getEffectType());
+ }
+ return output;
}
- public KelpLocation getEyeLocation() {
- return this.livingEntityVersionTemplate.getEyeLocation(bukkitLivingEntity);
- }
+ T removePotionEffect(KelpPotionEffectType effectType);
+
+ /**
+ * Gets the location of the entity's eyes. When you get
+ * the normal location of a player for example, the feet location
+ * will be returned. This method gets the eye location depending
+ * on the current entity type.
+ *
+ * @return The location of the entity's eyes.
+ */
+ KelpLocation getEyeLocation();
+
+ SimpleEntityEquipment getEquipment();
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/AreaEffectCloudEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/AreaEffectCloudEntity.java
new file mode 100644
index 00000000..b2b58f10
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/AreaEffectCloudEntity.java
@@ -0,0 +1,120 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.ProjectileLauncher;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.particle.type.ParticleType;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+import java.util.List;
+
+public interface AreaEffectCloudEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static AreaEffectCloudEntity create(KelpLocation location) {
+ return (AreaEffectCloudEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static AreaEffectCloudEntity from(Entity entity) {
+ return (AreaEffectCloudEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.AREA_EFFECT_CLOUD;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getDuration();
+
+ void setDuration(int var1);
+
+ int getWaitTime();
+
+ void setWaitTime(int var1);
+
+ int getReapplicationDelay();
+
+ void setReapplicationDelay(int var1);
+
+ int getDurationOnUse();
+
+ void setDurationOnUse(int var1);
+
+ float getRadius();
+
+ void setRadius(float var1);
+
+ float getRadiusOnUse();
+
+ void setRadiusOnUse(float var1);
+
+ float getRadiusPerTick();
+
+ void setRadiusPerTick(float var1);
+
+ ParticleType getParticle();
+
+ void setParticle(ParticleType particleType);
+
+ void setBasePotionEffect(KelpPotionEffectType potionEffect);
+
+ KelpPotionEffectType getBasePotionEffect();
+
+ boolean hasCustomEffects();
+
+ List getCustomEffects();
+
+ boolean addCustomEffect(KelpPotionEffectType effect, boolean var2);
+
+ boolean removeCustomEffect(KelpPotionEffectType effect);
+
+ boolean hasCustomEffect(KelpPotionEffectType effect);
+
+ void clearCustomEffects();
+
+ Color getColor();
+
+ void setColor(Color color);
+
+ ProjectileLauncher> getSource();
+
+ void setSource(ProjectileLauncher> source);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ArmorStandEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ArmorStandEntity.java
new file mode 100644
index 00000000..09d18bc3
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ArmorStandEntity.java
@@ -0,0 +1,113 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.type.SimpleEntityEquipment;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.ArmorStand;
+import org.bukkit.entity.Entity;
+import org.bukkit.util.EulerAngle;
+
+public interface ArmorStandEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ArmorStandEntity create(KelpLocation location) {
+ return (ArmorStandEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static ArmorStandEntity from(Entity entity) {
+ return (ArmorStandEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ARMOR_STAND;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ EulerAngle getBodyPose();
+
+ ArmorStandEntity setBodyPose(EulerAngle bodyPose);
+
+ EulerAngle getLeftArmPose();
+
+ ArmorStandEntity setLeftArmPose(EulerAngle leftArmPose);
+
+ EulerAngle getRightArmPose();
+
+ ArmorStandEntity setRightArmPose(EulerAngle rightArmPose);
+
+ EulerAngle getLeftLegPose();
+
+ ArmorStandEntity setLeftLegPose(EulerAngle leftLegPose);
+
+ EulerAngle getRightLegPose();
+
+ ArmorStandEntity setRightLegPose(EulerAngle rightLegPose);
+
+ EulerAngle getHeadPose();
+
+ ArmorStandEntity setHeadPose(EulerAngle headPose);
+
+ boolean hasBasePlate();
+
+ ArmorStandEntity setBasePlate(boolean basePlate);
+
+ boolean isVisible();
+
+ ArmorStandEntity setVisible(boolean visible);
+
+ boolean hasArms();
+
+ ArmorStandEntity setArms(boolean arms);
+
+ boolean isSmall();
+
+ ArmorStandEntity setSmall(boolean small);
+
+ boolean isMarker();
+
+ ArmorStandEntity setMarker(boolean marker);
+
+ SimpleEntityEquipment getEquipment();
+
+// void addEquipmentLock(EquipmentSlot var1, ArmorStand.LockType var2);
+//
+// void removeEquipmentLock(EquipmentSlot var1, ArmorStand.LockType var2);
+//
+// boolean hasEquipmentLock(EquipmentSlot var1, ArmorStand.LockType var2);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ArrowEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ArrowEntity.java
new file mode 100644
index 00000000..017b777a
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ArrowEntity.java
@@ -0,0 +1,79 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractArrowEntity;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+import java.util.List;
+
+public interface ArrowEntity extends AbstractArrowEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ArrowEntity create(KelpLocation location) {
+ return (ArrowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static ArrowEntity from(Entity entity) {
+ return (ArrowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ARROW;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ ArrowEntity addCustomEffect(KelpPotionEffectType effect, int tier);
+
+ boolean hasCustomEffect(KelpPotionEffectType effect);
+
+ ArrowEntity removeCustomEffect(KelpPotionEffectType effect);
+
+ ArrowEntity setColor(Color color);
+
+ Color getColor();
+
+ List getCustomEffects();
+
+ boolean hasCustomEffects();
+
+ int getCustomEffectTier(KelpPotionEffectType effect);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/BatEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/BatEntity.java
new file mode 100644
index 00000000..3ec50d47
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/BatEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MobileEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface BatEntity extends MobileEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static BatEntity create(KelpLocation location) {
+ return (BatEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static BatEntity from(Entity entity) {
+ return (BatEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.BAT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isAwake();
+
+ BatEntity setAwake(boolean awake);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/BeeEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/BeeEntity.java
new file mode 100644
index 00000000..2ee4d805
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/BeeEntity.java
@@ -0,0 +1,84 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Location;
+import org.bukkit.entity.Entity;
+
+public interface BeeEntity extends BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static BeeEntity create(KelpLocation location) {
+ return (BeeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static BeeEntity from(Entity entity) {
+ return (BeeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.BEE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ KelpLocation getHive();
+
+ void setHive(KelpLocation hive);
+
+ KelpLocation getFlower();
+
+ void setFlower(KelpLocation flower);
+
+ boolean hasNectar();
+
+ void setHasNectar(boolean hasNectar);
+
+ boolean hasStung();
+
+ void setHasStung(boolean hasStung);
+
+ int getAnger();
+
+ void setAnger(int anger);
+
+ int getCannotEnterHiveTicks();
+
+ void setCannotEnterHiveTicks(int cannotEnterHiveTicks);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/BlazeEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/BlazeEntity.java
new file mode 100644
index 00000000..51a8f024
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/BlazeEntity.java
@@ -0,0 +1,78 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Difficulty;
+import org.bukkit.entity.Blaze;
+import org.bukkit.entity.Entity;
+
+public interface BlazeEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static BlazeEntity create(KelpLocation location) {
+ return (BlazeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static BlazeEntity from(Entity entity) {
+ return (BlazeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.BLAZE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ @Override
+ default int getMaximumSpawnLightLevel() {
+ return -1;
+ }
+
+ @Override
+ default double getAttackDamage(Difficulty difficulty) {
+ if (difficulty == Difficulty.EASY) {
+ return 4;
+ } else if (difficulty == Difficulty.NORMAL) {
+ return 5;
+ } if (difficulty == Difficulty.HARD) {
+ return 9;
+ }
+ return 0;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/BoatEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/BoatEntity.java
new file mode 100644
index 00000000..997aac93
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/BoatEntity.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.VehicleEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.material.KelpMaterial;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface BoatEntity extends VehicleEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static BoatEntity create(KelpLocation location) {
+ return (BoatEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static BoatEntity from(Entity entity) {
+ return (BoatEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.BOAT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ KelpMaterial getBoatType();
+
+ BoatEntity setBoatType(KelpMaterial boatType);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/CatEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/CatEntity.java
new file mode 100644
index 00000000..a372e8c2
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/CatEntity.java
@@ -0,0 +1,70 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.util.CatType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Cat;
+import org.bukkit.entity.Entity;
+
+public interface CatEntity extends AnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static CatEntity create(KelpLocation location) {
+ return (CatEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static CatEntity from(Entity entity) {
+ return (CatEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.CAT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ Color getCollarDyeColor();
+
+ CatEntity setCollarDyeColor(Color color);
+
+ CatType getCatType();
+
+ CatEntity setCatType(CatType catType);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/CaveSpiderEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/CaveSpiderEntity.java
new file mode 100644
index 00000000..85e1a68e
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/CaveSpiderEntity.java
@@ -0,0 +1,76 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Difficulty;
+import org.bukkit.entity.Entity;
+
+public interface CaveSpiderEntity extends SpiderEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static CaveSpiderEntity create(KelpLocation location) {
+ return (CaveSpiderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static CaveSpiderEntity from(Entity entity) {
+ return (CaveSpiderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.CAVE_SPIDER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ @Override
+ default int getMaximumSpawnLightLevel() {
+ return 7;
+ }
+
+ @Override
+ default double getAttackDamage(Difficulty difficulty) {
+ if (difficulty == Difficulty.EASY) {
+ return 2;
+ } else if (difficulty == Difficulty.NORMAL) {
+ return 2;
+ } if (difficulty == Difficulty.HARD) {
+ return 3;
+ }
+ return 0;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ChickenEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ChickenEntity.java
new file mode 100644
index 00000000..68bcc708
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ChickenEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ChickenEntity extends BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ChickenEntity create(KelpLocation location) {
+ return (ChickenEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static ChickenEntity from(Entity entity) {
+ return (ChickenEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.CHICKEN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/CodEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/CodEntity.java
new file mode 100644
index 00000000..0f48cbf2
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/CodEntity.java
@@ -0,0 +1,60 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractFishEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Cod;
+import org.bukkit.entity.Entity;
+
+public interface CodEntity extends AbstractFishEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static CodEntity create(KelpLocation location) {
+ return (CodEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static CodEntity from(Entity entity) {
+ return (CodEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.COD;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/CommandMinecartEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/CommandMinecartEntity.java
new file mode 100644
index 00000000..e73c0791
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/CommandMinecartEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface CommandMinecartEntity extends MinecartEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static CommandMinecartEntity create(KelpLocation location) {
+ return (CommandMinecartEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static CommandMinecartEntity from(Entity entity) {
+ return (CommandMinecartEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MINECART_COMMAND;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ String getCommand();
+
+ CommandMinecartEntity setCommand(String command);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/CowEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/CowEntity.java
new file mode 100644
index 00000000..933233d6
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/CowEntity.java
@@ -0,0 +1,61 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.command.Command;
+import org.bukkit.entity.Entity;
+
+public interface CowEntity extends AnimalEntity, BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static CowEntity create(KelpLocation location) {
+ return (CowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static CowEntity from(Entity entity) {
+ return (CowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.COW;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/CreeperEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/CreeperEntity.java
new file mode 100644
index 00000000..ba8bcc31
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/CreeperEntity.java
@@ -0,0 +1,105 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.ExplosiveEntity;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Difficulty;
+import org.bukkit.entity.Entity;
+
+public interface CreeperEntity extends MonsterEntity, ExplosiveEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static CreeperEntity create(KelpLocation location) {
+ return (CreeperEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static CreeperEntity from(Entity entity) {
+ return (CreeperEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.CREEPER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isCharged();
+
+ CreeperEntity setCharged(boolean charged);
+
+ CreeperEntity setMaxFuseTicks(int maxFuseTicks);
+
+ int getMaxFuseTicks();
+
+ CreeperEntity setFuseTicks(int fuseTicks);
+
+ int getFuseTicks();
+
+ CreeperEntity explode();
+
+ CreeperEntity ignite();
+
+ boolean isIgnited();
+
+ @Override
+ default int getMaximumSpawnLightLevel() {
+ return 7;
+ }
+
+ @Override
+ default double getAttackDamage(Difficulty difficulty) {
+ if (difficulty == Difficulty.EASY) {
+ if (isCharged()) {
+ return 43.5;
+ }
+ return 22.5;
+ } else if (difficulty == Difficulty.NORMAL) {
+ if (isCharged()) {
+ return 85;
+ }
+ return 43;
+ } if (difficulty == Difficulty.HARD) {
+ if (isCharged()) {
+ return 127.5;
+ }
+ return 64.5;
+ }
+ return 0;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/DolphinEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/DolphinEntity.java
new file mode 100644
index 00000000..962b8a2c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/DolphinEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.WaterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface DolphinEntity extends WaterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static DolphinEntity create(KelpLocation location) {
+ return (DolphinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static DolphinEntity from(Entity entity) {
+ return (DolphinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.DOLPHIN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/DonkeyEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/DonkeyEntity.java
new file mode 100644
index 00000000..cfd3c1fa
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/DonkeyEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.ChestedHorse;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface DonkeyEntity extends ChestedHorse {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static DonkeyEntity create(KelpLocation location) {
+ return (DonkeyEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static DonkeyEntity from(Entity entity) {
+ return (DonkeyEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.DONKEY;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/DragonFireballEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/DragonFireballEntity.java
new file mode 100644
index 00000000..d3f71f90
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/DragonFireballEntity.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface DragonFireballEntity extends ThrownFireballEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static DragonFireballEntity create(KelpLocation location) {
+ return (DragonFireballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static DragonFireballEntity from(Entity entity) {
+ return (DragonFireballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.DRAGON_FIREBALL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/DroppedItemEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/DroppedItemEntity.java
index 2b17d9d0..c35c4efb 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/type/DroppedItemEntity.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/DroppedItemEntity.java
@@ -3,10 +3,11 @@
import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.entity.KelpEntity;
import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.util.ItemDropType;
import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
import de.pxav.kelp.core.inventory.item.KelpItem;
-import org.bukkit.Location;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
/**
@@ -14,36 +15,60 @@
*
* @author pxav
*/
-public class DroppedItemEntity extends KelpEntity {
+public interface DroppedItemEntity extends KelpEntity {
- private KelpItem item;
- private ItemDropType itemDropType;
-
- public static DroppedItemEntity from(Item item) {
- return (DroppedItemEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).getKelpEntity(item);
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static DroppedItemEntity create(KelpLocation location) {
+ return (DroppedItemEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
}
- public DroppedItemEntity() {}
-
- public DroppedItemEntity(EntityVersionTemplate entityVersionTemplate, Object entity, int entityId, Location location, KelpItem item) {
- super(entity, KelpEntityType.DROPPED_ITEM, location, entityId, entityVersionTemplate);
- this.item = item;
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static DroppedItemEntity from(Entity entity) {
+ return (DroppedItemEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
}
- public KelpItem getItem() {
- return item;
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.DROPPED_ITEM;
}
- public void setItem(KelpItem item) {
- this.item = item;
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
}
- public ItemDropType getItemDropType() {
- return itemDropType;
- }
+ KelpItem getItem();
- public void setItemDropType(ItemDropType itemDropType) {
- this.itemDropType = itemDropType;
- }
+ void setItem(KelpItem item);
+
+ ItemDropType getItemDropType();
+
+ void setItemDropType(ItemDropType itemDropType);
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/DrownedEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/DrownedEntity.java
new file mode 100644
index 00000000..37c37e00
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/DrownedEntity.java
@@ -0,0 +1,76 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Difficulty;
+import org.bukkit.entity.Entity;
+
+public interface DrownedEntity extends ZombieEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ZombieEntity create(KelpLocation location) {
+ return (ZombieEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static ZombieEntity from(Entity entity) {
+ return (ZombieEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.DROWNED;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ @Override
+ default int getMaximumSpawnLightLevel() {
+ return 7;
+ }
+
+ @Override
+ default double getAttackDamage(Difficulty difficulty) {
+ if (difficulty == Difficulty.EASY) {
+ return 2.5;
+ } else if (difficulty == Difficulty.NORMAL) {
+ return 3;
+ } if (difficulty == Difficulty.HARD) {
+ return 4.5;
+ }
+ return 0;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ElderGuardianEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ElderGuardianEntity.java
index 6d8dd705..3cf648a5 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/type/ElderGuardianEntity.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ElderGuardianEntity.java
@@ -1,21 +1,65 @@
package de.pxav.kelp.core.entity.type;
+import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityFactory;
import de.pxav.kelp.core.entity.KelpEntityType;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
-import org.bukkit.Location;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
/**
* A class description goes here.
*
* @author pxav
*/
-public class ElderGuardianEntity extends KelpEntity {
+public interface ElderGuardianEntity extends MonsterEntity {
- public ElderGuardianEntity() {}
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ElderGuardianEntity create(KelpLocation location) {
+ return (ElderGuardianEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static ElderGuardianEntity from(Entity entity) {
+ return (ElderGuardianEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ELDER_GUARDIAN;
+ }
- public ElderGuardianEntity(EntityVersionTemplate entityVersionTemplate, Object entity, int entityId, Location location) {
- super(entity, KelpEntityType.ELDER_GUARDIAN, location, entityId, entityVersionTemplate);
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/EnderCrystalEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/EnderCrystalEntity.java
new file mode 100644
index 00000000..f245994d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/EnderCrystalEntity.java
@@ -0,0 +1,66 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface EnderCrystalEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static EnderCrystalEntity create(KelpLocation location) {
+ return (EnderCrystalEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static EnderCrystalEntity from(Entity entity) {
+ return (EnderCrystalEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ENDER_CRYSTAL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isShowingBottom();
+
+ EnderCrystalEntity setShowingBottom(boolean showingBottom);
+
+ KelpLocation getBeamTarget();
+
+ EnderCrystalEntity setBeamTarget(KelpLocation beamTarget);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/EnderDragonEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/EnderDragonEntity.java
new file mode 100644
index 00000000..03d9a9c2
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/EnderDragonEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface EnderDragonEntity extends LivingKelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static EnderDragonEntity create(KelpLocation location) {
+ return (EnderDragonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static EnderDragonEntity from(Entity entity) {
+ return (EnderDragonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ENDER_DRAGON;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getDeathAnimationInTicks();
+
+ // TODO implement other ender dragon specific things
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/EnderSignalEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/EnderSignalEntity.java
new file mode 100644
index 00000000..3ea3bf70
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/EnderSignalEntity.java
@@ -0,0 +1,75 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.item.KelpItem;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface EnderSignalEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static EnderSignalEntity create(KelpLocation location) {
+ return (EnderSignalEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static EnderSignalEntity from(Entity entity) {
+ return (EnderSignalEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ENDER_SIGNAL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ KelpLocation getTargetLocation();
+
+ EnderSignalEntity setTargetLocation(KelpLocation var1);
+
+ boolean getDropItem();
+
+ EnderSignalEntity setDropItem(boolean dropItem);
+
+ KelpItem getItem();
+
+ EnderSignalEntity setItem(KelpItem item);
+
+ int getDespawnTimer();
+
+ EnderSignalEntity setDespawnTimer(int despawnTimer);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/EndermanEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/EndermanEntity.java
new file mode 100644
index 00000000..6b2c4311
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/EndermanEntity.java
@@ -0,0 +1,65 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.material.KelpMaterial;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Enderman;
+import org.bukkit.entity.Entity;
+
+public interface EndermanEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static EndermanEntity create(KelpLocation location) {
+ return (EndermanEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static EndermanEntity from(Entity entity) {
+ return (EndermanEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ENDERMAN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ KelpMaterial getCarriedBlock();
+
+ EndermanEntity setCarriedBlock(KelpMaterial carriedBlock);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/EndermiteEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/EndermiteEntity.java
new file mode 100644
index 00000000..8c42eec2
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/EndermiteEntity.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Endermite;
+import org.bukkit.entity.Entity;
+
+public interface EndermiteEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static EndermiteEntity create(KelpLocation location) {
+ return (EndermiteEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static EndermiteEntity from(Entity entity) {
+ return (EndermiteEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ENDERMITE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isPlayerSpawned();
+
+ EndermiteEntity setPlayerSpawned(boolean playerSpawned);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/EvokerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/EvokerEntity.java
new file mode 100644
index 00000000..5b3412b1
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/EvokerEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.SpellcastingEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface EvokerEntity extends SpellcastingEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static EvokerEntity create(KelpLocation location) {
+ return (EvokerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static EvokerEntity from(Entity entity) {
+ return (EvokerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.EVOKER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/EvokerFangEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/EvokerFangEntity.java
new file mode 100644
index 00000000..4dd36b98
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/EvokerFangEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface EvokerFangEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static EvokerFangEntity create(KelpLocation location) {
+ return (EvokerFangEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static EvokerFangEntity from(Entity entity) {
+ return (EvokerFangEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.EVOKER_FANGS;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ LivingKelpEntity> getFangOwner();
+
+ EvokerFangEntity setFangOwner(LivingKelpEntity> fangOwner);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ExperienceOrbEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ExperienceOrbEntity.java
new file mode 100644
index 00000000..c8b8b211
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ExperienceOrbEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.ExperienceOrb;
+
+public interface ExperienceOrbEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ExperienceOrbEntity create(KelpLocation location) {
+ return (ExperienceOrbEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ExperienceOrbEntity from(Entity entity) {
+ return (ExperienceOrbEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.EXPERIENCE_ORB;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getExperience();
+
+ ExperienceOrbEntity setExperience(int experience);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ExplosiveMinecart.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ExplosiveMinecart.java
new file mode 100644
index 00000000..02fafc64
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ExplosiveMinecart.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ExplosiveMinecart extends MinecartEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ExplosiveMinecart create(KelpLocation location) {
+ return (ExplosiveMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ExplosiveMinecart from(Entity entity) {
+ return (ExplosiveMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MINECART_TNT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/FallingBlockEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/FallingBlockEntity.java
new file mode 100644
index 00000000..db535d44
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/FallingBlockEntity.java
@@ -0,0 +1,69 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.material.KelpMaterial;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface FallingBlockEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static FallingBlockEntity create(KelpLocation location) {
+ return (FallingBlockEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static FallingBlockEntity from(Entity entity) {
+ return (FallingBlockEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.FALLING_BLOCK;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean canHurtEntities();
+
+ boolean willDropItem();
+
+ FallingBlockEntity dropsItem(boolean dropsItem);
+
+ FallingBlockEntity hurtEntities(boolean hurtEntities);
+
+ KelpMaterial getMaterial();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/FireworkEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/FireworkEntity.java
new file mode 100644
index 00000000..76a074b8
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/FireworkEntity.java
@@ -0,0 +1,71 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.metadata.FireworkMetadata;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Firework;
+
+public interface FireworkEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static FireworkEntity create(KelpLocation location) {
+ return (FireworkEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static FireworkEntity from(Entity entity) {
+ return (FireworkEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.FIREWORK;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ FireworkEntity detonate();
+
+ FireworkMetadata getFireworkMetadata();
+
+ FireworkEntity setFireworkMetadata(FireworkMetadata fireworkMetadata);
+
+ boolean isShotAtAngle();
+
+ FireworkEntity setShotAtAngle(boolean shotAtAngle);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/FishHookEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/FishHookEntity.java
new file mode 100644
index 00000000..faa6e492
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/FishHookEntity.java
@@ -0,0 +1,89 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.util.FishHookState;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftFishHook;
+import org.bukkit.entity.Entity;
+
+public interface FishHookEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static FishHookEntity create(KelpLocation location) {
+ return (FishHookEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static FishHookEntity from(Entity entity) {
+ return (FishHookEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.FISHING_HOOK;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ KelpEntity> getOwner();
+
+ int getWaitTimeInTicks();
+
+ FishHookEntity setWaitTime(int waitTicks);
+
+ int getMinWaitTime();
+
+ FishHookEntity setMinWaitTime(int minWaitTime);
+
+ int getMaxWaitTime();
+
+ FishHookEntity setMaxWaitTime(int maxWaitTime);
+
+ boolean hasLure();
+
+ FishHookEntity setApplyLure(boolean hasLure);
+
+ boolean isInOpenWater();
+
+ KelpEntity> getHookedEntity();
+
+ FishHookEntity setHookedEntity(KelpEntity> hookedEntity);
+
+ FishHookEntity pullHookedEntity();
+
+ FishHookState getFishHookState();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/FoxEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/FoxEntity.java
new file mode 100644
index 00000000..6ea49672
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/FoxEntity.java
@@ -0,0 +1,78 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.util.FoxType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface FoxEntity extends AnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static FoxEntity create(KelpLocation location) {
+ return (FoxEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static FoxEntity from(Entity entity) {
+ return (FoxEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.FOX;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ FoxType getFoxType();
+
+ void setFoxType(FoxType foxType);
+
+ boolean isCrouching();
+
+ void setCrouching(boolean crouching);
+
+ void setSleeping(boolean sleeping);
+
+ KelpEntity> getFirstTrustedEntity();
+
+ void setFirstTrustedEntity(KelpEntity> trusted);
+
+ KelpEntity> getSecondTrustedEntity();
+
+ void setSecondTrustedEntity(KelpEntity> trusted);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/GhastEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/GhastEntity.java
new file mode 100644
index 00000000..adae9985
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/GhastEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MobileEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface GhastEntity extends MobileEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static GhastEntity create(KelpLocation location) {
+ return (GhastEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static GhastEntity from(Entity entity) {
+ return (GhastEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.GHAST;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/GuardianEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/GuardianEntity.java
index 65067739..6480cc57 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/type/GuardianEntity.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/GuardianEntity.java
@@ -1,21 +1,65 @@
package de.pxav.kelp.core.entity.type;
+import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityFactory;
import de.pxav.kelp.core.entity.KelpEntityType;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
-import org.bukkit.Location;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
/**
* A class description goes here.
*
* @author pxav
*/
-public class GuardianEntity extends KelpEntity {
+public interface GuardianEntity extends MonsterEntity {
- public GuardianEntity() {}
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static GuardianEntity create(KelpLocation location) {
+ return (GuardianEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static GuardianEntity from(Entity entity) {
+ return (GuardianEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.GUARDIAN;
+ }
- public GuardianEntity(EntityVersionTemplate entityVersionTemplate, Object entity, int entityId, Location location) {
- super(entity, KelpEntityType.GUARDIAN, location, entityId, entityVersionTemplate);
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/HoglinEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/HoglinEntity.java
new file mode 100644
index 00000000..bfa5aca4
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/HoglinEntity.java
@@ -0,0 +1,73 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface HoglinEntity extends BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static HoglinEntity create(KelpLocation location) {
+ return (HoglinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static HoglinEntity from(Entity entity) {
+ return (HoglinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.HOGLIN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isImmuneToZombification();
+
+ void setImmuneToZombification(boolean immuneToZombification);
+
+ boolean isHuntable();
+
+ void setHuntable(boolean huntable);
+
+ int getConversionTime();
+
+ void setConversionTime(int conversionTime);
+
+ boolean isConverting();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/HopperMinecart.java b/core/src/main/java/de/pxav/kelp/core/entity/type/HopperMinecart.java
new file mode 100644
index 00000000..385bd629
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/HopperMinecart.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface HopperMinecart extends MinecartEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static HopperMinecart create(KelpLocation location) {
+ return (HopperMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static HopperMinecart from(Entity entity) {
+ return (HopperMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MINECART_HOPPER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isHopperEnabled();
+
+ HopperMinecart setHopperEnabled(boolean enabled);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/HorseEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/HorseEntity.java
new file mode 100644
index 00000000..fa894011
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/HorseEntity.java
@@ -0,0 +1,72 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractHorseEntity;
+import de.pxav.kelp.core.entity.util.HorseColor;
+import de.pxav.kelp.core.entity.util.HorseStyle;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.type.HorseInventory;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface HorseEntity extends AbstractHorseEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static HorseEntity create(KelpLocation location) {
+ return (HorseEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static HorseEntity from(Entity entity) {
+ return (HorseEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.HORSE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ HorseInventory getInventory();
+
+ HorseColor getHorseColor();
+
+ HorseStyle getHorseStyle();
+
+ HorseEntity setHorseColor(HorseColor color);
+
+ HorseEntity setHorseStyle(HorseStyle style);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/HuskEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/HuskEntity.java
new file mode 100644
index 00000000..8078a994
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/HuskEntity.java
@@ -0,0 +1,65 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Husk;
+
+public interface HuskEntity extends ZombieEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static HuskEntity create(KelpLocation location) {
+ return (HuskEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static HuskEntity from(Entity entity) {
+ return (HuskEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.HUSK;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isConverting();
+
+ int getConversionTime();
+
+ void setConversionTime(int conversionTime);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/IllusionerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/IllusionerEntity.java
new file mode 100644
index 00000000..da6058bb
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/IllusionerEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.IllagerEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface IllusionerEntity extends IllagerEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static IllusionerEntity create(KelpLocation location) {
+ return (IllusionerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static IllusionerEntity from(Entity entity) {
+ return (IllusionerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ILLUSIONER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/IronGolemEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/IronGolemEntity.java
new file mode 100644
index 00000000..420e7f09
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/IronGolemEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.GolemEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface IronGolemEntity extends GolemEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static IronGolemEntity create(KelpLocation location) {
+ return (IronGolemEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static IronGolemEntity from(Entity entity) {
+ return (IronGolemEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.IRON_GOLEM;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isPlayerCreated();
+
+ IronGolemEntity setPlayerCreated(boolean playerCreated);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ItemFrameEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ItemFrameEntity.java
new file mode 100644
index 00000000..6458ec33
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ItemFrameEntity.java
@@ -0,0 +1,85 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.HangingEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.item.KelpItem;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Rotation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.ItemFrame;
+
+// hanging, attachable
+public interface ItemFrameEntity extends HangingEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ItemFrameEntity create(KelpLocation location) {
+ return (ItemFrameEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ItemFrameEntity from(Entity entity) {
+ return (ItemFrameEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ITEM_FRAME;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ Rotation getItemRotation();
+
+ ItemFrameEntity setItemRotation(Rotation rotation);
+
+ ItemFrameEntity setFixed(boolean fixed);
+
+ boolean isFixed();
+
+ ItemFrameEntity setVisible(boolean visible);
+
+ boolean isVisible();
+
+ KelpItem getItem();
+
+ ItemFrameEntity setItem(KelpItem item);
+
+ ItemFrameEntity setItemAndPlayPlacementSound(KelpItem item);
+
+ double getItemDropChance();
+
+ ItemFrameEntity setItemDropChance(double itemDropChance);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/KillerBunnyEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/KillerBunnyEntity.java
new file mode 100644
index 00000000..5514d0ce
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/KillerBunnyEntity.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface KillerBunnyEntity extends RabbitEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static KillerBunnyEntity create(KelpLocation location) {
+ return (KillerBunnyEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static KillerBunnyEntity from(Entity entity) {
+ return (KillerBunnyEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.KILLER_BUNNY;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/LargeFireball.java b/core/src/main/java/de/pxav/kelp/core/entity/type/LargeFireball.java
new file mode 100644
index 00000000..ab43db05
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/LargeFireball.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface LargeFireball extends ThrownFireballEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static LargeFireball create(KelpLocation location) {
+ return (LargeFireball) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static LargeFireball from(Entity entity) {
+ return (LargeFireball) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.LARGE_FIREBALL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/LeashHitchEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/LeashHitchEntity.java
new file mode 100644
index 00000000..b5ded402
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/LeashHitchEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.HangingEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface LeashHitchEntity extends HangingEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static LeashHitchEntity create(KelpLocation location) {
+ return (LeashHitchEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static LeashHitchEntity from(Entity entity) {
+ return (LeashHitchEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.LEASH_HITCH;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/LightningEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/LightningEntity.java
new file mode 100644
index 00000000..c9ba58ee
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/LightningEntity.java
@@ -0,0 +1,60 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface LightningEntity extends KelpEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static LightningEntity create(KelpLocation location) {
+ return (LightningEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static LightningEntity from(Entity entity) {
+ return (LightningEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.LIGHTNING;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isEffect();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/LlamaEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/LlamaEntity.java
new file mode 100644
index 00000000..1be1054b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/LlamaEntity.java
@@ -0,0 +1,71 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractHorseEntity;
+import de.pxav.kelp.core.entity.util.LlamaColor;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.type.LlamaInventory;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface LlamaEntity extends AbstractHorseEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static LlamaEntity create(KelpLocation location) {
+ return (LlamaEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static LlamaEntity from(Entity entity) {
+ return (LlamaEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.LLAMA;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ LlamaInventory getInventory();
+
+ int getLlamaStrength();
+
+ LlamaEntity setLlamaStrength(int llamaStrength);
+
+ LlamaColor getBodyColor();
+
+ LlamaEntity setBodyColor(LlamaColor llamaColor);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/LlamaSpitEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/LlamaSpitEntity.java
new file mode 100644
index 00000000..ef0fe14c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/LlamaSpitEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface LlamaSpitEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static LlamaSpitEntity create(KelpLocation location) {
+ return (LlamaSpitEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static LlamaSpitEntity from(Entity entity) {
+ return (LlamaSpitEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.LLAMA_SPIT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/MagmaCubeEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/MagmaCubeEntity.java
new file mode 100644
index 00000000..92111015
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/MagmaCubeEntity.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface MagmaCubeEntity extends SlimeEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static MagmaCubeEntity create(KelpLocation location) {
+ return (MagmaCubeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static MagmaCubeEntity from(Entity entity) {
+ return (MagmaCubeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MAGMA_CUBE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/MuleEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/MuleEntity.java
new file mode 100644
index 00000000..c9e55971
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/MuleEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.ChestedHorse;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface MuleEntity extends ChestedHorse {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static MuleEntity create(KelpLocation location) {
+ return (MuleEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static MuleEntity from(Entity entity) {
+ return (MuleEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MULE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/MushroomCowEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/MushroomCowEntity.java
new file mode 100644
index 00000000..9584b3df
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/MushroomCowEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.util.MushroomCowType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface MushroomCowEntity extends CowEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static MushroomCowEntity create(KelpLocation location) {
+ return (MushroomCowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static MushroomCowEntity from(Entity entity) {
+ return (MushroomCowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MUSHROOM_COW;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ MushroomCowType getMushroomType();
+
+ MushroomCowEntity setMushroomType(MushroomCowType mushroomType);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/OcelotEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/OcelotEntity.java
new file mode 100644
index 00000000..2975e888
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/OcelotEntity.java
@@ -0,0 +1,60 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.TameableAnimal;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface OcelotEntity extends AnimalEntity, TameableAnimal {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static OcelotEntity create(KelpLocation location) {
+ return (OcelotEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static OcelotEntity from(Entity entity) {
+ return (OcelotEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.OCELOT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PaintingEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PaintingEntity.java
new file mode 100644
index 00000000..16062fcb
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PaintingEntity.java
@@ -0,0 +1,68 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.HangingEntity;
+import de.pxav.kelp.core.entity.util.PaintingType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PaintingEntity extends HangingEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PaintingEntity create(KelpLocation location) {
+ return (PaintingEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PaintingEntity from(Entity entity) {
+ return (PaintingEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PAINTING;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ PaintingEntity setPaintingType(PaintingType type);
+
+ PaintingType getPaintingType();
+
+ default int[] getPaintingDimensions() {
+ return new int[] {getPaintingType().getWidth(), getPaintingType().getHeight()};
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PandaEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PandaEntity.java
new file mode 100644
index 00000000..f6f40804
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PandaEntity.java
@@ -0,0 +1,70 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.type.general.TameableAnimal;
+import de.pxav.kelp.core.entity.util.PandaGene;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PandaEntity extends TameableAnimal, BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PandaEntity create(KelpLocation location) {
+ return (PandaEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PandaEntity from(Entity entity) {
+ return (PandaEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PANDA;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ PandaEntity setMainGene(PandaGene prominentGene);
+
+ PandaEntity setHiddenGene(PandaGene hiddenGene);
+
+ PandaGene getMainGene();
+
+ PandaGene getHiddenGene();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ParrotEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ParrotEntity.java
new file mode 100644
index 00000000..6cd76f1a
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ParrotEntity.java
@@ -0,0 +1,65 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.TameableAnimal;
+import de.pxav.kelp.core.entity.util.ParrotType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ParrotEntity extends AnimalEntity, TameableAnimal {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ParrotEntity create(KelpLocation location) {
+ return (ParrotEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ParrotEntity from(Entity entity) {
+ return (ParrotEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PARROT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ ParrotEntity setParrotType(ParrotType parrotType);
+
+ ParrotType getParrotType();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PhantomEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PhantomEntity.java
new file mode 100644
index 00000000..d170a86d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PhantomEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MobileEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PhantomEntity extends MobileEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PhantomEntity create(KelpLocation location) {
+ return (PhantomEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PhantomEntity from(Entity entity) {
+ return (PhantomEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PHANTOM;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getPhantomSize();
+
+ PhantomEntity setPhantomSize(int phantomSize);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PigEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PigEntity.java
new file mode 100644
index 00000000..7153b448
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PigEntity.java
@@ -0,0 +1,66 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.type.general.VehicleEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Pig;
+
+public interface PigEntity extends AnimalEntity, BreedableAnimalEntity, VehicleEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PigEntity create(KelpLocation location) {
+ return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PigEntity from(Entity entity) {
+ return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PIG;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean hasSaddle();
+
+ PigEntity setSaddled(boolean saddled);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PigZombie.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PigZombie.java
new file mode 100644
index 00000000..79360d20
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PigZombie.java
@@ -0,0 +1,72 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PigZombie extends ZombieEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PigZombie create(KelpLocation location) {
+ return (PigZombie) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PigZombie from(Entity entity) {
+ return (PigZombie) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PIG_ZOMBIE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getAnger();
+
+ void setAnger(int anger);
+
+ void setAngry(boolean angry);
+
+ boolean isAngry();
+
+ boolean isConverting();
+
+ int getConversionTime();
+
+ void setConversionTime(int conversionTime);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PiglinBruteEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PiglinBruteEntity.java
new file mode 100644
index 00000000..8dbadbdd
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PiglinBruteEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractPiglin;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PiglinBruteEntity extends AbstractPiglin {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PiglinBruteEntity create(KelpLocation location) {
+ return (PiglinBruteEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PiglinBruteEntity from(Entity entity) {
+ return (PiglinBruteEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PIGLIN_BRUTE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PiglinEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PiglinEntity.java
new file mode 100644
index 00000000..14ca9540
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PiglinEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractPiglin;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PiglinEntity extends AbstractPiglin {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PiglinEntity create(KelpLocation location) {
+ return (PiglinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PiglinEntity from(Entity entity) {
+ return (PiglinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PIGLIN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isAbleToHunt();
+
+ PiglinEntity setAbleToHunt(boolean ableToHunt);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PillagerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PillagerEntity.java
new file mode 100644
index 00000000..accc3a6f
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PillagerEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.IllagerEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PillagerEntity extends IllagerEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PillagerEntity create(KelpLocation location) {
+ return (PillagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PillagerEntity from(Entity entity) {
+ return (PillagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PILLAGER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PolarBear.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PolarBear.java
new file mode 100644
index 00000000..68c61e76
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PolarBear.java
@@ -0,0 +1,60 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PolarBear extends AnimalEntity, BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PolarBear create(KelpLocation location) {
+ return (PolarBear) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PolarBear from(Entity entity) {
+ return (PolarBear) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.POLAR_BEAR;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PoweredMinecart.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PoweredMinecart.java
new file mode 100644
index 00000000..bb817140
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PoweredMinecart.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PoweredMinecart extends MinecartEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PoweredMinecart create(KelpLocation location) {
+ return (PoweredMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PoweredMinecart from(Entity entity) {
+ return (PoweredMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MINECART_FURNACE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getFuelTicks();
+
+ PoweredMinecart setFuelTicks(int fuelTicks);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PrimedTntEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PrimedTntEntity.java
new file mode 100644
index 00000000..7a89ac9f
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PrimedTntEntity.java
@@ -0,0 +1,69 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.ExplosiveEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.TNTPrimed;
+
+// explosive
+public interface PrimedTntEntity extends ExplosiveEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PrimedTntEntity create(KelpLocation location) {
+ return (PrimedTntEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PrimedTntEntity from(Entity entity) {
+ return (PrimedTntEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PRIMED_TNT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getFuseTicks();
+
+ PrimedTntEntity setFuseTicks(int fuseTicks);
+
+ KelpEntity> getSource();
+
+ PrimedTntEntity setSource(KelpEntity> sourceEntity);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/PufferfishEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/PufferfishEntity.java
new file mode 100644
index 00000000..351aa4d9
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/PufferfishEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.WaterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface PufferfishEntity extends WaterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static PufferfishEntity create(KelpLocation location) {
+ return (PufferfishEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static PufferfishEntity from(Entity entity) {
+ return (PufferfishEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.PUFFERFISH;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getPuffState();
+
+ PufferfishEntity setPuffState();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/RabbitEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/RabbitEntity.java
new file mode 100644
index 00000000..87e473a6
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/RabbitEntity.java
@@ -0,0 +1,65 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.util.RabbitType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface RabbitEntity extends AnimalEntity, BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static RabbitEntity create(KelpLocation location) {
+ return (RabbitEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static RabbitEntity from(Entity entity) {
+ return (RabbitEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.RABBIT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ RabbitType getRabbitType();
+
+ RabbitEntity setRabbitType(RabbitType rabbitType);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/RavagerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/RavagerEntity.java
new file mode 100644
index 00000000..8cdaa676
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/RavagerEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.RaidingEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface RavagerEntity extends RaidingEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static RavagerEntity create(KelpLocation location) {
+ return (RavagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static RavagerEntity from(Entity entity) {
+ return (RavagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.RAVAGER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/RideableMinecart.java b/core/src/main/java/de/pxav/kelp/core/entity/type/RideableMinecart.java
new file mode 100644
index 00000000..4de1da77
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/RideableMinecart.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface RideableMinecart extends MinecartEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static RideableMinecart create(KelpLocation location) {
+ return (RideableMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static RideableMinecart from(Entity entity) {
+ return (RideableMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MINECART;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SalmonEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SalmonEntity.java
new file mode 100644
index 00000000..433be0cc
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SalmonEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.WaterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SalmonEntity extends WaterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SalmonEntity create(KelpLocation location) {
+ return (SalmonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SalmonEntity from(Entity entity) {
+ return (SalmonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SALMON;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SheepEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SheepEntity.java
new file mode 100644
index 00000000..c07cc926
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SheepEntity.java
@@ -0,0 +1,65 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Sheep;
+
+public interface SheepEntity extends AnimalEntity, BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SheepEntity create(KelpLocation location) {
+ return (SheepEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SheepEntity from(Entity entity) {
+ return (SheepEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SHEEP;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isSheared();
+
+ SheepEntity setSheared(boolean sheared);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ShulkerBulletEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ShulkerBulletEntity.java
new file mode 100644
index 00000000..16c7d41f
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ShulkerBulletEntity.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.ShulkerBullet;
+
+public interface ShulkerBulletEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ShulkerBulletEntity create(KelpLocation location) {
+ return (ShulkerBulletEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ShulkerBulletEntity from(Entity entity) {
+ return (ShulkerBulletEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SHULKER_BULLET;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ KelpEntity> getTarget();
+
+ void setTarget(KelpEntity> target);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ShulkerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ShulkerEntity.java
new file mode 100644
index 00000000..adacf734
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ShulkerEntity.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.GolemEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ShulkerEntity extends GolemEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ShulkerEntity create(KelpLocation location) {
+ return (ShulkerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ShulkerEntity from(Entity entity) {
+ return (ShulkerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SHULKER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ Color getDyeColor();
+
+ ShulkerEntity setDyeColor();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SilverfishEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SilverfishEntity.java
new file mode 100644
index 00000000..df166f00
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SilverfishEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SilverfishEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SilverfishEntity create(KelpLocation location) {
+ return (SilverfishEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SilverfishEntity from(Entity entity) {
+ return (SilverfishEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ZOGLIN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SkeletonEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SkeletonEntity.java
new file mode 100644
index 00000000..3a9d814c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SkeletonEntity.java
@@ -0,0 +1,72 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Difficulty;
+import org.bukkit.entity.Entity;
+
+public interface SkeletonEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SkeletonEntity create(KelpLocation location) {
+ return (SkeletonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SkeletonEntity from(Entity entity) {
+ return (SkeletonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SKELETON;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ //todo maybe check how many arrows left if possible in minecraft
+
+ @Override
+ default int getMaximumSpawnLightLevel() {
+ return 7;
+ }
+
+ @Override
+ default double getAttackDamage(Difficulty difficulty) {
+ return 0;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SkeletonHorseEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SkeletonHorseEntity.java
new file mode 100644
index 00000000..026f1472
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SkeletonHorseEntity.java
@@ -0,0 +1,62 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractHorseEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftAnimals;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftHanging;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.SkeletonHorse;
+
+public interface SkeletonHorseEntity extends AbstractHorseEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SkeletonHorseEntity create(KelpLocation location) {
+ return (SkeletonHorseEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SkeletonHorseEntity from(Entity entity) {
+ return (SkeletonHorseEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SKELETON_HORSE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SlimeEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SlimeEntity.java
new file mode 100644
index 00000000..f996177b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SlimeEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MobileEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SlimeEntity extends MobileEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SlimeEntity create(KelpLocation location) {
+ return (SlimeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SlimeEntity from(Entity entity) {
+ return (SlimeEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SLIME;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getSlimeSize();
+
+ SlimeEntity setSlimeSize(int slimeSize);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SmallFireballEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SmallFireballEntity.java
new file mode 100644
index 00000000..e5737091
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SmallFireballEntity.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SmallFireballEntity extends ThrownFireballEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SmallFireballEntity create(KelpLocation location) {
+ return (SmallFireballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SmallFireballEntity from(Entity entity) {
+ return (SmallFireballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SMALL_FIREBALL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SnowmanEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SnowmanEntity.java
new file mode 100644
index 00000000..0a56597d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SnowmanEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.GolemEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SnowmanEntity extends GolemEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SnowmanEntity create(KelpLocation location) {
+ return (SnowmanEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SnowmanEntity from(Entity entity) {
+ return (SnowmanEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SNOWMAN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean hasPumpkin();
+
+ SnowmanEntity setPumpkinHead(boolean pumpkinHead);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SpawnerMinecart.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SpawnerMinecart.java
new file mode 100644
index 00000000..e03db823
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SpawnerMinecart.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SpawnerMinecart extends MinecartEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SpawnerMinecart create(KelpLocation location) {
+ return (SpawnerMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SpawnerMinecart from(Entity entity) {
+ return (SpawnerMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MINECART_MOB_SPAWNER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SpectralArrowEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SpectralArrowEntity.java
new file mode 100644
index 00000000..482539f5
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SpectralArrowEntity.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractArrowEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+// subtype of abstract arrow
+public interface SpectralArrowEntity extends AbstractArrowEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SpectralArrowEntity create(KelpLocation location) {
+ return (SpectralArrowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SpectralArrowEntity from(Entity entity) {
+ return (SpectralArrowEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SPECTRAL_ARROW;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getGlowingTicks();
+
+ SpectralArrowEntity setGlowingTicks(int durationInTicks);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SpiderEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SpiderEntity.java
new file mode 100644
index 00000000..24495643
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SpiderEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SpiderEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SpiderEntity create(KelpLocation location) {
+ return (SpiderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SpiderEntity from(Entity entity) {
+ return (SpiderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SPIDER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/SquidEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/SquidEntity.java
new file mode 100644
index 00000000..439e73e9
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/SquidEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.WaterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface SquidEntity extends WaterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static SquidEntity create(KelpLocation location) {
+ return (SquidEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static SquidEntity from(Entity entity) {
+ return (SquidEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SQUID;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/StorageMinecart.java b/core/src/main/java/de/pxav/kelp/core/entity/type/StorageMinecart.java
new file mode 100644
index 00000000..4c6dd169
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/StorageMinecart.java
@@ -0,0 +1,62 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MinecartEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.type.StorageInventory;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface StorageMinecart extends MinecartEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static StorageMinecart create(KelpLocation location) {
+ return (StorageMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static StorageMinecart from(Entity entity) {
+ return (StorageMinecart) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.MINECART_CHEST;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ StorageInventory> getInventory();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/StraySkeletonEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/StraySkeletonEntity.java
new file mode 100644
index 00000000..13b4c002
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/StraySkeletonEntity.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface StraySkeletonEntity extends SkeletonEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static StraySkeletonEntity create(KelpLocation location) {
+ return (StraySkeletonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static StraySkeletonEntity from(Entity entity) {
+ return (StraySkeletonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.STRAY_SKELETON;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/StriderEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/StriderEntity.java
new file mode 100644
index 00000000..1c9c4d2d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/StriderEntity.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface StriderEntity extends AnimalEntity, BreedableAnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static StriderEntity create(KelpLocation location) {
+ return (StriderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static StriderEntity from(Entity entity) {
+ return (StriderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.STRIDER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isShivering();
+
+ StriderEntity setShivering(boolean shivering);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownChickenEggEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownChickenEggEntity.java
new file mode 100644
index 00000000..65c6587f
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownChickenEggEntity.java
@@ -0,0 +1,74 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.common.MathUtils;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ThrownChickenEggEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownChickenEggEntity create(KelpLocation location) {
+ return (ThrownChickenEggEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownChickenEggEntity from(Entity entity) {
+ return (ThrownChickenEggEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.CHICKEN_EGG;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ default boolean spawnsChicken() {
+ return MathUtils.perCentChance(0.125);
+ }
+
+ default int getSpawnedChickens() {
+ if (spawnsChicken()) {
+ if (MathUtils.perCentChance(0.03125)) {
+ return 4;
+ }
+ return 1;
+ }
+ return 0;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownEnderPearlEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownEnderPearlEntity.java
new file mode 100644
index 00000000..c1d71fb6
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownEnderPearlEntity.java
@@ -0,0 +1,60 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.EnderPearl;
+import org.bukkit.entity.Entity;
+
+public interface ThrownEnderPearlEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownEnderPearlEntity create(KelpLocation location) {
+ return (ThrownEnderPearlEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownEnderPearlEntity from(Entity entity) {
+ return (ThrownEnderPearlEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ENDER_PEARL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownExperienceBottleEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownExperienceBottleEntity.java
new file mode 100644
index 00000000..3b682899
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownExperienceBottleEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ThrownExperienceBottleEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownExperienceBottleEntity create(KelpLocation location) {
+ return (ThrownExperienceBottleEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownExperienceBottleEntity from(Entity entity) {
+ return (ThrownExperienceBottleEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.THROWN_EXP_BOTTLE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownFireballEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownFireballEntity.java
new file mode 100644
index 00000000..97ab424b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownFireballEntity.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.ExplosiveEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+import org.bukkit.util.Vector;
+
+public interface ThrownFireballEntity extends ExplosiveEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownFireballEntity create(KelpLocation location) {
+ return (ThrownFireballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownFireballEntity from(Entity entity) {
+ return (ThrownFireballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.FIREBALL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ Vector getDirection();
+
+ ThrownFireballEntity setDirection(Vector vector);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownPotionEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownPotionEntity.java
new file mode 100644
index 00000000..a09c7fe8
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownPotionEntity.java
@@ -0,0 +1,69 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.item.KelpItem;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+import java.util.Collection;
+
+public interface ThrownPotionEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownPotionEntity create(KelpLocation location) {
+ return (ThrownPotionEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownPotionEntity from(Entity entity) {
+ return (ThrownPotionEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SPLASH_POTION;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ Collection getPotionEffects();
+
+ KelpItem getItem();
+
+ ThrownPotionEntity setItem(KelpItem item);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownSnowballEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownSnowballEntity.java
new file mode 100644
index 00000000..c9b13545
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownSnowballEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ThrownSnowballEntity extends KelpProjectile {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownSnowballEntity create(KelpLocation location) {
+ return (ThrownSnowballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownSnowballEntity from(Entity entity) {
+ return (ThrownSnowballEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.SNOWBALL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownTridentEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownTridentEntity.java
new file mode 100644
index 00000000..dc37929c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownTridentEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractArrowEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ThrownTridentEntity extends AbstractArrowEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownTridentEntity create(KelpLocation location) {
+ return (ThrownTridentEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownTridentEntity from(Entity entity) {
+ return (ThrownTridentEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.TRIDENT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownWitherSkullEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownWitherSkullEntity.java
new file mode 100644
index 00000000..3f9ee145
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ThrownWitherSkullEntity.java
@@ -0,0 +1,62 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ThrownWitherSkullEntity extends ThrownFireballEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ThrownWitherSkullEntity create(KelpLocation location) {
+ return (ThrownWitherSkullEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ThrownWitherSkullEntity from(Entity entity) {
+ return (ThrownWitherSkullEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.WITHER_SKULL;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isCharged();
+
+ ThrownWitherSkullEntity setCharged(boolean charged);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/TraderLlamaEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/TraderLlamaEntity.java
new file mode 100644
index 00000000..da0a132d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/TraderLlamaEntity.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface TraderLlamaEntity extends LlamaEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static TraderLlamaEntity create(KelpLocation location) {
+ return (TraderLlamaEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static TraderLlamaEntity from(Entity entity) {
+ return (TraderLlamaEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.TRADER_LLAMA;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/TropicalFishEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/TropicalFishEntity.java
new file mode 100644
index 00000000..6f7710d9
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/TropicalFishEntity.java
@@ -0,0 +1,70 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractFishEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface TropicalFishEntity extends AbstractFishEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static TropicalFishEntity create(KelpLocation location) {
+ return (TropicalFishEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static TropicalFishEntity from(Entity entity) {
+ return (TropicalFishEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.TROPICAL_FISH;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ // TODO: Add patterns!
+
+ Color getBodyDyeColor();
+
+ Color getPatternDyeColor();
+
+ TropicalFishEntity setPatternDyeColor();
+
+ TropicalFishEntity setBodyDyeColor();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/TurtleEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/TurtleEntity.java
new file mode 100644
index 00000000..87f1f437
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/TurtleEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface TurtleEntity extends AnimalEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static TurtleEntity create(KelpLocation location) {
+ return (TurtleEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static TurtleEntity from(Entity entity) {
+ return (TurtleEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.TURTLE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/VexEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/VexEntity.java
new file mode 100644
index 00000000..2896e36c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/VexEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface VexEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static VexEntity create(KelpLocation location) {
+ return (VexEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static VexEntity from(Entity entity) {
+ return (VexEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ZOGLIN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isCharging();
+
+ VexEntity setCharging(boolean charging);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/VillagerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/VillagerEntity.java
new file mode 100644
index 00000000..b990a699
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/VillagerEntity.java
@@ -0,0 +1,77 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractVillager;
+import de.pxav.kelp.core.entity.util.VillagerProfession;
+import de.pxav.kelp.core.entity.util.VillagerType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface VillagerEntity extends AbstractVillager {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static VillagerEntity create(KelpLocation location) {
+ return (VillagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static VillagerEntity from(Entity entity) {
+ return (VillagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.VILLAGER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ VillagerProfession getProfession();
+
+ VillagerEntity setProfession(VillagerProfession profession);
+
+ VillagerType getVillagerType();
+
+ VillagerEntity setVillagerType(VillagerType villagerType);
+
+ int getVillagerExperience();
+
+ int getVillagerLevel();
+
+ VillagerEntity setVillagerLevel(int villagerLevel);
+
+ VillagerEntity setVillagerExperience();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/VindicatorEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/VindicatorEntity.java
new file mode 100644
index 00000000..a38186f7
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/VindicatorEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.IllagerEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface VindicatorEntity extends IllagerEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static VindicatorEntity create(KelpLocation location) {
+ return (VindicatorEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static VindicatorEntity from(Entity entity) {
+ return (VindicatorEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.VINDICATOR;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/WanderingTraderEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/WanderingTraderEntity.java
new file mode 100644
index 00000000..35c53d18
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/WanderingTraderEntity.java
@@ -0,0 +1,63 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractVillager;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface WanderingTraderEntity extends AbstractVillager {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static WanderingTraderEntity create(KelpLocation location) {
+ return (WanderingTraderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static WanderingTraderEntity from(Entity entity) {
+ return (WanderingTraderEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.WANDERING_TRADER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ int getDespawnDelay();
+
+ WanderingTraderEntity setDespawnDelay(int despawnDelay);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/WitchEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/WitchEntity.java
new file mode 100644
index 00000000..141be594
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/WitchEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface WitchEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static WitchEntity create(KelpLocation location) {
+ return (WitchEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static WitchEntity from(Entity entity) {
+ return (WitchEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.WITCH;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/WitherEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/WitherEntity.java
new file mode 100644
index 00000000..a5c8c1af
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/WitherEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface WitherEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static WitherEntity create(KelpLocation location) {
+ return (WitherEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static WitherEntity from(Entity entity) {
+ return (WitherEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.WITHER;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/WitherSkeletonEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/WitherSkeletonEntity.java
new file mode 100644
index 00000000..2e5f2950
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/WitherSkeletonEntity.java
@@ -0,0 +1,58 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface WitherSkeletonEntity extends SkeletonEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static WitherSkeletonEntity create(KelpLocation location) {
+ return (WitherSkeletonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static WitherSkeletonEntity from(Entity entity) {
+ return (WitherSkeletonEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.WITHER_SKELETON;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/WolfEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/WolfEntity.java
new file mode 100644
index 00000000..30151237
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/WolfEntity.java
@@ -0,0 +1,69 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AnimalEntity;
+import de.pxav.kelp.core.entity.type.general.TameableAnimal;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface WolfEntity extends AnimalEntity, TameableAnimal {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static WolfEntity create(KelpLocation location) {
+ return (WolfEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static WolfEntity from(Entity entity) {
+ return (WolfEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.WOLF;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+ boolean isAngry();
+
+ WolfEntity setAngry(boolean angry);
+
+ Color getCollarDyeColor();
+
+ WolfEntity setCollarDyeColor(Color color);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ZoglinEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ZoglinEntity.java
new file mode 100644
index 00000000..8e2571f3
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ZoglinEntity.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ZoglinEntity extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ZoglinEntity create(KelpLocation location) {
+ return (ZoglinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ZoglinEntity from(Entity entity) {
+ return (ZoglinEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ZOGLIN;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieEntity.java
index 55f4c2f9..df5b3235 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieEntity.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieEntity.java
@@ -1,34 +1,81 @@
package de.pxav.kelp.core.entity.type;
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityFactory;
import de.pxav.kelp.core.entity.KelpEntityType;
-import de.pxav.kelp.core.entity.LivingKelpEntity;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
-import de.pxav.kelp.core.entity.version.LivingEntityVersionTemplate;
-import org.bukkit.Location;
-import org.bukkit.entity.LivingEntity;
-
-/**
- * A class description goes here.
- *
- * @author pxav
- */
-public class ZombieEntity extends LivingKelpEntity {
-
- private boolean isBaby = false;
-
- public ZombieEntity() {}
-
- public ZombieEntity(EntityVersionTemplate entityVersionTemplate, LivingEntityVersionTemplate livingEntityVersionTemplate, LivingEntity livingEntity, Object entity, int entityId, Location location, boolean isBaby) {
- super(entity, KelpEntityType.ZOMBIE, location, entityId, entityVersionTemplate, livingEntityVersionTemplate, livingEntity);
- this.isBaby = isBaby;
+import de.pxav.kelp.core.entity.type.general.AgeableEntity;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.Difficulty;
+import org.bukkit.entity.Entity;
+
+public interface ZombieEntity extends AgeableEntity, MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ZombieEntity create(KelpLocation location) {
+ return (ZombieEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ZombieEntity from(Entity entity) {
+ return (ZombieEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ZOMBIE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
}
- public boolean isBaby() {
- return isBaby;
+ @Override
+ default double getAttackDamage(Difficulty difficulty) {
+ if (difficulty == Difficulty.EASY) {
+ return 4;
+ }
+ if (difficulty == Difficulty.NORMAL) {
+ return 6;
+ }
+ if (difficulty == Difficulty.HARD) {
+ return 8;
+ }
+ return 0;
}
- public void setBaby(boolean baby) {
- isBaby = baby;
+ @Override
+ default int getMaximumSpawnLightLevel() {
+ return 7;
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieGiant.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieGiant.java
new file mode 100644
index 00000000..5d769029
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieGiant.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.MonsterEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ZombieGiant extends MonsterEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ZombieGiant create(KelpLocation location) {
+ return (ZombieGiant) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return The kelp instance of the given bukkit entity.
+ */
+ static ZombieGiant from(Entity entity) {
+ return (ZombieGiant) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ZOMBIE_GIANT;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieHorse.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieHorse.java
new file mode 100644
index 00000000..d0d0fbc5
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieHorse.java
@@ -0,0 +1,59 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.type.general.AbstractHorseEntity;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+public interface ZombieHorse extends AbstractHorseEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ZombieHorse create(KelpLocation location) {
+ return (ZombieHorse) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(getEntityType(), location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static ZombieHorse from(Entity entity) {
+ return (ZombieHorse) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ static KelpEntityType getEntityType() {
+ return KelpEntityType.ZOMBIE_HORSE;
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return getEntityType();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieVillagerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieVillagerEntity.java
new file mode 100644
index 00000000..bab03f86
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/ZombieVillagerEntity.java
@@ -0,0 +1,69 @@
+package de.pxav.kelp.core.entity.type;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.util.VillagerProfession;
+import de.pxav.kelp.core.entity.util.VillagerType;
+import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.entity.Entity;
+
+// sub type of zombie
+public interface ZombieVillagerEntity extends ZombieEntity {
+
+ /**
+ * Creates a new entity of this type at the given location.
+ *
+ * While this creates a new instance, it won't actually spawn the entity.
+ * You can first do some modifications on it and then call the
+ * {@link KelpEntity#spawn()} method.
+ *
+ * If you don't want to create a new entity, but just a new kelp
+ * entity instance based of an existing bukkit entity, you can use
+ * {@link #from(Entity)} instead.
+ *
+ * @param location The location, where the entity should be spawned later.
+ * @return A new instance of a sheep entity.
+ */
+ static ZombieVillagerEntity create(KelpLocation location) {
+ return (ZombieVillagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .newKelpEntity(KelpEntityType.ZOMBIE_VILLAGER, location.getBukkitLocation());
+ }
+
+ /**
+ * Takes a bukkit entity and converts it to a kelp entity of the same type.
+ *
+ * This can be used if you are for example handling an event that returns a bukkit entity,
+ * but you want to use a kelp entity for your operations. You can also use
+ * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
+ * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
+ * but this way you don't have to cast your entity to the specific type
+ * manually.
+ *
+ * @param entity The entity you want to convert.
+ * @return
+ */
+ static ZombieVillagerEntity from(Entity entity) {
+ return (ZombieVillagerEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class)
+ .getKelpEntity(entity);
+ }
+
+ @Override
+ default KelpEntityType getType() {
+ return KelpEntityType.ZOMBIE_VILLAGER;
+ }
+
+ ZombieVillagerEntity setConversionTime(int conversionTime);
+
+ ZombieVillagerEntity setVillagerType(VillagerType villagerType);
+
+ ZombieVillagerEntity setVillagerProfession(VillagerProfession villagerProfession);
+
+ int getConversionTime();
+
+ VillagerType getVillagerType();
+
+ VillagerProfession getVillagerProfession();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractArrowEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractArrowEntity.java
new file mode 100644
index 00000000..42382128
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractArrowEntity.java
@@ -0,0 +1,66 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.util.ArrowPickupStatus;
+import de.pxav.kelp.core.player.KelpPlayer;
+import de.pxav.kelp.core.world.KelpBlock;
+import org.bukkit.GameMode;
+
+public interface AbstractArrowEntity> extends KelpProjectile {
+
+ KelpBlock getAttachedBlock();
+
+ double getBaseDamage();
+
+ // equivalent to knockback enchantment level
+ int getKnockbackLevel();
+
+ ArrowPickupStatus getPickupStatus();
+
+ default boolean canPickup(KelpEntity> entity) {
+ if (!(entity instanceof KelpPlayer)) {
+ return false;
+ }
+
+ if (getPickupStatus() == ArrowPickupStatus.ALWAYS_FORBIDDEN) {
+ return false;
+ }
+
+ if (getPickupStatus() == ArrowPickupStatus.CREATIVE_ONLY) {
+ KelpPlayer player = KelpPlayer.from(entity.getUUID());
+ return player.getGameMode() == GameMode.CREATIVE;
+ }
+
+ return true;
+ }
+
+ int getPierceLevel();
+
+ boolean isCritical();
+
+ boolean isInBlock();
+
+ boolean isShotFromCrossbow();
+
+ default boolean isShotFromNormalBow() {
+ return !isShotFromCrossbow();
+ }
+
+ T setPickupStatus(ArrowPickupStatus pickupStatus);
+
+ T setCritical(boolean critical);
+
+ T setDamage(double damage);
+
+ T setKnockbackLevel(int knockbackLevel);
+
+ T setPierceLevel(int pierceLevel);
+
+ T setShotFromCrossbow(boolean fromCrossbow);
+
+ default T setShowFromNormalBow(boolean fromNormalBow) {
+ setShotFromCrossbow(!fromNormalBow);
+ return (T) this;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractFishEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractFishEntity.java
new file mode 100644
index 00000000..3909960e
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractFishEntity.java
@@ -0,0 +1,4 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface AbstractFishEntity> extends WaterEntity {
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractHorseEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractHorseEntity.java
new file mode 100644
index 00000000..08253408
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractHorseEntity.java
@@ -0,0 +1,21 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.inventory.type.AbstractHorseInventory;
+
+public interface AbstractHorseEntity> extends TameableAnimal {
+
+ int getDomestication();
+
+ AbstractHorseInventory> getInventory();
+
+ double getJumpStrength();
+
+ int getMaximumDomestication();
+
+ T setDomestication(int domesticationLevel);
+
+ T setJumpStrength(double jumpStrength);
+
+ T setMaximumDomestication(int maximumDomestication);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractPiglin.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractPiglin.java
new file mode 100644
index 00000000..2afaa24b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractPiglin.java
@@ -0,0 +1,17 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import org.bukkit.entity.PiglinAbstract;
+
+public interface AbstractPiglin> extends AgeableEntity, MonsterEntity {
+
+ boolean isImmuneToZombification();
+
+ void setImmuneToZombification(boolean immuneToZombification);
+
+ int getConversionTime();
+
+ void setConversionTime(int conversionTime);
+
+ boolean isConverting();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractVillager.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractVillager.java
new file mode 100644
index 00000000..bdce3017
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AbstractVillager.java
@@ -0,0 +1,9 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.inventory.type.StorageInventory;
+
+public interface AbstractVillager> extends HumanEntity {
+
+ StorageInventory> getStorageInventory();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/AgeableEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AgeableEntity.java
new file mode 100644
index 00000000..e49a99b5
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AgeableEntity.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface AgeableEntity> extends MobileEntity {
+
+ boolean isAgeLocked();
+
+ T setAgeLocked(boolean ageLocked);
+
+ default T makeBaby() {
+ setBaby(true);
+ return (T) this;
+ }
+
+ T setBaby(boolean baby);
+
+ default T setAdult(boolean adult) {
+ setBaby(!adult);
+ return (T) this;
+ }
+
+ default T makeAdult() {
+ setAdult(true);
+ return (T) this;
+ }
+
+ default boolean isAdult() {
+ return !isBaby();
+ }
+
+ boolean isBaby();
+
+ T setAge(int age);
+
+ default T toggleMaxAge() {
+ if (isBaby()) {
+ makeAdult();
+ } else {
+ makeBaby();
+ }
+ return (T) this;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/AnimalEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AnimalEntity.java
new file mode 100644
index 00000000..351cb1db
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/AnimalEntity.java
@@ -0,0 +1,19 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+
+public interface AnimalEntity> extends MobileEntity {
+
+ boolean isInLove();
+
+ T setInLove(boolean inLove);
+
+ KelpEntity> getBreeder();
+
+ T setBreeder(KelpEntity> breeder);
+
+ int getLoveModeTicks();
+
+ T setLoveModeTicks(int loveModeTicks);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/BreedableAnimalEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/BreedableAnimalEntity.java
new file mode 100644
index 00000000..61869211
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/BreedableAnimalEntity.java
@@ -0,0 +1,9 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface BreedableAnimalEntity> extends AnimalEntity {
+
+ boolean canBreed();
+
+ T setBreedable(boolean breedable);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/ChestedHorse.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/ChestedHorse.java
new file mode 100644
index 00000000..8ae2a8de
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/ChestedHorse.java
@@ -0,0 +1,9 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface ChestedHorse> extends AbstractHorseEntity {
+
+ boolean isCarryingChest();
+
+ T setCarryingChest(boolean carryingChest);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/DamageableEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/DamageableEntity.java
new file mode 100644
index 00000000..f0cd1004
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/DamageableEntity.java
@@ -0,0 +1,21 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+
+public interface DamageableEntity> extends KelpEntity {
+
+ T damage(double damage);
+
+ T damage(double damage, KelpEntity> source);
+
+ double getAbsorptionAmount();
+
+ T setAbsorptionAmount(double absorptionAmount);
+
+ double getHealth();
+
+ double getMaxHealth();
+
+ T setHealth(double health);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/ExplosiveEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/ExplosiveEntity.java
new file mode 100644
index 00000000..bea2ac0b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/ExplosiveEntity.java
@@ -0,0 +1,31 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.world.util.ExplosionPower;
+
+public interface ExplosiveEntity> extends KelpEntity {
+
+ ExplosionPower getExplosionPower();
+
+ T setExplosionPower(ExplosionPower power);
+
+ boolean createsFire();
+
+ T canCreateFire(boolean create);
+
+ default T enableFire() {
+ canCreateFire(true);
+ return (T) this;
+ }
+
+ default T disableFire() {
+ canCreateFire(false);
+ return (T) this;
+ }
+
+ default T disableExplosion() {
+ setExplosionPower(ExplosionPower.NO_EXPLOSION);
+ return (T) this;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/GolemEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/GolemEntity.java
new file mode 100644
index 00000000..e1bc5a1b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/GolemEntity.java
@@ -0,0 +1,5 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface GolemEntity> extends MobileEntity {
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/HangingEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/HangingEntity.java
new file mode 100644
index 00000000..73aa3d54
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/HangingEntity.java
@@ -0,0 +1,15 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.world.KelpBlock;
+import de.pxav.kelp.core.world.util.KelpBlockFace;
+
+public interface HangingEntity> extends KelpEntity {
+
+ KelpBlockFace getAttachedFace();
+
+ KelpBlock getAttachedBlock();
+
+ T setFacingDirection(KelpBlockFace blockFace);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/HumanEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/HumanEntity.java
new file mode 100644
index 00000000..2205f03d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/HumanEntity.java
@@ -0,0 +1,29 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import de.pxav.kelp.core.world.KelpLocation;
+import org.bukkit.GameMode;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftHumanEntity;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftVehicle;
+
+public interface HumanEntity> extends LivingKelpEntity {
+
+ // TODO: INVENTORIES
+
+ GameMode getGameMode();
+
+ T setGameMode(GameMode gameMode);
+
+ // location of bed the player is currently sleeping in null if not sleeping
+ KelpLocation getCurrentBedLocation();
+
+ int getExpToLevel();
+
+ // not set spawn loc
+ T wakeUp();
+
+ T wakeUpAndSetSpawnLocation();
+
+ T sleep(KelpLocation bedLocation);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/IllagerEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/IllagerEntity.java
new file mode 100644
index 00000000..d5d9bee1
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/IllagerEntity.java
@@ -0,0 +1,4 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface IllagerEntity> extends RaidingEntity {
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/KelpProjectile.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/KelpProjectile.java
new file mode 100644
index 00000000..3eedc948
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/KelpProjectile.java
@@ -0,0 +1,11 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+
+public interface KelpProjectile> extends KelpEntity {
+
+ T setLauncher(ProjectileLauncher> launcher);
+
+ ProjectileLauncher> getLauncher();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/MinecartEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/MinecartEntity.java
new file mode 100644
index 00000000..170f7171
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/MinecartEntity.java
@@ -0,0 +1,36 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.inventory.material.KelpMaterial;
+import org.bukkit.util.Vector;
+
+public interface MinecartEntity> extends VehicleEntity {
+
+ T setDamage(double damage);
+
+ double getDamage();
+
+ double getMaxSpeed();
+
+ T setMaxSpeed(double maxSpeed);
+
+ boolean isSlowWhenEmpty();
+
+ T setSlowWhenEmpty(boolean slowWhenEmpty);
+
+ Vector getFlyingVelocityModifier();
+
+ T setFlyingVelocityModifier(Vector flyingVelocityModifier);
+
+ Vector getDerailedVelocityModifier();
+
+ T setDerailedVelocityModifier(Vector derailedVelocityModifier);
+
+ T setDisplayBlock(KelpMaterial material);
+
+ KelpMaterial getDisplayBlock();
+
+ T setDisplayBlockOffset(int displayBlockOffset);
+
+ int getDisplayBlockOffset();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/MobileEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/MobileEntity.java
new file mode 100644
index 00000000..1bbcf7bb
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/MobileEntity.java
@@ -0,0 +1,15 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+
+public interface MobileEntity> extends LivingKelpEntity {
+
+ T setTarget(LivingKelpEntity> target);
+
+ LivingKelpEntity> getTarget();
+
+ boolean isAware();
+
+ T setAware(boolean aware);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/MonsterEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/MonsterEntity.java
new file mode 100644
index 00000000..5aea7540
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/MonsterEntity.java
@@ -0,0 +1,31 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Difficulty;
+import org.bukkit.World;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftCreature;
+import org.bukkit.craftbukkit.v1_16_R3.entity.CraftMob;
+
+public interface MonsterEntity> extends MobileEntity {
+
+ default int getMaximumSpawnLightLevel() {
+ return 0;
+ }
+
+ default boolean canSpawnInLightLevel(int lightLevel) {
+ return getMaximumSpawnLightLevel() >= lightLevel;
+ }
+
+ default double getAttackDamage(Difficulty difficulty) {
+ return 0;
+ }
+
+ default double getAttackDamage() {
+ World world = Bukkit.getWorld(getLocation().getWorldName());
+ if (world == null) {
+ return 0.0d;
+ }
+ return getAttackDamage(world.getDifficulty());
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/ProjectileLauncher.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/ProjectileLauncher.java
new file mode 100644
index 00000000..1bd8ca57
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/ProjectileLauncher.java
@@ -0,0 +1,7 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface ProjectileLauncher> {
+
+ T launchProjectile(KelpProjectile> projectileType);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/RaidingEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/RaidingEntity.java
new file mode 100644
index 00000000..d59015b7
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/RaidingEntity.java
@@ -0,0 +1,19 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.world.KelpBlock;
+
+public interface RaidingEntity> extends MonsterEntity {
+
+ KelpBlock getPatrolTarget();
+
+ T setPatrolTarget(KelpBlock patrolTarget);
+
+ boolean canJoinRaid();
+
+ boolean isPatrolLeader();
+
+ T setCanJoinRaid(boolean canJoinRaid);
+
+ T setPatrolLeader(boolean patrolLeader);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/SpellcastingEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/SpellcastingEntity.java
new file mode 100644
index 00000000..7c2b39ad
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/SpellcastingEntity.java
@@ -0,0 +1,11 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.util.SpellType;
+
+public interface SpellcastingEntity> extends IllagerEntity {
+
+ T setSpellType(SpellType spellType);
+
+ SpellType getSpellType();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/TameableAnimal.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/TameableAnimal.java
new file mode 100644
index 00000000..fff49fc4
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/TameableAnimal.java
@@ -0,0 +1,20 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+
+import java.util.UUID;
+
+public interface TameableAnimal> extends AnimalEntity {
+
+ T setTamed(boolean tamed);
+
+ boolean isTamed();
+
+ KelpEntity> getOwner();
+
+ UUID getOwnerUUID();
+
+ T setOwner(KelpEntity> owner);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/VehicleEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/VehicleEntity.java
new file mode 100644
index 00000000..48c57710
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/VehicleEntity.java
@@ -0,0 +1,12 @@
+package de.pxav.kelp.core.entity.type.general;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+import org.bukkit.util.Vector;
+
+public interface VehicleEntity> extends KelpEntity {
+
+ Vector getVehicleVelocity();
+
+ T setVehicleVelocity(Vector vehicleVelocity);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/general/WaterEntity.java b/core/src/main/java/de/pxav/kelp/core/entity/type/general/WaterEntity.java
new file mode 100644
index 00000000..d8655a1e
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/type/general/WaterEntity.java
@@ -0,0 +1,5 @@
+package de.pxav.kelp.core.entity.type.general;
+
+public interface WaterEntity> extends MobileEntity {
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/ArrowPickupStatus.java b/core/src/main/java/de/pxav/kelp/core/entity/util/ArrowPickupStatus.java
new file mode 100644
index 00000000..f78df743
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/ArrowPickupStatus.java
@@ -0,0 +1,9 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum ArrowPickupStatus {
+
+ ALWAYS_ALLOWED,
+ CREATIVE_ONLY,
+ ALWAYS_FORBIDDEN
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/CatType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/CatType.java
new file mode 100644
index 00000000..fe272fa9
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/CatType.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.util;
+
+import com.google.common.collect.Lists;
+import de.pxav.kelp.core.KelpServer;
+import de.pxav.kelp.core.version.KelpVersion;
+
+import java.util.Collections;
+import java.util.List;
+
+public enum CatType {
+
+ TABBY,
+ TUXEDO,
+ RED,
+ SIAMESE,
+ BRITISH_SHORTHAIR,
+ CALICO,
+ PERSIAN,
+ RAGDOLL,
+ WHITE,
+ JELLIE,
+ ALL_BLACK;
+
+ public static CatType randomCatType() {
+ List availableTypes = Lists.newArrayList();
+ availableTypes.add(CatType.ALL_BLACK);
+ availableTypes.add(CatType.RED);
+ availableTypes.add(CatType.SIAMESE);
+ if (KelpServer.getVersion().isHigherThanOrEqualTo(KelpVersion.MC_1_14_0)) {
+ availableTypes.add(CatType.TABBY);
+ availableTypes.add(CatType.TUXEDO);
+ availableTypes.add(CatType.BRITISH_SHORTHAIR);
+ availableTypes.add(CatType.CALICO);
+ availableTypes.add(CatType.PERSIAN);
+ availableTypes.add(CatType.RAGDOLL);
+ availableTypes.add(CatType.WHITE);
+ availableTypes.add(CatType.JELLIE);
+ }
+ Collections.shuffle(availableTypes);
+ return availableTypes.get(0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/FishHookState.java b/core/src/main/java/de/pxav/kelp/core/entity/util/FishHookState.java
new file mode 100644
index 00000000..54193628
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/FishHookState.java
@@ -0,0 +1,9 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum FishHookState {
+
+ UNHOOKED,
+ HOOKED_ENTITY,
+ BOBBING;
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/FoxType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/FoxType.java
new file mode 100644
index 00000000..6bb14a4d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/FoxType.java
@@ -0,0 +1,8 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum FoxType {
+
+ RED,
+ SNOW
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/HorseColor.java b/core/src/main/java/de/pxav/kelp/core/entity/util/HorseColor.java
new file mode 100644
index 00000000..a3d71635
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/HorseColor.java
@@ -0,0 +1,11 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum HorseColor {
+ WHITE,
+ CREAMY,
+ CHESTNUT,
+ BROWN,
+ BLACK,
+ GRAY,
+ DARK_BROWN;
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/HorseStyle.java b/core/src/main/java/de/pxav/kelp/core/entity/util/HorseStyle.java
new file mode 100644
index 00000000..d732c872
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/HorseStyle.java
@@ -0,0 +1,9 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum HorseStyle {
+ NONE,
+ WHITE,
+ WHITEFIELD,
+ WHITE_DOTS,
+ BLACK_DOTS;
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/type/ItemDropType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/ItemDropType.java
similarity index 94%
rename from core/src/main/java/de/pxav/kelp/core/entity/type/ItemDropType.java
rename to core/src/main/java/de/pxav/kelp/core/entity/util/ItemDropType.java
index b79bd5ff..059b13f8 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/type/ItemDropType.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/ItemDropType.java
@@ -1,4 +1,4 @@
-package de.pxav.kelp.core.entity.type;
+package de.pxav.kelp.core.entity.util;
/**
* This enum expresses how an item should be dropped.
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/LlamaColor.java b/core/src/main/java/de/pxav/kelp/core/entity/util/LlamaColor.java
new file mode 100644
index 00000000..926c0928
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/LlamaColor.java
@@ -0,0 +1,10 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum LlamaColor {
+
+ BROWN,
+ CREAMY,
+ LIGHT_GRAY,
+ WHITE
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/MushroomCowType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/MushroomCowType.java
new file mode 100644
index 00000000..ac42212b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/MushroomCowType.java
@@ -0,0 +1,8 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum MushroomCowType {
+
+ BROWN_MUSHROOMS,
+ RED_MUSHROOMS;
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/PaintingType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/PaintingType.java
new file mode 100644
index 00000000..7c1bc182
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/PaintingType.java
@@ -0,0 +1,64 @@
+package de.pxav.kelp.core.entity.util;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+public enum PaintingType {
+
+ KEBAB(1, 1),
+ AZTEC(1, 1),
+ ALBANIAN( 1, 1),
+ AZTEC2( 1, 1),
+ BOMB( 1, 1),
+ PLANT( 1, 1),
+ WASTELAND( 1, 1),
+ POOL(2, 1),
+ COURBET( 2, 1),
+ SEA(2, 1),
+ SUNSET(2, 1),
+ CREEBET(2, 1),
+ WANDERER(1, 2),
+ GRAHAM(1, 2),
+ MATCH(2, 2),
+ BUST(2, 2),
+ STAGE(2, 2),
+ VOID(2, 2),
+ SKULL_AND_ROSES(2, 2),
+ WITHER(2, 2),
+ FIGHTERS(4, 2),
+ POINTER(4, 4),
+ PIGSCENE(4, 4),
+ BURNING_SKULL( 4, 4),
+ SKELETON(4, 3),
+ DONKEY_KONG(4, 3)
+
+ ;
+
+ private int width;
+ private int height;
+
+ PaintingType(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public static PaintingType random() {
+ return values()[ThreadLocalRandom.current().nextInt(values().length)];
+ }
+
+ public static PaintingType random(int width, int height) {
+ PaintingType output = random();
+ while (output.width != width || output.height != height) {
+ output = random();
+ }
+ return output;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/PandaGene.java b/core/src/main/java/de/pxav/kelp/core/entity/util/PandaGene.java
new file mode 100644
index 00000000..61a7f0e6
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/PandaGene.java
@@ -0,0 +1,27 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum PandaGene {
+
+ AGGRESSIVE(true),
+ BROWN(false),
+ LAZY(true),
+ NORMAL(true),
+ PLAYFUL(true),
+ WEAK(false),
+ WORRIED(true);
+
+ private boolean isDominant;
+
+ PandaGene(boolean isDominant) {
+ this.isDominant = isDominant;
+ }
+
+ public boolean isDominant() {
+ return isDominant;
+ }
+
+ public boolean isRecessive() {
+ return !isDominant;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/ParrotType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/ParrotType.java
new file mode 100644
index 00000000..324be3b7
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/ParrotType.java
@@ -0,0 +1,11 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum ParrotType {
+
+ BLUE,
+ CYAN,
+ LIGHT_GRAY,
+ GREEN,
+ RED
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/RabbitType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/RabbitType.java
new file mode 100644
index 00000000..d695dcbc
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/RabbitType.java
@@ -0,0 +1,12 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum RabbitType {
+
+ BLACK,
+ BLACK_AND_WHITE,
+ BROWN,
+ BEIGE,
+ SALT_AND_PEPPER,
+ WHITE
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/SpellType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/SpellType.java
new file mode 100644
index 00000000..4e4bc9e0
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/SpellType.java
@@ -0,0 +1,12 @@
+package de.pxav.kelp.core.entity.util;
+
+public enum SpellType {
+
+ BLINDNESS,
+ DISAPPEAR,
+ FANGS,
+ NONE,
+ SUMMON_VEX,
+ WOLOLO
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/VillagerProfession.java b/core/src/main/java/de/pxav/kelp/core/entity/util/VillagerProfession.java
new file mode 100644
index 00000000..408034ca
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/VillagerProfession.java
@@ -0,0 +1,36 @@
+package de.pxav.kelp.core.entity.util;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.version.EntityConstantsVersionTemplate;
+
+public enum VillagerProfession {
+
+ NONE,
+ ARMORER,
+ BUTCHER,
+ CARTOGRAPHER,
+ CLERIC,
+ FARMER,
+ FISHERMAN,
+ FLETCHER,
+ LEATHER_WORKER,
+ LIBRARIAN,
+ MASON,
+ NITWIT,
+ SHEPHERD,
+ TOOL_SMITH,
+ WEAPON_SMITH;
+
+ public static VillagerProfession from(String bukkitProfession) {
+ return KelpPlugin.getInjector().getInstance(EntityConstantsVersionTemplate.class).getVillagerProfession(bukkitProfession);
+ }
+
+ public static String toBukkitProfession(VillagerProfession profession) {
+ return KelpPlugin.getInjector().getInstance(EntityConstantsVersionTemplate.class).getVillagerProfession(profession);
+ }
+
+ public String toBukkitProfession() {
+ return toBukkitProfession(this);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/VillagerType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/VillagerType.java
new file mode 100644
index 00000000..f44e880d
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/VillagerType.java
@@ -0,0 +1,29 @@
+package de.pxav.kelp.core.entity.util;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.version.EntityConstantsVersionTemplate;
+
+public enum VillagerType {
+
+ DESERT,
+ JUNGLE,
+ PLAINS,
+ SAVANNA,
+ SNOW,
+ SWAMP,
+ TAIGA,
+ NONE;
+
+ public static VillagerType from(String bukkitType) {
+ return KelpPlugin.getInjector().getInstance(EntityConstantsVersionTemplate.class).getVillagerType(bukkitType);
+ }
+
+ public static String toBukkitType(VillagerType type) {
+ return KelpPlugin.getInjector().getInstance(EntityConstantsVersionTemplate.class).getVillagerType(type);
+ }
+
+ public String toBukkitType() {
+ return toBukkitType(this);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpEffectRating.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpEffectRating.java
new file mode 100644
index 00000000..cd0a62c1
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpEffectRating.java
@@ -0,0 +1,45 @@
+package de.pxav.kelp.core.entity.util.potion;
+
+/**
+ * Describes whether a potion effect type is considered as positive,
+ * negative or mixed for the player who consumed it. This can help to
+ * determine which effects to get from lucky blocks for example.
+ *
+ * @author pxav
+ */
+public enum KelpEffectRating {
+
+ /**
+ * The effect is positive for the player. Examples would be
+ *
+ * - Strength
+ * - Regeneration
+ * - Absorption
+ * - Speed
+ * - Jump Boost
+ * - Instant healing
+ * - ...
+ *
+ */
+ POSITIVE,
+
+ /**
+ * The effect is negative for the player. Examples would be
+ *
+ * - Instant damage
+ * - Levitation
+ * - Poison
+ * - Nausea
+ * - ...
+ *
+ */
+ NEGATIVE,
+
+ /**
+ * The effect is positive, but comes at the cost of also having some
+ * negative effects. An example would be {@code Turtle master}, which reduces
+ * taken damage, but also slows you down.
+ */
+ MIXED
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpPotionEffect.java
new file mode 100644
index 00000000..e9bd5262
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpPotionEffect.java
@@ -0,0 +1,75 @@
+package de.pxav.kelp.core.entity.util.potion;
+
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.scheduler.TimeConverter;
+import org.bukkit.potion.PotionEffect;
+
+import java.util.concurrent.TimeUnit;
+
+public class KelpPotionEffect {
+
+ private int durationInTicks = 20 * 30;
+ private KelpPotionEffectType effectType = PotionEffects.ABSORPTION;
+ private boolean showParticles = true;
+ private int level = 1;
+
+ public static KelpPotionEffect from(PotionEffect bukkitEffect) {
+ return KelpPlugin.getInjector().getInstance(PotionVersionTemplate.class).fetchEffect(bukkitEffect);
+ }
+
+ public static KelpPotionEffect create() {
+ return new KelpPotionEffect();
+ }
+
+ public KelpPotionEffect duration(int value, TimeUnit timeUnit) {
+ this.durationInTicks = TimeConverter.getTicks(value, timeUnit);
+ return this;
+ }
+
+ public KelpPotionEffect durationTicks(int ticks) {
+ this.durationInTicks = ticks;
+ return this;
+ }
+
+ public KelpPotionEffect effectType(KelpPotionEffectType effectType) {
+ this.effectType = effectType;
+ return this;
+ }
+
+ public KelpPotionEffect showParticles(boolean show) {
+ this.showParticles = show;
+ return this;
+ }
+
+ public KelpPotionEffect hideParticles() {
+ this.showParticles = false;
+ return this;
+ }
+
+ public KelpPotionEffect showParticles() {
+ this.showParticles = true;
+ return this;
+ }
+
+ public KelpPotionEffect level(int level) {
+ this.level = level;
+ return this;
+ }
+
+ public int getDurationInTicks() {
+ return durationInTicks;
+ }
+
+ public KelpPotionEffectType getEffectType() {
+ return effectType;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public boolean particlesShown() {
+ return showParticles;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpPotionEffectType.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpPotionEffectType.java
new file mode 100644
index 00000000..2caf44a5
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/KelpPotionEffectType.java
@@ -0,0 +1,144 @@
+package de.pxav.kelp.core.entity.util.potion;
+
+import de.pxav.kelp.core.KelpServer;
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+import net.minecraft.server.v1_16_R3.CriterionTriggerLevitation;
+import net.minecraft.server.v1_16_R3.EntityShulkerBullet;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ * Represents an abstract potion effect a player can get by drinking a potion for example.
+ *
+ * Every potion effect type has to extend from this class to define the individual properties.
+ * But please note that it is currently not possible to add custom effects as they are hard coded
+ * into the minecraft client and are therefore not modifiable by the server, unlike
+ * {@link de.pxav.kelp.core.inventory.enchant.KelpEnchantment enchantments}. If this feature is ever added
+ * to minecraft, you will be able to create custom effects by extending this class as well.
+ *
+ * @author pxav
+ */
+public abstract class KelpPotionEffectType {
+
+ /**
+ * Gets the default name of the effect. Please note that the actual name displayed
+ * to the player may vary as this is dependent on the player's client language.
+ * Names returned by this method are always in english.
+ *
+ * @return
+ */
+ public abstract String getName();
+
+ /**
+ * Determines whether the effect is instant. An instant is an effect that applies
+ * instantly and does not last for several ticks. Once consumed, the player will
+ * have no long-term effects. An example would be the instant damage or instant healing
+ * potion by minecraft.
+ *
+ * @return {@code true} if the effect is instant.
+ */
+ public abstract boolean isInstant();
+
+ /**
+ * Gets the color used by the particles of this effect.
+ *
+ * @return The color of the particles used by this effect.
+ */
+ public abstract Color getColor();
+
+ /**
+ * Gets the rating of this effect. The rating gives information
+ * on whether getting this effect is considered positive, negative or mixed.
+ * Damage for example would be negative, while regeneration would be positive.
+ * Mixed effects would be effects that give you positive abilities at the cost
+ * of a slower speed for example.
+ *
+ * @return The effect rating of this potion effect.
+ */
+ public abstract KelpEffectRating getRating();
+
+ /**
+ * If custom potion effects are ever added to minecraft, this method can be used to
+ * define what should happen with an entity when the effect is applied to them.
+ *
+ * @param entity The entity who consumed the potion effect and to whom the effects should be applied.
+ * @param effectInfo Other information about the effect such as the duration or level. This also includes if
+ * particles should be displayed.
+ */
+ public void onConsume(LivingKelpEntity> entity, KelpPotionEffect effectInfo) {}
+
+ /**
+ * This method is triggered when the effect is removed from an entity.
+ * However, this only applies for effects that do not natively exist in the current
+ * server version and are therefore emulated by Kelp. This is therefore not triggered
+ * when the effect is removed via the official {@code /effect} command, but only
+ * when drinking milk or using the {@link LivingKelpEntity#removePotionEffect(KelpPotionEffectType)}
+ * method.
+ *
+ * @param entity The entity from which the effect has been removed.
+ */
+ public void onRemove(LivingKelpEntity> entity) {}
+
+ /**
+ * Checks if this potion effect is emulated for the current server version.
+ * So all potions that exist natively for the current version, will return
+ * false. Only potions that can be emulated without modifying too much of
+ * the gameplay experience will return {@code true} on this. If this returns
+ * true, you can apply the potion effect even if it does not exist on your
+ * server version.
+ *
+ * @return {@code true} if the potion effect type is emulated by Kelp.
+ */
+ public boolean isEmulated() {
+ return false;
+ }
+
+ /**
+ * Checks if the effect type can be removed from a player when
+ * they consume a bucket of milk.
+ *
+ * @return {@code true} if the effect can be removed with a bucket of milk.
+ */
+ public boolean isRemovableWithMilk() {
+ return true;
+ }
+
+ /**
+ * Checks if this effect is a default potion effect offered by minecraft/bukkit.
+ * As of now, every effect will return {@code true} on this as custom potion effects
+ * are not yet possible in minecraft.
+ *
+ * @return {@code true} if the effect is a default effect.
+ */
+ public final boolean isBukkitEffect() {
+ return isBukkitEffectUnsafe(KelpServer.getVersion());
+ }
+
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof KelpPotionEffectType)) {
+ return false;
+ }
+
+ KelpPotionEffectType otherEffect = (KelpPotionEffectType) other;
+
+ return otherEffect.getName().equals(getName())
+ && otherEffect.isInstant() == isInstant()
+ && otherEffect.getColor().equals(getColor());
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(37, 17)
+ .append(getName())
+ .append(getColor())
+ .append(getRating())
+ .toHashCode();
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/MinecraftPotion.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/MinecraftPotion.java
new file mode 100644
index 00000000..7034618b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/MinecraftPotion.java
@@ -0,0 +1,16 @@
+package de.pxav.kelp.core.entity.util.potion;
+
+import de.pxav.kelp.core.version.KelpVersion;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface MinecraftPotion {
+
+ KelpVersion since();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionEffects.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionEffects.java
new file mode 100644
index 00000000..6332a6c4
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionEffects.java
@@ -0,0 +1,121 @@
+package de.pxav.kelp.core.entity.util.potion;
+
+import com.google.common.collect.Lists;
+import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.KelpServer;
+import de.pxav.kelp.core.entity.util.potion.minecraft.*;
+import de.pxav.kelp.core.version.KelpVersion;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This class holds some constant values for quick access to some potion
+ * effect types needed to for example create a new {@link KelpPotionEffect} instance,
+ * which can then be {@link de.pxav.kelp.core.entity.LivingKelpEntity#addPotionEffect(KelpPotionEffect) applied to an entity}.
+ *
+ * Please note that this class is not an enum and its values are therefore not comparable
+ * using the {@code ==} operator. If you want to compare effect types, use
+ * {@code PotionEffects.ABSORPTION.equals(anotherPotionEffectInstance)} instead.
+ *
+ * @author pxav
+ */
+public abstract class PotionEffects {
+
+ // default minecraft potion types.
+ public static final KelpPotionEffectType ABSORPTION = KelpPlugin.getInjector().getInstance(AbsorptionPotionEffect.class);
+ public static final KelpPotionEffectType BAD_LUCK = KelpPlugin.getInjector().getInstance(BadLuckPotionEffect.class);
+ public static final KelpPotionEffectType BAD_OMEN = KelpPlugin.getInjector().getInstance(BadOmenPotionEffect.class);
+ public static final KelpPotionEffectType BLINDNESS = KelpPlugin.getInjector().getInstance(BlindnessPotionEffect.class);
+ public static final KelpPotionEffectType CONDUIT_POWER = KelpPlugin.getInjector().getInstance(ConduitPowerPotionEffect.class);
+ public static final KelpPotionEffectType DOLPHINS_GRACE = KelpPlugin.getInjector().getInstance(DolphinsGracePotionEffect.class);
+ public static final KelpPotionEffectType FIRE_RESISTANCE = KelpPlugin.getInjector().getInstance(FireResistancePotionEffect.class);
+ public static final KelpPotionEffectType GLOWING = KelpPlugin.getInjector().getInstance(GlowingPotionEffect.class);
+ public static final KelpPotionEffectType HASTE = KelpPlugin.getInjector().getInstance(HastePotionEffect.class);
+ public static final KelpPotionEffectType HEALTH_BOOST = KelpPlugin.getInjector().getInstance(HealthBoostPotionEffect.class);
+ public static final KelpPotionEffectType HERO_OF_THE_VILLAGE = KelpPlugin.getInjector().getInstance(HeroOfTheVillagePotionEffect.class);
+ public static final KelpPotionEffectType HUNGER = KelpPlugin.getInjector().getInstance(HungerPotionEffect.class);
+ public static final KelpPotionEffectType INSTANT_DAMAGE = KelpPlugin.getInjector().getInstance(InstantDamagePotionEffect.class);
+ public static final KelpPotionEffectType INSTANT_HEAL = KelpPlugin.getInjector().getInstance(InstantHealPotionEffect.class);
+ public static final KelpPotionEffectType INVISIBILITY = KelpPlugin.getInjector().getInstance(InvisibilityPotionEffect.class);
+ public static final KelpPotionEffectType JUMP_BOOST = KelpPlugin.getInjector().getInstance(JumpBoostPotionEffect.class);
+ public static final KelpPotionEffectType LEVITATION = KelpPlugin.getInjector().getInstance(LevitationEffect.class);
+ public static final KelpPotionEffectType LUCK = KelpPlugin.getInjector().getInstance(LuckPotionEffect.class);
+ public static final KelpPotionEffectType MINING_FATIGUE = KelpPlugin.getInjector().getInstance(MiningFatiguePotionEffect.class);
+ public static final KelpPotionEffectType NAUSEA = KelpPlugin.getInjector().getInstance(NauseaPotionEffect.class);
+ public static final KelpPotionEffectType NIGHT_VISION = KelpPlugin.getInjector().getInstance(NightVisionPotionEffect.class);
+ public static final KelpPotionEffectType POISON = KelpPlugin.getInjector().getInstance(PoisonPotionEffect.class);
+ public static final KelpPotionEffectType REGENERATION = KelpPlugin.getInjector().getInstance(RegenerationPotionEffect.class);
+ public static final KelpPotionEffectType RESISTANCE = KelpPlugin.getInjector().getInstance(ResistancePotionEffect.class);
+ public static final KelpPotionEffectType SATURATION = KelpPlugin.getInjector().getInstance(SaturationPotionEffect.class);
+ public static final KelpPotionEffectType SLOW_FALLING = KelpPlugin.getInjector().getInstance(SlowFallingPotionEffect.class);
+ public static final KelpPotionEffectType SLOWNESS = KelpPlugin.getInjector().getInstance(SlownessPotionEffect.class);
+ public static final KelpPotionEffectType SPEED = KelpPlugin.getInjector().getInstance(SpeedPotionEffect.class);
+ public static final KelpPotionEffectType STRENGTH = KelpPlugin.getInjector().getInstance(StrengthPotionEffect.class);
+ public static final KelpPotionEffectType WATER_BREATHING = KelpPlugin.getInjector().getInstance(WaterBreathingPotionEffect.class);
+ public static final KelpPotionEffectType WEAKNESS = KelpPlugin.getInjector().getInstance(WeaknessPotionEffect.class);
+ public static final KelpPotionEffectType WITHER = KelpPlugin.getInjector().getInstance(WitherPotionEffect.class);
+
+ /**
+ * Picks a random potion effect type from all existing ones
+ * at the current server version. This method uses values
+ * returned from {@link #values()} in the background.
+ *
+ * @return A random potion effect type available at the current server version.
+ */
+ public static KelpPotionEffectType randomEffectType() {
+ final List types = values();
+ Collections.shuffle(types);
+ return types.get(0);
+ }
+
+ /**
+ * Picks a random potion effect type from existing ones at the
+ * current server version. Only potion types with the given rating
+ * are returned, meaning that if you want to have a positive potion
+ * effect type, {@link KelpEffectRating#POSITIVE} has to be passed.
+ *
+ * If you don't care about the effect's rating, use {@link #randomEffectType()}
+ * instead.
+ *
+ * @param rating The rating of the effect.
+ * @return
+ */
+ public static KelpPotionEffectType randomEffectType(KelpEffectRating rating) {
+ final List types = values();
+ do {
+ Collections.shuffle(types);
+ } while (types.get(0).getRating() != rating);
+ return types.get(0);
+ }
+
+ public static KelpPotionEffectType valueOf(String fieldName) {
+ switch (fieldName) {
+ case "ABSORPTION": return ABSORPTION;
+ case "LEVITATION": return LEVITATION;
+ case "HASTE": return HASTE;
+ }
+ return PotionEffects.ABSORPTION;
+ }
+
+ /**
+ * Returns all potion effect types existing on the current server version.
+ * So if you call this method on a 1.8 server, {@code LEVITATION} will be excluded,
+ * while it is included in 1.9+.
+ *
+ * @return A list of all potion effect types available at the current server version.
+ */
+ public static List values() {
+ List output = Lists.newArrayList(
+ ABSORPTION,
+ HASTE
+ );
+
+ if (KelpServer.getVersion().isHigherThanOrEqualTo(KelpVersion.MC_1_9_0)) {
+ output.add(LEVITATION);
+ }
+
+ return output;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionListener.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionListener.java
new file mode 100644
index 00000000..58acfd42
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionListener.java
@@ -0,0 +1,27 @@
+package de.pxav.kelp.core.entity.util.potion;
+
+import de.pxav.kelp.core.player.KelpPlayer;
+import org.bukkit.Material;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.player.PlayerItemConsumeEvent;
+
+public class PotionListener {
+
+ @EventHandler(priority = EventPriority.HIGHEST)
+ public void handleMilkConsume(PlayerItemConsumeEvent event) {
+ if (event.getItem().getType() != Material.MILK_BUCKET || event.isCancelled()) {
+ return;
+ }
+
+ KelpPlayer player = KelpPlayer.from(event.getPlayer());
+
+ for (KelpPotionEffectType effectType : player.getActivePotionEffectTypes()) {
+ if (!effectType.isBukkitEffect() && effectType.isRemovableWithMilk()) {
+ player.removePotionEffect(effectType);
+ }
+ }
+
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionVersionTemplate.java
new file mode 100644
index 00000000..6efe6bb6
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/PotionVersionTemplate.java
@@ -0,0 +1,66 @@
+package de.pxav.kelp.core.entity.util.potion;
+
+import de.pxav.kelp.core.application.KelpVersionTemplate;
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+/**
+ * This class allows you to execute version-dependent operations
+ * on potion effects such as converting bukkit and kelp effects.
+ *
+ * This does not implement potion effects that are unavailable in
+ * some versions, please look at the individual potion effect classes
+ * in this case.
+ *
+ * @author pxav
+ */
+@KelpVersionTemplate
+public abstract class PotionVersionTemplate {
+
+ /**
+ * Gets the bukkit potion effect type from a given kelp effect type.
+ *
+ * This method can obviously only return the potion types that are available
+ * in the bukkit version you are running, so if you request {@link PotionEffectType#LEVITATION}
+ * on a 1.8 server, {@code null} will be returned as there is no equivalent.
+ *
+ * @param effect The kelp effect type you want to get the bukkit equivalent of.
+ * @return The bukkit potion effect type equivalent to the given kelp effect type.
+ */
+ public abstract PotionEffectType getBukkitPotion(KelpPotionEffectType effect);
+
+ /**
+ * Applies the given {@link KelpPotionEffect potion effect} to the given entity.
+ * Not every effect will have the same consequences for all entities. Some entities might
+ * be immune against certain effects or can be affected differently than expected
+ * (e. g. Zombies are damaged by a heal potion).
+ *
+ * If the requested potion effect type does not exist, the Kelp implementation of
+ * this effect will be called to emulate the effect.
+ *
+ * @param entity The entity to apply the effect to.
+ * @param potionEffect The {@link KelpPotionEffect potion effect} to apply to the entity
+ * including all information such as duration or level of the effect.
+ */
+ public abstract void applyTo(LivingKelpEntity> entity, KelpPotionEffect potionEffect);
+
+ /**
+ * Converts the given bukkit potion effect to a {@link KelpPotionEffect}.
+ * This is useful when getting all effects of an entity for example.
+ *
+ * @param effect The bukkit effect to convert.
+ * @return A new instance of {@link KelpPotionEffect} containing the data equivalent to the bukkit potion effect.
+ */
+ public abstract KelpPotionEffect fetchEffect(PotionEffect effect);
+
+ /**
+ * Converts the given bukkit potion effect type to the equivalent kelp effect type.
+ *
+ * @param effectType The bukkit effect type to convert.
+ * @return The {@link KelpPotionEffectType} equivalent to the given bukkit effect.
+ */
+ public abstract KelpPotionEffectType getKelpPotion(PotionEffectType effectType);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/AbsorptionPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/AbsorptionPotionEffect.java
new file mode 100644
index 00000000..4b729bb6
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/AbsorptionPotionEffect.java
@@ -0,0 +1,69 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Represents the absorption potion effect. Absorption is a status
+ * effect that pads the health bar with extra hearts.
+ *
+ * Absorption adds 4 additional health points per level to the player,
+ * displayed as yellow hearts above the normal health bar. If the player takes damage while under this effect,
+ * the absorption health points are depleted before the normal health points.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class AbsorptionPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Gets the amount of extra health points (HP) for the given level.
+ * Two health points are equal to 1 heart.
+ *
+ * @param level The absorption level to get the HP for.
+ * @return The HP given by this level
+ */
+ public static int getHealthPointsForLevel(int level) {
+ return level * 4;
+ }
+
+ /**
+ * Gets the amount of extra hearts a player receives when the given
+ * level of absorption is applied.
+ *
+ * @param level The level to get the amount of hearts for.
+ * @return The hearts given by this level.
+ */
+ public static int getHeartsForLevel(int level) {
+ return level * 2;
+ }
+
+ @Override
+ public String getName() {
+ return "Absorption";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("2552A5");
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BadLuckPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BadLuckPotionEffect.java
new file mode 100644
index 00000000..ea487bf4
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BadLuckPotionEffect.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Bad Luck, also known as Unluck, is a status effect that decreases
+ * the chance of the player getting high-quality loot, contrary to Luck.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_9_0)
+public class BadLuckPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Bad Luck";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("C0A44D");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_9_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BadOmenPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BadOmenPotionEffect.java
new file mode 100644
index 00000000..ff592755
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BadOmenPotionEffect.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Bad Omen is a status effect that causes a raid to appear
+ * when an afflicted player enters a village.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_14_0)
+public class BadOmenPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Bad Omen";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("0b6138");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.MIXED;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_14_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BlindnessPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BlindnessPotionEffect.java
new file mode 100644
index 00000000..bb1367b1
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/BlindnessPotionEffect.java
@@ -0,0 +1,46 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Blindness impairs the player's vision as if a thick black fog were surrounding them,
+ * with only the immediate area being visible (this means that only a few blocks directly
+ * around the player are visible to them).
+ * The effect also prevents the player from sprinting or inflicting critical hits.
+ * If combined with Night Vision, the screen appears completely black aside from the sun and moon.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class BlindnessPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Blindness";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("1F1F23");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/ConduitPowerPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/ConduitPowerPotionEffect.java
new file mode 100644
index 00000000..87acf2ac
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/ConduitPowerPotionEffect.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Conduit Power is an area-of-effect status effect given by conduits that
+ * combines Water Breathing, Night Vision (only underwater), and Haste (only underwater).
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_13_0)
+public class ConduitPowerPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Conduit Power";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("1DC2D1");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_13_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/DolphinsGracePotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/DolphinsGracePotionEffect.java
new file mode 100644
index 00000000..2f08b075
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/DolphinsGracePotionEffect.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Dolphin's Grace is a status effect that increases the player's swimming
+ * speed when a dolphin is nearby and following the player.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_13_0)
+public class DolphinsGracePotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Dolphin's Grace";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("88A3BE");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_13_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/FireResistancePotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/FireResistancePotionEffect.java
new file mode 100644
index 00000000..6262d984
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/FireResistancePotionEffect.java
@@ -0,0 +1,47 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Grants immunity to damage from fire, blaze fireballs, fire charges,
+ * magma blocks, and lava, but not ghast fireballs and blaze touch attacks.
+ * Negates the fire damage from bows enchanted with Flame and swords enchanted
+ * with Fire Aspect, but does not affect the attacks themselves.
+ * The fog effect under lava is also mitigated somewhat.
+ * Players also see better under lava when they have the Fire Resistance effect.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class FireResistancePotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Fire Resistance";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("E49A3A");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/GlowingPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/GlowingPotionEffect.java
new file mode 100644
index 00000000..dc69f970
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/GlowingPotionEffect.java
@@ -0,0 +1,46 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * The Glowing effect causes entities to glow with an outline that can be seen through blocks and entities.
+ * This outline is white by default, but can be set to display other colors if the entity is part of a team.
+ * The outline displays around any holes in a mob's texture or model, though only when that part of the model
+ * can be seen all the way through. If multiple entities with glowing are near each other,
+ * the outlines merge to prevent overlapping.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_9_0)
+public class GlowingPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Glowing";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("94A061");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.MIXED;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_9_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HastePotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HastePotionEffect.java
new file mode 100644
index 00000000..0fc428c0
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HastePotionEffect.java
@@ -0,0 +1,44 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Haste is a status effect that increases attack speed by 10% per level and
+ * increases mining speed by 20% per level. Negative levels decrease mining and attack speed,
+ * similar to Mining Fatigue. However, the attack speed increases are purely visual.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class HastePotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Haste";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("D9C043");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HealthBoostPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HealthBoostPotionEffect.java
new file mode 100644
index 00000000..a991d15f
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HealthBoostPotionEffect.java
@@ -0,0 +1,47 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Health Boost is a status effect that increases a player's (or mob's) maximum health.
+ * Adds 4 health points maximum health per level. Unlike Absorption, the added hearts are
+ * empty at first, but can be healed through the usual methods
+ * such as natural regeneration and the Regeneration and Instant Health effects).
+ *
+ * When the effect ends, any extra health is lost.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class HealthBoostPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Health Boost";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("F87D23");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HeroOfTheVillagePotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HeroOfTheVillagePotionEffect.java
new file mode 100644
index 00000000..f22b2c50
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HeroOfTheVillagePotionEffect.java
@@ -0,0 +1,57 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Players receive gifts and discounts from villager trades while under the effect.
+ *
+ * Level I Hero of the Village decreases the cost of the first item in a trade by 30%;
+ * each additional level decreases the price by an additional 6.25%.
+ *
+ * Hero of the Village XII gives a discount of 98.75%, decreasing all prices to 1.
+ * No matter how large the discount is, the final item count in the trade is
+ * always at least one, never zero. In other cases, the decrement is the discount
+ * ratio multiplied by the original count rounded down or rounded up if the decrement
+ * is less than 1.
+ *
+ * Example: Level III would give a 42.5% discount. For trade with 14 emeralds as the cost,
+ * the discount would be 5 emeralds (rounded down from 5.95 emeralds), for a final price of 9 emeralds.
+ *
+ * The formula can be written as:
+ * {@code Discounted price = Initial price - max[1, Initial Price × (.0625 × (Level - 1) + 0.3)]}
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_14_0)
+public class HeroOfTheVillagePotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Hero of the Village";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("44FF44");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_14_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HungerPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HungerPotionEffect.java
new file mode 100644
index 00000000..a74eef7b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/HungerPotionEffect.java
@@ -0,0 +1,48 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Hunger increases food exhaustion by {@code 0.005 * level} per game tick
+ * (removes 1 food saturation point every {@code 40 / level seconds}).
+ * It also turns the hunger bar a yellow-greenish color.
+ * Negative levels decrease food exhaustion, although they do not increase saturation or the hunger bar.
+ *
+ * The status effect does not decrease hunger level on Peaceful mode,
+ * although it does re-color the hunger bar.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class HungerPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Hunger";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("587653");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InstantDamagePotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InstantDamagePotionEffect.java
new file mode 100644
index 00000000..97e1a75f
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InstantDamagePotionEffect.java
@@ -0,0 +1,78 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.common.MathUtils;
+import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Instant Damage is an instant status effect that decreases health for living mobs and heals the undead.
+ * Instant Damage inflicts magic damage of {@code 3HP * 2^level}. Undead mobs (including the wither)
+ * are healed as if with Instant Health instead.
+ * When applied using a lingering potion, damage is inflicted every second.
+ * As this is magic damage, it can be decreased only via Resistance and Protection.
+ *
+ * An Instant Damage IV potion is powerful enough to kill a player instantly.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class InstantDamagePotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Calculates the health loss made for an entity at the given effect level.
+ * If the entity is an undead, a negative number will be returned as those
+ * entities actually gain health from this effect. For the calculation of this
+ * number the negative value of {}
+ *
+ * @param entity The entity to calculate the damage for.
+ * @param level The level with which the effect is applied.
+ * @return The total amount of damage made to the entity in health points.
+ */
+ public static double getHealthLoss(LivingKelpEntity> entity, int level) {
+ // witches are 85% immune against instant damage
+ if (entity.getType() == KelpEntityType.WITCH) {
+ if (MathUtils.perCentChance(0.85)) {
+ return 0;
+ }
+ }
+
+ double healthLoss = 3 * Math.pow(2, level);
+
+ if (entity.getType().isUndead()) {
+ return -healthLoss;
+ }
+
+ return healthLoss;
+ }
+
+ @Override
+ public String getName() {
+ return "Damage";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return true;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("430A09");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InstantHealPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InstantHealPotionEffect.java
new file mode 100644
index 00000000..b890863e
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InstantHealPotionEffect.java
@@ -0,0 +1,78 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Instant Health is an instant status effect that increases health
+ * for living mobs and damages the undead.
+ * Instantly heals {@code 2HP * 2^level}.
+ *
+ * Undead mobs (including the wither) are damaged as if with Instant Damage, instead.
+ * When applied using a lingering potion, the entity is healed every second.
+ * Levels 30–32 provide no healing. Levels outside the range 1–32
+ * are used modulo 32, making level 33 the same as level 1, etc.
+ *
+ * Ender dragons are completely immune to this effect.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class InstantHealPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Calculates the health gain made for an entity at the given effect level.
+ * If the entity is an undead, a negative number will be returned as those
+ * entities actually lose health from this effect.
+ *
+ * @param entity The entity to calculate the health gain for.
+ * @param level The level with which the effect is applied.
+ * @return The total amount of health gain made to the entity in health points.
+ */
+ public static double getHealthGain(LivingKelpEntity> entity, int level) {
+ if (level == 30 || level == 31 || level == 32) {
+ return 0;
+ }
+ if (level > 32) {
+ level = level % 32;
+ }
+
+ double healthGain = 2 * Math.pow(2, level);
+
+ if (entity.getType().isUndead()) {
+ return -healthGain;
+ }
+
+ return healthGain;
+ }
+
+ @Override
+ public String getName() {
+ return "Healing";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return true;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("F82423");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InvisibilityPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InvisibilityPotionEffect.java
new file mode 100644
index 00000000..1ef3e147
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/InvisibilityPotionEffect.java
@@ -0,0 +1,53 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.KelpEntity;
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffect;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.player.KelpPlayer;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Invisibility is a status effect that turns entities invisible.
+ * Applying higher levels does not make a difference, however the duration
+ * can be extended when applied as an {@link KelpPotionEffect effect}.
+ *
+ * Please note that this effect may not cause complete invisibility as
+ * only the entity itself is hidden. Particle effects (e. g. from a potion),
+ * armor or arrows are still visible for other players. To completely hide
+ * a player, use {@link de.pxav.kelp.core.player.KelpPlayer#hidePlayer(KelpPlayer)}
+ * or {@link KelpEntity#remove()} for entities.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class InvisibilityPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Invisibility";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("7F8392");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/JumpBoostPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/JumpBoostPotionEffect.java
new file mode 100644
index 00000000..70a91cf0
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/JumpBoostPotionEffect.java
@@ -0,0 +1,57 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Jump Boost is a status effect that temporarily increases the jump height of the player.
+ *
+ * Jump Boost allows the player to jump higher than the normal 1.25 blocks.
+ * Each level adds 50% to the jump height. It also reduces fall damage by 2 health points each level.
+ * If the level is high enough, fall damage can be avoided completely.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class JumpBoostPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Calculates the amount of blocks a player can jump along the Y axis
+ * with the given level of jump boost applied.
+ *
+ * @param level The jump boost level to calculate the height for.
+ * @return The jump height of a player with the given jump boost level.
+ */
+ public static double getJumpHeight(int level) {
+ return 1.25 * Math.pow(1.5, level);
+ }
+
+ @Override
+ public String getName() {
+ return "Jump Boost";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("22FF4C");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/LevitationEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/LevitationEffect.java
new file mode 100644
index 00000000..2dbcfec9
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/LevitationEffect.java
@@ -0,0 +1,42 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+@MinecraftPotion(since = KelpVersion.MC_1_9_0)
+public class LevitationEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Levitation";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("CEFFFF");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isEmulated() {
+ return true;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_9_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/LuckPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/LuckPotionEffect.java
new file mode 100644
index 00000000..d4f869fb
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/LuckPotionEffect.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Luck is a status effect that makes it more likely to receive better
+ * loot from certain loot tables in generated structures.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_9_0)
+public class LuckPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Luck";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("339900");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_9_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/MiningFatiguePotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/MiningFatiguePotionEffect.java
new file mode 100644
index 00000000..0f9b243c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/MiningFatiguePotionEffect.java
@@ -0,0 +1,56 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Mining Fatigue reduces mining and attack speed, opposite to the
+ * {@link HastePotionEffect Haste} effect. Unlike the Haste effect,
+ * this effect actually reduces the attack speed and not only its animation.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class MiningFatiguePotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Gets the attack speed in per cent of the player's original attack speed.
+ * The normal attack speed is 100% ({@code 1}), therefore {@code 0.7} would be
+ * a {@code 30%} decrease in attack speed.
+ *
+ * @param level The level this effect is applied with.
+ * @return The attack speed modifier of the player based on the given effect level.
+ */
+ public static double getAttackSpeedModifier(int level) {
+ return 1 - (0.1 * level);
+ }
+
+ @Override
+ public String getName() {
+ return "Mining Fatigue";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("4A4217");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/NauseaPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/NauseaPotionEffect.java
new file mode 100644
index 00000000..9220ee93
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/NauseaPotionEffect.java
@@ -0,0 +1,46 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Nausea causes the player's vision to warp and wobble, with the distortion ramping
+ * up and down at the start and end of the effect. Although Nausea can be given in the
+ * normal range of levels, the level has no impact - it does not increase the distortion.
+ *
+ * The intensity of this effect can be configured in the client's video settings.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class NauseaPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Nausea";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("551D4A");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/NightVisionPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/NightVisionPotionEffect.java
new file mode 100644
index 00000000..19edb815
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/NightVisionPotionEffect.java
@@ -0,0 +1,44 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Night vision greatly increases the brightness, so the player can easily see in a light level of 0.
+ * But this effect is not strong enough to look the same as light level 15. That's why the player
+ * can still visually distinguish between light levels when this effect is applied.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class NightVisionPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Night Vision";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("1F1FA1");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/PoisonPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/PoisonPotionEffect.java
new file mode 100644
index 00000000..26cc8e47
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/PoisonPotionEffect.java
@@ -0,0 +1,44 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Poison inflicts damage over time, reducing the player's health to 1 HP, but cannot kill.
+ * The health bar of a player is colored yellow while this effect is applied.
+ * The speed with which health is lost, depends on the effect level.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class PoisonPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Poison";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("4E9331");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/RegenerationPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/RegenerationPotionEffect.java
new file mode 100644
index 00000000..93aef807
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/RegenerationPotionEffect.java
@@ -0,0 +1,86 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Regeneration is a status effect that restores a player's (or mob's) health over time.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class RegenerationPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Get the amounts of hearts that are regenerated every second based on the
+ * level of the effect.
+ *
+ * If you want to get the health points per second, simply multiply the result
+ * of this method by 2.
+ *
+ * If the level is invalid - so if it is negative for example,
+ * {@code -1} will be returned.
+ *
+ * Amplifiers outside the range 0–31 (corresponding to levels 1–32) are used modulo 32,
+ * making level 33 the same as level 1, etc.
+ *
+ * @param level The level to get the regenerated hearts for.
+ * @return The amount of regenerated hearts based on the given level. {@code -1} if the level is invalid.
+ */
+ public static double getHeartsPerSecond(int level) {
+ if (level < 1) {
+ return -1;
+ }
+
+ // if level limitation of 32 is reached,
+ // use numbers as modulo
+ if (level > 32) {
+ level = level % 32;
+ }
+
+ if (level == 1) {
+ return 0.2d;
+ } else if (level == 2) {
+ return 0.4d;
+ } else if (level == 3) {
+ return 0.835d;
+ } else if (level == 4) {
+ return 1.665d;
+ } else if (level == 5) {
+ return 3.335d;
+
+ // level six and higher
+ } else {
+ return 10d;
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "Regeneration";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("CD5CAB");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/ResistancePotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/ResistancePotionEffect.java
new file mode 100644
index 00000000..5aeb5351
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/ResistancePotionEffect.java
@@ -0,0 +1,46 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Resistance reduces incoming damage from all sources except starvation,
+ * the void, and {@code /kill} by {@code 20% * level}.
+ *
+ * Level 5 gives the player full immunity to all damage, while the exceptions
+ * from above persist.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class ResistancePotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Resistance";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("99453A");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SaturationPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SaturationPotionEffect.java
new file mode 100644
index 00000000..46571454
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SaturationPotionEffect.java
@@ -0,0 +1,46 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Saturation is an instant status effect that reduces the need for eating.
+ * It also prevents death by hunger if the player has no food.
+ *
+ * The effect instantly replenishes {@code 1FP * level} and {@code 2FP * level}
+ * points of saturation.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class SaturationPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Saturation";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("F82421");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SlowFallingPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SlowFallingPotionEffect.java
new file mode 100644
index 00000000..c6fb1ad9
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SlowFallingPotionEffect.java
@@ -0,0 +1,46 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * The affected entity falls at a much slower rate than normal, and is immune to fall damage.
+ * However, the entity still takes damage from using an ender pearl.
+ * In addition, the entity cannot turn farmland into dirt by jumping on it.
+ *
+ * Higher levels do not have an impact on this effect.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_13_0)
+public class SlowFallingPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Slow Falling";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("F7F8E0");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return version.isHigherThanOrEqualTo(KelpVersion.MC_1_13_0);
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SlownessPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SlownessPotionEffect.java
new file mode 100644
index 00000000..86d72367
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SlownessPotionEffect.java
@@ -0,0 +1,57 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.npc.MovementSpeed;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Slowness decreases walking speed by {@code 15% * level} and contracts the player's field of view accordingly.
+ * Negative levels of Slowness increase walking speed. However, sprinting and jumping is barely affected,
+ * unlike with the {@link SpeedPotionEffect}.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class SlownessPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Gets the blocks per second a player can walk with the given
+ * level of slowness applied.
+ *
+ * @param level The level to get the walking speed for.
+ * @return The amount of blocks a player can walk each second with the given level of slowness applied.
+ */
+ public static double getBlocksPerSecond(MovementSpeed movementSpeed, int level) {
+ // TODO: Add MovementSpeed.JUMPING!
+ return movementSpeed.getBlocksPerSecond() * 1.15 * level;
+ }
+
+ @Override
+ public String getName() {
+ return "Slowness";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("5A6C81");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SpeedPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SpeedPotionEffect.java
new file mode 100644
index 00000000..7484af21
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/SpeedPotionEffect.java
@@ -0,0 +1,57 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.npc.MovementSpeed;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Speed is a status effect that increases an entity's walking speed by 20% multiplied by the effect level.
+ * It expands a player's field of view (FOV) accordingly. Negative levels decrease speed.
+ * Jumping and falling are also affected by this effect, although not every server can handle the
+ * jump speed coming with higher effect levels.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class SpeedPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Gets the blocks per second a player can walk with the given
+ * level of speed applied.
+ *
+ * @param level The level to get the walking speed for.
+ * @return The amount of blocks a player can walk each second with the given level of speed applied.
+ */
+ public static double getBlocksPerSecond(MovementSpeed movementSpeed, int level) {
+ return movementSpeed.getBlocksPerSecond() * 1.2 * level;
+ }
+
+ @Override
+ public String getName() {
+ return "Speed";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("7CAFC6");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/StrengthPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/StrengthPotionEffect.java
new file mode 100644
index 00000000..4633b4e4
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/StrengthPotionEffect.java
@@ -0,0 +1,68 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Strength is an effect which increases attack power.
+ *
+ * Increases melee damage by {@code 3HP × level}.
+ * Negative levels decrease melee damage, with attacks being ignored entirely
+ * if damage would be 0 or lower.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class StrengthPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Calculates the increased/decreased total attack damage made by the given
+ * effect level and the original attack damage.
+ *
+ * @param originalAttackDamage The original attack damage in health points
+ * ({@code heart amount * 2}).
+ * @param level The level of the potion effect.
+ * @return The amount of damage made with the given effect level and
+ * original attack damage in health points.
+ */
+ public static double getDamageIncrease(double originalAttackDamage, int level) {
+ if (level == 0) {
+ return originalAttackDamage;
+ }
+ double attackDamage = originalAttackDamage + (3 * level);
+ return attackDamage > 0 ? attackDamage : 0;
+ }
+
+ // Todo: getDamageIncrease() method, where you can pass a KelpItem
+ // Todo: Kelp then automatically checks the material and enchantments to
+ // Todo: determine the original attack damage
+
+ @Override
+ public String getName() {
+ return "Strength";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("932423");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WaterBreathingPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WaterBreathingPotionEffect.java
new file mode 100644
index 00000000..2591b57b
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WaterBreathingPotionEffect.java
@@ -0,0 +1,42 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Water breathing is a status effect that prevents or delays drowning.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class WaterBreathingPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Water Breathing";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("2E5299");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.POSITIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WeaknessPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WeaknessPotionEffect.java
new file mode 100644
index 00000000..2bde608c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WeaknessPotionEffect.java
@@ -0,0 +1,54 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Melee damage inflicted by the affected entity is reduced by {@code 4HP * level}.
+ * Negative levels increase melee damage dealt.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class WeaknessPotionEffect extends KelpPotionEffectType {
+
+ /**
+ * Calculates how much damage in health points is lost based
+ * on the given level of the effect.
+ *
+ * @param level The level of the weakness effect.
+ * @return The amount of damage the melee attack is reduced by.
+ */
+ public static double getDamageLoss(int level) {
+ return 4 * level;
+ }
+
+ @Override
+ public String getName() {
+ return "Weakness";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("484D48");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WitherPotionEffect.java b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WitherPotionEffect.java
new file mode 100644
index 00000000..c601216e
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/util/potion/minecraft/WitherPotionEffect.java
@@ -0,0 +1,45 @@
+package de.pxav.kelp.core.entity.util.potion.minecraft;
+
+import de.pxav.kelp.core.entity.util.potion.KelpEffectRating;
+import de.pxav.kelp.core.entity.util.potion.KelpPotionEffectType;
+import de.pxav.kelp.core.entity.util.potion.MinecraftPotion;
+import de.pxav.kelp.core.inventory.metadata.Color;
+import de.pxav.kelp.core.version.KelpVersion;
+
+/**
+ * Wither is a status effect that inflicts damage over time.
+ * Unlike Poison, it can affect undead mobs, and can kill.
+ * It is usually difficult for the player to see how much health they have left,
+ * as it turns the player's health bar black.
+ *
+ * @author pxav
+ */
+@MinecraftPotion(since = KelpVersion.MC_1_8_0)
+public class WitherPotionEffect extends KelpPotionEffectType {
+
+ @Override
+ public String getName() {
+ return "Wither";
+ }
+
+ @Override
+ public boolean isInstant() {
+ return false;
+ }
+
+ @Override
+ public Color getColor() {
+ return Color.fromHEX("352A27");
+ }
+
+ @Override
+ public KelpEffectRating getRating() {
+ return KelpEffectRating.NEGATIVE;
+ }
+
+ @Override
+ public boolean isBukkitEffectUnsafe(KelpVersion version) {
+ return true;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/version/EntityConstantsVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/entity/version/EntityConstantsVersionTemplate.java
new file mode 100644
index 00000000..7e099098
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/entity/version/EntityConstantsVersionTemplate.java
@@ -0,0 +1,43 @@
+package de.pxav.kelp.core.entity.version;
+
+import de.pxav.kelp.core.application.KelpVersionTemplate;
+import de.pxav.kelp.core.entity.type.RabbitEntity;
+import de.pxav.kelp.core.entity.type.general.KelpProjectile;
+import de.pxav.kelp.core.entity.util.*;
+import org.bukkit.Art;
+import org.bukkit.entity.Villager;
+
+@KelpVersionTemplate
+public abstract class EntityConstantsVersionTemplate {
+
+ public abstract PaintingType getPaintingType(Art art);
+
+ public abstract Art getBukkitPaintingType(PaintingType paintingType);
+
+ public abstract VillagerProfession getVillagerProfession(String bukkitProfession);
+
+ public abstract String getVillagerProfession(VillagerProfession villagerType);
+
+ public abstract VillagerType getVillagerType(String bukkitType);
+
+ public abstract String getVillagerType(VillagerType villagerType);
+
+ public abstract CatType getCatType(String bukkitCatType);
+
+ public abstract String getCatType(CatType catType);
+
+ public abstract String getHorseColor(HorseColor horseColor);
+
+ public abstract HorseColor getHorseColor(String horseColor);
+
+ public abstract String getHorseStyle(HorseStyle horseStyle);
+
+ public abstract HorseStyle getHorseStyle(String horseStyle);
+
+ public abstract String getRabbitType(RabbitType rabbitType);
+
+ public abstract RabbitType getRabbitType(String rabbitType);
+
+ public abstract > T launchProjectile();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/version/EntityTypeVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/entity/version/EntityTypeVersionTemplate.java
index 3c9f1512..89bb1775 100644
--- a/core/src/main/java/de/pxav/kelp/core/entity/version/EntityTypeVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/entity/version/EntityTypeVersionTemplate.java
@@ -3,19 +3,42 @@
import de.pxav.kelp.core.application.KelpVersionTemplate;
import de.pxav.kelp.core.entity.KelpEntity;
import de.pxav.kelp.core.entity.KelpEntityType;
+import de.pxav.kelp.core.world.KelpLocation;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
/**
- * A class description goes here.
+ * This version template handles the conversion between kelp and bukkit
+ * entity types. It allows you to convert and create kelp entities and is
+ * used by other methods in the background such as the static factories
+ * in the entity classes.
*
* @author pxav
*/
@KelpVersionTemplate
public abstract class EntityTypeVersionTemplate {
- public abstract KelpEntity newKelpEntity(KelpEntityType entityType, Location location);
+ /**
+ * Creates a new kelp entity instance with a specific type at a specific location.
+ * This method won't spawn the entity, so that you can still do modifications
+ * on it as needed.
+ *
+ * @param entityType The type of the entity you want to spawn.
+ * @param location The location, where the entity should be spawned at later.
+ * @return The new kelp entity instance.
+ */
+ public abstract KelpEntity> newKelpEntity(KelpEntityType entityType, Location location);
- public abstract KelpEntity getKelpEntity(Entity bukkitEntity);
+ /**
+ * Takes any bukkit entity and converts it to a new kelp entity instance.
+ *
+ * This is used by the static methods in the entity classes such as
+ * {@link de.pxav.kelp.core.entity.type.SheepEntity#from(Entity)}, so if you
+ * are an application developer you should prefer those methods over this one.
+ *
+ * @param bukkitEntity The bukkit entity you want to convert.
+ * @return The instance of the kelp entity equivalent to the given bukkit entity.
+ */
+ public abstract KelpEntity> getKelpEntity(Entity bukkitEntity);
}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/version/EntityVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/entity/version/EntityVersionTemplate.java
deleted file mode 100644
index 08435e61..00000000
--- a/core/src/main/java/de/pxav/kelp/core/entity/version/EntityVersionTemplate.java
+++ /dev/null
@@ -1,453 +0,0 @@
-package de.pxav.kelp.core.entity.version;
-
-import de.pxav.kelp.core.application.KelpVersionTemplate;
-import de.pxav.kelp.core.entity.KelpEntity;
-import de.pxav.kelp.core.version.KelpVersion;
-import de.pxav.kelp.core.version.SinceKelpVersion;
-import de.pxav.kelp.core.world.KelpLocation;
-import org.bukkit.Location;
-import org.bukkit.Server;
-import org.bukkit.World;
-import org.bukkit.entity.Entity;
-import org.bukkit.event.entity.EntityDamageEvent;
-import org.bukkit.event.player.PlayerTeleportEvent;
-import org.bukkit.util.Vector;
-
-import java.util.List;
-import java.util.UUID;
-
-/**
- * A class description goes here.
- *
- * @author pxav
- */
-@KelpVersionTemplate
-public abstract class EntityVersionTemplate {
-
- /**
- * Spawns the entity at the given location. As
- * creating the entity only registers it and returns
- * the entity instance, this method is necessary to
- * finally add your entity to the world.
- *
- * It is recommended to execute this method with a
- * small delay if you use it on a player join as
- * some versions will not spawn it correctly if you
- * do not do so.
- *
- * @param entity The entity you want to spawn.
- */
- public abstract void spawnEntity(KelpEntity entity);
-
- public abstract Entity toBukkitEntity(Object minecraftEntity);
-
- /**
- * Gets the current entity's location in the world.
- *
- * @param entity The entity whose location you want to get.
- * @return The location of the given entity.
- */
- public abstract KelpLocation getLocation(Entity entity);
-
- /**
- * Sets the entity's velocity to the given vector.
- *
- * @param entity The entity whose velocity you want to manipulate.
- * @param vector The vector of the velocity you want to set.
- */
- public abstract void setVelocity(Entity entity, Vector vector);
-
- /**
- * Gets the velocity of the desired entity.
- *
- * @param entity The entity whose velocity you want to get.
- * @return The velocity of the given entity.
- */
- public abstract Vector getVelocity(Entity entity);
-
- /**
- * Gets the height of an entity. In older versions
- * this property was called 'length' of an entity.
- *
- * @param entity The entity whose height you want to get.
- * @return The height of the given entity.
- */
- public abstract double getHeight(Entity entity);
-
- /**
- * Gets the width of the given entity.
- *
- * @param entity The entity whose width you want to get.
- * @return The entity's width.
- */
- public abstract double getWidth(Entity entity);
-
-// /**
-// * Get the current bounding box of the given entity.
-// * A bounding box is a way to mark 3D regions in the
-// * minecraft world and surrounds the entity. More
-// * information can be found in the documentation of
-// * {@code BoundingBox}
-// *
-// * @param entity The entity whose bounding box you want to get.
-// * @return The entity's bounding box.
-// * @see BoundingBox
-// */
-// public abstract BoundingBox getBoundingBox(Entity entity);
-
- /**
- * Checks if the entity is currently on the ground.
- *
- * @param entity The entity you want to check.
- * @return {@code true} if the entity is currently on ground.
- */
- public abstract boolean isOnGround(Entity entity);
-
- /**
- * Sets the rotation of the given entity. This does not
- * affect the location x, y and z axes.
- *
- * @param entity The entity whose rotation you want to modify.
- * @param yaw The yaw value of the desired rotation.
- * @param pitch The pitch value of the desired rotation.
- */
- public abstract void setRotation(Entity entity, float yaw, float pitch);
-
- /**
- * Teleports the entity to the given location.
- *
- * @param entity The entity you want to teleport.
- * @param location The location you want the entity to teleport to.
- * @param teleportCause The cause for the teleportation.
- * @return {@code true} if the teleport action was successful.
- */
- public abstract boolean teleport(Entity entity, KelpLocation location, PlayerTeleportEvent.TeleportCause teleportCause);
-
- /**
- * Gets all entities within the given radius centered around
- * the given entity.
- *
- * @param entity The entity where the center should be set.
- * @param x the radius for the x axis
- * (1/2 the size of the box along x axis)
- * @param y the radius for the y axis
- * (1/2 the size of the box along y axis)
- * @param z the radius for the z axis
- * (1/2 the size of the box along z axis)
- * @return A list of all nearby entities within the given radius.
- */
- public abstract List getNearbyEntities(Entity entity, double x, double y, double z);
-
- /**
- * Gets the id of the given entity.
- *
- * @param entity The entity whose id you want to get.
- * @return the entity id
- */
- public abstract int getEntityId(Entity entity);
-
- /**
- * Gets the current amount of fire ticks for the given
- * entity.
- *
- * Fire ticks are the duration before the entity stops
- * being on fire in ticks. So 60 for example would mean
- * the entity will stop burning after 3 seconds once
- * it ran into fire.
- *
- * @param entity The entity whose fire ticks you want to get.
- * @return The amount of fire ticks.
- */
- public abstract int getFireTicks(Entity entity);
-
- /**
- * Gets the amount of the maximum fire ticks of the given entity.
- *
- * @param entity The entity whose maximum fire ticks you want to get.
- * @return The amount of maximum fire ticks of the given entity.
- */
- public abstract int getMaxFireTicks(Entity entity);
-
- /**
- * Sets the amount of the maximum fire ticks of the given entity.
- *
- * @param entity The entity whose maximum fire ticks you want to modify.
- * @param maxFireTicks The amount of maximum fire ticks to set.
- */
- public abstract void setMaxFireTicks(Entity entity, int maxFireTicks);
-
- /**
- * Sets the current amount of fire ticks for the given
- * entity.
- *
- * Fire ticks are the duration before the entity stops
- * being on fire in ticks. So 60 for example would mean
- * the entity will stop burning after 3 seconds once
- * it ran into fire.
- *
- * @param entity The entity whose fire ticks you want to set.
- * @param fireTicks The amount of fire ticks you want to set.
- */
- public abstract void setFireTicks(Entity entity, int fireTicks);
-
- /**
- * Removes the entity from the world.
- *
- * @param entity The entity you want to remove.
- */
- public abstract void remove(Entity entity);
-
- /**
- * Checks if the given entity is dead.
- *
- * @param entity The entity you want to check.
- * @return {@code true} if the entity is dead.
- */
- public abstract boolean isDead(Entity entity);
-
- /**
- * Checks if the entity is valid.
- *
- * Valid means the entity has to be alive and currently
- * spawned in a world.
- *
- * @param entity The entity whose validity you want to check.
- * @return {@code true} if the entity is 'valid'.
- */
- public abstract boolean isValid(Entity entity);
-
- /**
- * Gets the current server containing the entity.
- *
- * @param entity The entity whose server you want to get.
- * @return The server instance.
- */
- public abstract Server getServer(Entity entity);
-
- /**
- * Returns a list of all passengers currently riding
- * on the entity.
- *
- * Note that most entities are only able to hold only
- * one passenger and the list will likely contain only
- * one element. Boats from newer versions can contain
- * up to two passengers for example.
- *
- * @param entity The entity whose passengers you want to get.
- * @return A list of all passengers of the given entity.
- */
- public abstract List getPassengers(Entity entity);
-
- /**
- * Adds a new passenger to the given entity.
- *
- * Note that most entities can only hold one passenger.
- * In this case the old entity will be removed in order
- * to hold the new passenger provided in this method.
- *
- * @param entity The entity you want to add the passenger to.
- * @param passenger The passenger you want to add.
- * @return {@code true} if the action was successful.
- */
- public abstract boolean addPassenger(Entity entity, Entity passenger);
-
- /**
- * Removes a passenger from the given entity.
- *
- * @param entity The entity you want to remove the passenger from.
- * @param passenger The passenger you want to remove.
- * @return {@code true} if the action succeeded.
- */
- public abstract boolean removePassenger(Entity entity, Entity passenger);
-
- /**
- * Checks if the given entity has no passengers.
- *
- * @param entity The entity you want to check.
- * @return {@code true} if the entity has no passengers at all.
- */
- public abstract boolean isEmpty(Entity entity);
-
- /**
- * Ejects any passenger currently riding on the
- * given entity.
- *
- * @param entity The entity you want to eject all
- * passengers of.
- * @return {@code true} if there were any passengers to eject.
- */
- public abstract boolean eject(Entity entity);
-
- /**
- * Gets the current fall distance of the current entity.
- *
- * The fall distance is the distance of blocks in the y-axis
- * the player is falling down. The higher the fall distance
- * the higher the fall damage. If the player is currently on
- * ground, the fall distance will be 0.
- *
- * @param entity The entity whose fall distance you want to get.
- * @return The current fall distance of the entity.
- */
- public abstract float getFallDistance(Entity entity);
-
- /**
- * Sets the current fall distance of the current entity.
- *
- * The fall distance is the distance of blocks in the y-axis
- * the player is falling down. The higher the fall distance
- * the higher the fall damage. If the player is currently on
- * ground, the fall distance will be 0.
- *
- * @param entity The entity whose fall distance you want to set.
- * @param fallDistance The new fall distance you want to set.
- */
- public abstract void setFallDistance(Entity entity, float fallDistance);
-
- /**
- * Sets the last damage cause the entity has suffered.
- *
- * @param entity The entity whose damage cause you want to set.
- * @param event The instance of the last entity damage event containing
- * the last damage cause.
- */
- public abstract void setLastDamageCause(Entity entity, EntityDamageEvent event);
-
- /**
- * Gets the last damage cause. If the entity has not been damaged
- * so far, it will return null.
- *
- * @param entity The entity whose last damage cause you want to get.
- * @return The last damage event instance containing the last
- * damage cause.
- */
- public abstract EntityDamageEvent getLastDamageCause(Entity entity);
-
- /**
- * Returns a unique as well as persistent id for
- * the given entity. For players, the player UUID will
- * be returned.
- *
- * @param entity The entity whose unique id you want to get.
- * @return The UUID of the given entity.
- */
- public abstract UUID getUniqueId(Entity entity);
-
- /**
- * Gets the amount of ticks the entity has been alive.
- * This number is equivalent to the 'age' property in entities.
- *
- * @param entity The entity whose lifetime you want to get.
- * @return The age of the entity.
- */
- public abstract int getTicksLived(Entity entity);
-
- /**
- * Gets the amount of ticks the entity has been alive.
- * This number is equivalent to the 'age' property in entities.
- *
- * @param entity The entity whose lifetime you want to get.
- * @param ticksLived The amount of ticks you want to set.
- * May not be less than one tick.
- */
- public abstract void setTicksLived(Entity entity, int ticksLived);
-
- // TODO: play effect public abstract void playEffect(@NotNull EntityEffect var1);
-
- // public abstract EntityType getType();
-
- /**
- * Returns true if the entity is currently inside a vehicle.
- *
- * @param entity The entity you want to check.
- * @return {@code true} if the entity is inside a vehicle.
- */
- public abstract boolean isInsideVehicle(Entity entity);
-
- /**
- * Makes the entity leave its current vehicle.
- *
- * @param entity The entity you want to kick from its
- * vehicle.
- * @return {@code true} if the entity was actually removed
- * and has been sitting in a vehicle before.
- */
- public abstract boolean leaveVehicle(Entity entity);
-
- /**
- * Gets the current vehicle of the given entity.
- *
- * @param entity The entity whose vehicle you want to check.
- * @return The vehicle of the entity. If the entity
- * has no vehicle, null will be returned.
- */
- public abstract Entity getVehicle(Entity entity);
-
- /**
- * Sets the custom name of an entity visible or invisible
- * for the clients.
- *
- * @param entity The entity whose nametag you want to hide/show.
- * @param visible {@code true} if it should be visible
- * {@code false} if it should not be visible.
- */
- public abstract void setCustomNameVisible(Entity entity, boolean visible);
-
- /**
- * Checks if the custom name of the given entity is
- * currently visible.
- *
- * @param entity The entity whose nametag visibility you want to check.
- * @return {@code true} if the custom name is visible.
- */
- public abstract boolean isCustomNameVisible(Entity entity);
-
- @SinceKelpVersion(KelpVersion.MC_1_9_0)
- public abstract void setGlowing(Entity entity, boolean glowing);
-
- @SinceKelpVersion(KelpVersion.MC_1_9_0)
- public abstract boolean isGlowing(Entity entity);
-
- // public abstract void setInvulnerable(boolean var1);
-
- // public abstract boolean isInvulnerable();
-
- /**
- * Checks whether the entity is currently silent.
- *
- * If the silent flag is set, the entity will not
- * produce any sounds.
- *
- * @param entity The entity you want to check.
- * @return {@code true} if the entity is silent
- */
- public abstract boolean isSilent(Entity entity);
-
- /**
- * Makes the entity silent or unsilent.
- *
- * If the silent flag is set, the entity will not
- * produce any sounds.
- *
- * @param entity The entity you want to make silent/unsilent.
- * @param silent {@code true} if you want to make the
- * entity silent,
- * {@code false} if not.
- */
- public abstract void setSilent(Entity entity, boolean silent);
-
- // public abstract boolean hasGravity(Entity entity);
-
- // public abstract void setGravity(Entity entity, boolean gravity);
-
- // public abstract int getPortalCooldown();
-
- // public abstract void setPortalCooldown(int var1);
-
- // public abstract PistonMoveReaction getPistonMoveReaction();
-
- // public abstract BlockFace getFacing();
-
- // public abstract Pose getPose();
-
-}
diff --git a/core/src/main/java/de/pxav/kelp/core/entity/version/LivingEntityVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/entity/version/LivingEntityVersionTemplate.java
deleted file mode 100644
index 79427daf..00000000
--- a/core/src/main/java/de/pxav/kelp/core/entity/version/LivingEntityVersionTemplate.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.pxav.kelp.core.entity.version;
-
-import de.pxav.kelp.core.application.KelpVersionTemplate;
-import de.pxav.kelp.core.world.KelpLocation;
-import org.bukkit.Location;
-import org.bukkit.entity.LivingEntity;
-
-/**
- * A class description goes here.
- *
- * @author pxav
- */
-@KelpVersionTemplate
-public abstract class LivingEntityVersionTemplate {
-
- public abstract KelpLocation getEyeLocation(LivingEntity livingEntity);
-
-}
diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryCloseEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryCloseEvent.java
index 6fbff405..21758395 100644
--- a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryCloseEvent.java
+++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryCloseEvent.java
@@ -2,9 +2,7 @@
import de.pxav.kelp.core.inventory.type.KelpInventory;
import de.pxav.kelp.core.player.KelpPlayer;
-import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
-import org.bukkit.event.player.PlayerEvent;
/**
* This event is called when a player closes their {@link KelpInventory}
diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryOpenEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryOpenEvent.java
index 2bb254bb..2cc1021d 100644
--- a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryOpenEvent.java
+++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryOpenEvent.java
@@ -2,9 +2,7 @@
import de.pxav.kelp.core.inventory.type.KelpInventory;
import de.pxav.kelp.core.player.KelpPlayer;
-import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
-import org.bukkit.event.player.PlayerEvent;
/**
* This event is triggered when a player opens a {@link KelpInventory} or
diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryUpdateEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryUpdateEvent.java
index eeb5dd7e..82a7e514 100644
--- a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryUpdateEvent.java
+++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpInventoryUpdateEvent.java
@@ -2,9 +2,7 @@
import de.pxav.kelp.core.inventory.type.KelpInventory;
import de.pxav.kelp.core.player.KelpPlayer;
-import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
-import org.bukkit.event.player.PlayerEvent;
/**
* This event is called when a {@link KelpInventory} is updated. This does not
diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerLoginEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerLoginEvent.java
index 3945bc52..9f40e403 100644
--- a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerLoginEvent.java
+++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerLoginEvent.java
@@ -3,7 +3,6 @@
import de.pxav.kelp.core.player.KelpPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
-import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerLoginEvent;
/**
diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerUpdateSettingsEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerUpdateSettingsEvent.java
index 8a741d9d..156db418 100644
--- a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerUpdateSettingsEvent.java
+++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerUpdateSettingsEvent.java
@@ -3,7 +3,6 @@
import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.player.PlayerChatVisibility;
import org.bukkit.event.HandlerList;
-import org.bukkit.event.player.PlayerEvent;
/**
* This event is triggered when the client settings of a player change.
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/InventoryConstants.java b/core/src/main/java/de/pxav/kelp/core/inventory/InventoryConstants.java
new file mode 100644
index 00000000..8fdabe15
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/InventoryConstants.java
@@ -0,0 +1,14 @@
+package de.pxav.kelp.core.inventory;
+
+import de.pxav.kelp.core.inventory.widget.GroupedWidget;
+
+import java.util.function.Predicate;
+
+public class InventoryConstants {
+
+ public static final int NOT_RENDERED_SIMPLE_WIDGET = -1;
+
+ public static final Predicate NOT_RENDERED_GROUPED_WIDGET =
+ groupedWidget -> groupedWidget.getCoveredSlots().isEmpty() || groupedWidget.getCoveredSlots() == null;
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/KelpInventoryRepository.java b/core/src/main/java/de/pxav/kelp/core/inventory/KelpInventoryRepository.java
index 295cb366..f1905499 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/KelpInventoryRepository.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/KelpInventoryRepository.java
@@ -142,8 +142,7 @@ public void updateInventory(KelpPlayer player) {
KelpInventory> kelpInventory = playerInventories.get(player.getUUID());
if (kelpInventory == null) {
- PlayerInventory playerInventory = PlayerInventory.of(player);
- playerInventory.updateWidgets();
+ player.getInventory().updateWidgets();
return;
}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/item/KelpItem.java b/core/src/main/java/de/pxav/kelp/core/inventory/item/KelpItem.java
index bd690211..d8fc7c54 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/item/KelpItem.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/item/KelpItem.java
@@ -10,12 +10,10 @@
import de.pxav.kelp.core.inventory.listener.KelpListenerRepository;
import de.pxav.kelp.core.inventory.material.KelpMaterial;
import de.pxav.kelp.core.inventory.metadata.ItemMetadata;
-import de.pxav.kelp.core.inventory.metadata.ItemMetadataVersionTemplate;
import de.pxav.kelp.core.inventory.metadata.LeatherArmorMetadata;
import de.pxav.kelp.core.inventory.version.ItemVersionTemplate;
import de.pxav.kelp.core.player.KelpPlayer;
import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/listener/KelpClickEvent.java b/core/src/main/java/de/pxav/kelp/core/inventory/listener/KelpClickEvent.java
index c660a621..da21e9f9 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/listener/KelpClickEvent.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/listener/KelpClickEvent.java
@@ -1,7 +1,6 @@
package de.pxav.kelp.core.inventory.listener;
import de.pxav.kelp.core.inventory.item.KelpItem;
-import de.pxav.kelp.core.inventory.type.KelpInventory;
import de.pxav.kelp.core.player.KelpPlayer;
import java.util.function.Consumer;
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/listener/PlayerInventoryStateListener.java b/core/src/main/java/de/pxav/kelp/core/inventory/listener/PlayerInventoryStateListener.java
index 0aaa3988..427d3ed2 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/listener/PlayerInventoryStateListener.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/listener/PlayerInventoryStateListener.java
@@ -3,7 +3,6 @@
import com.google.inject.Inject;
import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.player.KelpPlayerRepository;
-import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryCloseEvent;
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/metadata/FireworkMetadata.java b/core/src/main/java/de/pxav/kelp/core/inventory/metadata/FireworkMetadata.java
new file mode 100644
index 00000000..d44b18b0
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/metadata/FireworkMetadata.java
@@ -0,0 +1,50 @@
+package de.pxav.kelp.core.inventory.metadata;
+
+import com.google.common.collect.Lists;
+import org.bukkit.FireworkEffect;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public class FireworkMetadata implements ItemMetadata {
+
+ private int height = 20;
+ private Collection effects = Lists.newArrayList();
+
+ public static FireworkMetadata create() {
+ return new FireworkMetadata();
+ }
+
+ public Collection getEffects() {
+ return effects;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public boolean hasAnyEffects() {
+ return !effects.isEmpty();
+ }
+
+ public FireworkMetadata height(int height) {
+ this.height = height;
+ return this;
+ }
+
+ public FireworkMetadata addEffect(FireworkEffect... effectsToAdd) {
+ effects.addAll(Arrays.asList(effectsToAdd));
+ return this;
+ }
+
+ public FireworkMetadata removeEffect(FireworkEffect toRemove) {
+ effects.remove(toRemove);
+ return this;
+ }
+
+ public FireworkMetadata clearEffects() {
+ this.effects.clear();
+ return this;
+ }
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/metadata/ItemMetadataVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/inventory/metadata/ItemMetadataVersionTemplate.java
index db0f1307..e1796049 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/metadata/ItemMetadataVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/metadata/ItemMetadataVersionTemplate.java
@@ -30,6 +30,8 @@ public abstract class ItemMetadataVersionTemplate {
*/
public abstract ItemStack applyMetadata(ItemStack itemStack, ItemMetadata metadata);
+ public abstract ItemMetadata getMetadata(ItemMeta itemMeta);
+
/**
* Retrieves the ItemMeta of the given bukkit item stack and converts
* it to a kelp {@link ItemMetadata}. This is used by {@link KelpItem#from(ItemStack)}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/AbstractHorseInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/AbstractHorseInventory.java
new file mode 100644
index 00000000..18a434e4
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/AbstractHorseInventory.java
@@ -0,0 +1,11 @@
+package de.pxav.kelp.core.inventory.type;
+
+import de.pxav.kelp.core.inventory.item.KelpItem;
+
+public interface AbstractHorseInventory> extends StorageInventory {
+
+ KelpItem getSaddle();
+
+ T setSaddle(KelpItem saddleItem);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/AnimatedInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/AnimatedInventory.java
index f6808055..c6a47f31 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/type/AnimatedInventory.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/AnimatedInventory.java
@@ -99,22 +99,7 @@ public Inventory render(KelpPlayer player) {
Inventory inventory = inventoryVersionTemplate.createInventory(this.size, title.states().get(0));
- for (SimpleWidget current : simpleWidgets) {
- KelpItem item = current.render();
- if (!item.hasTagKey("interactionAllowed")) {
- item.cancelInteractions();
- }
- inventory.setItem(item.getSlot(), item.getItemStack());
- }
-
- for (GroupedWidget current : groupedWidgets) {
- current.render(player).forEach(item -> {
- if (!item.hasTagKey("interactionAllowed")) {
- item.cancelInteractions();
- }
- inventory.setItem(item.getSlot(), item.getItemStack());
- });
- }
+ widgetsToInventory(inventory, player);
return inventory;
}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/HorseInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/HorseInventory.java
new file mode 100644
index 00000000..6565c4ca
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/HorseInventory.java
@@ -0,0 +1,11 @@
+package de.pxav.kelp.core.inventory.type;
+
+import de.pxav.kelp.core.inventory.item.KelpItem;
+
+public interface HorseInventory extends AbstractHorseInventory {
+
+ KelpItem getArmor();
+
+ HorseInventory setArmor(KelpItem armorItem);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/InventoryOwner.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/InventoryOwner.java
new file mode 100644
index 00000000..23175945
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/InventoryOwner.java
@@ -0,0 +1,13 @@
+package de.pxav.kelp.core.inventory.type;
+
+import org.bukkit.inventory.InventoryHolder;
+
+public interface InventoryOwner {
+
+ static InventoryOwner from(InventoryHolder holder) {
+ return null;
+ }
+
+ StorageInventory> getInventory();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/KelpInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/KelpInventory.java
index d3d1b136..e080c70c 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/type/KelpInventory.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/KelpInventory.java
@@ -1,19 +1,16 @@
package de.pxav.kelp.core.inventory.type;
import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+import de.pxav.kelp.core.inventory.InventoryConstants;
import de.pxav.kelp.core.inventory.item.KelpItem;
import de.pxav.kelp.core.inventory.version.InventoryVersionTemplate;
import de.pxav.kelp.core.inventory.widget.GroupedWidget;
import de.pxav.kelp.core.inventory.widget.SimpleWidget;
import de.pxav.kelp.core.inventory.widget.Widget;
import de.pxav.kelp.core.player.KelpPlayer;
-import org.bukkit.Material;
-import org.bukkit.block.Dispenser;
import org.bukkit.inventory.Inventory;
import java.util.List;
-import java.util.Set;
/**
* Represents the basis for every GUI inventory you can build
@@ -113,6 +110,66 @@ public T addWidget(GroupedWidget widget) {
*/
public abstract Inventory render(KelpPlayer player);
+ protected void widgetsToInventory(Inventory inventory, KelpPlayer player) {
+ for (SimpleWidget current : simpleWidgets) {
+
+ // render stateless widgets only once.
+ if (!current.isStateful() && current.getCoveredSlot() == InventoryConstants.NOT_RENDERED_SIMPLE_WIDGET) {
+ KelpItem item = current.render();
+ if (!item.hasTagKey("interactionAllowed")) {
+ item.cancelInteractions();
+ }
+ inventory.setItem(item.getSlot(), item.getItemStack());
+ continue;
+ }
+
+ if (current.getCoveredSlot() != -1) {
+ inventory.clear(current.getCoveredSlot());
+ }
+
+ KelpItem item = current.render();
+
+ // if items are not explicitly stated as interactable
+ // cancel interactions by default
+ if (!item.hasTagKey("interactionAllowed")) {
+ item.cancelInteractions();
+ }
+
+ inventory.setItem(item.getSlot(), item.getItemStack());
+ }
+
+ for (GroupedWidget current : groupedWidgets) {
+ if (!current.isStateful() && InventoryConstants.NOT_RENDERED_GROUPED_WIDGET.test(current)) {
+ current.render(player).forEach(item -> {
+
+ // if items are not explicitly stated as interactable
+ // cancel interactions by default
+ if (!item.hasTagKey("interactionAllowed")) {
+ item.cancelInteractions();
+ }
+
+ inventory.setItem(item.getSlot(), item.getItemStack());
+ });
+ continue;
+ }
+
+ for (Integer slot : current.getCoveredSlots()) {
+ inventory.clear(slot);
+ }
+
+ current.render(player).forEach(item -> {
+
+ // if items are not explicitly stated as interactable
+ // cancel interactions by default
+ if (!item.hasTagKey("interactionAllowed")) {
+ item.cancelInteractions();
+ }
+
+ inventory.setItem(item.getSlot(), item.getItemStack());
+ });
+ }
+ }
+
/**
* Updates all widgets contained by this inventory by clearing
* all contents and then adding them back widget by widget.
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/LlamaInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/LlamaInventory.java
new file mode 100644
index 00000000..924bd7f8
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/LlamaInventory.java
@@ -0,0 +1,11 @@
+package de.pxav.kelp.core.inventory.type;
+
+import de.pxav.kelp.core.inventory.item.KelpItem;
+
+public interface LlamaInventory extends AbstractHorseInventory {
+
+ KelpItem getDecoration();
+
+ LlamaInventory setDecoration(KelpItem decoration);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/PlayerInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/PlayerInventory.java
index 49d7f174..679ced27 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/type/PlayerInventory.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/PlayerInventory.java
@@ -1,15 +1,11 @@
package de.pxav.kelp.core.inventory.type;
-import de.pxav.kelp.core.KelpPlugin;
-import de.pxav.kelp.core.common.ConcurrentSetMultimap;
import de.pxav.kelp.core.inventory.item.KelpItem;
-import de.pxav.kelp.core.inventory.version.PlayerInventoryVersionTemplate;
import de.pxav.kelp.core.inventory.widget.GroupedWidget;
import de.pxav.kelp.core.inventory.widget.SimpleWidget;
import de.pxav.kelp.core.player.KelpPlayer;
import java.util.Set;
-import java.util.UUID;
/**
* Represents the personal inventory of a {@link KelpPlayer} which
@@ -24,62 +20,7 @@
*
* @author pxav
*/
-public class PlayerInventory {
-
- // the version template used for player inventory manipulation
- private PlayerInventoryVersionTemplate versionTemplate;
-
- // the owner of this inventory
- private KelpPlayer player;
-
- // all widgets currently stored by all players on the server.
- // the uuid represents the player uuid who owns the widget.
- private static ConcurrentSetMultimap simpleWidgets = ConcurrentSetMultimap.create();
- private static ConcurrentSetMultimap groupedWidgets = ConcurrentSetMultimap.create();
-
- /**
- * Gets the inventory of a specific {@link KelpPlayer}.
- * Alternatively, you can use {@link KelpPlayer#getInventory()} to get
- * the inventory directly from the kelp player class.
- *
- * @param player The player you want to get the inventory of.
- * @return The {@link PlayerInventory} of the given player.
- */
- public static PlayerInventory of(KelpPlayer player) {
- return new PlayerInventory(
- player,
- KelpPlugin.getInjector().getInstance(PlayerInventoryVersionTemplate.class)
- );
- }
-
- private PlayerInventory(KelpPlayer player, PlayerInventoryVersionTemplate versionTemplate) {
- this.player = player;
- this.versionTemplate = versionTemplate;
- }
-
- /**
- * Gets all items stored in this player inventory. This includes
- * all slots (main storage, armor and hot bar).
- *
- * @return A set of all items that are currently in the player's inventory.
- */
- public Set getItems() {
- return versionTemplate.getItems(player.getBukkitPlayer());
- }
-
- /**
- * Gets an item at a specific slot. The slot count starts at the
- * first hotbar slot from 0-8 and then goes on from the uppermost
- * line of the main storage.
- *
- * If there is no item at the given slot, {@code null} will be returned.
- *
- * @param slot The slot of the item you want to get.
- * @return The item stored at the given slot in the player inventory.
- */
- public KelpItem getItemAt(int slot) {
- return versionTemplate.getItemAt(player.getBukkitPlayer(), slot);
- }
+public interface PlayerInventory extends StorageInventory {
/**
* Gets all items stored in the player's hotbar. The hotbar
@@ -88,370 +29,29 @@ public KelpItem getItemAt(int slot) {
*
* @return A set of all items stored in the player's hotbar.
*/
- public Set getHotBarItems() {
- return versionTemplate.getHotBarItems(player.getBukkitPlayer());
- }
-
- /**
- * Sets the helmet the player is wearing to the given item.
- * Specifically for helmets, you can not only use the normal armor items
- * such as leather helmet, gold helmet, etc. but also blocks, heads or banners
- * to set them as a player head.
- *
- * @param helmet The item of the helmet you want to set. This can be
- * a normal armor helmet or any banner, head or even some blocks.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory setHelmet(KelpItem helmet) {
- versionTemplate.setHelmet(player.getBukkitPlayer(), helmet);
- return this;
- }
-
- /**
- * Sets the chest plate of the player owning this inventory.
- * Unlike in the helmet method, you cannot pass other item materials
- * than chest plates here.
- *
- * @param chestPlate The chest plate item you want to set.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory setChestPlate(KelpItem chestPlate) {
- versionTemplate.setChestPlate(player.getBukkitPlayer(), chestPlate);
- return this;
- }
-
- /**
- * Sets the leggings of the player owning this inventory.
- * Unlike in the helmet method, you cannot pass other item materials
- * than leggings here.
- *
- * @param leggings The leggings item you want to set.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory setLeggings(KelpItem leggings) {
- versionTemplate.setLeggings(player.getBukkitPlayer(), leggings);
- return this;
- }
-
- /**
- * Sets the boots of the player owning this inventory.
- * Unlike in the helmet method, you cannot pass other item materials
- * than boots here.
- *
- * @param boots The chest plate item you want to set.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory setBoots(KelpItem boots) {
- versionTemplate.setBoots(player.getBukkitPlayer(), boots);
- return this;
- }
-
- /**
- * Gets the helmet the player is currently wearing.
- * Unlike the other armor parts, the helmet can also be of
- * materials other than normal helmets, but also banners and some
- * blocks.
- *
- * If the player has no helmet, {@code null} will be returned.
- *
- * @return The item representing the player's helmet.
- */
- public KelpItem getHelmet() {
- return versionTemplate.getHelmet(player.getBukkitPlayer());
- }
-
- /**
- * Gets the chest plate the player is currently wearing.
- *
- * If the player has no chest plate, {@code null} will be returned.
- *
- * @return The item representing the player's chest plate.
- */
- public KelpItem getChestPlate() {
- return versionTemplate.getChestPlate(player.getBukkitPlayer());
- }
-
- /**
- * Gets the leggings the player is currently wearing.
- *
- * If the player has no leggings, {@code null} will be returned.
- *
- * @return The item representing the player's chest plate.
- */
- public KelpItem getLeggings() {
- return versionTemplate.getLeggings(player.getBukkitPlayer());
- }
-
- /**
- * Gets the boots the player is currently wearing.
- *
- * If the player has no boots, {@code null} will be returned.
- *
- * @return The item representing the player's chest plate.
- */
- public KelpItem getBoots() {
- return versionTemplate.getBoots(player.getBukkitPlayer());
- }
-
- /**
- * Stores an item in the player inventory at the given slot location.
- * If there already is an item present at the given location, this
- * item will be overwritten. If you want to avoid this and rather
- * search for free inventory space use {@link #addItem(KelpItem)} instead.
- *
- * @param slot The slot to store the item at.
- * @param item The item to store at the given slot.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory setItem(int slot, KelpItem item) {
- versionTemplate.setItem(player.getBukkitPlayer(), slot, item);
- return this;
- }
-
- /**
- * Adds a new item to the player's inventory.
- * This method won't overwrite any existing items, but try to find free
- * space in the inventory. If there is already a {@link KelpItem} with
- * the same data (same display name, item description, material, tags, etc.)
- * and this item has not yet exceeded its maximum stack size, it will add
- * the item to an existing stack.
- *
- * @param item The item to add.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory addItem(KelpItem item) {
- versionTemplate.addItem(player.getBukkitPlayer(), item);
- return this;
- }
-
- /**
- * Gets the item that is currently stored in the player's
- * main hand (the player's right hand).
- *
- * If the player has no item in hand, {@code null} will be returned.
- *
- * @return The item the player is holding right now.
- */
- public KelpItem getItemInHand() {
- return versionTemplate.getItemInHand(player.getBukkitPlayer());
- }
-
- /**
- * Sets the item in the player's main hand (the player's right hand).
- *
- * Unlike the off hand, the main hand can be used in all server versions.
- *
- * @param item The item to set in the player's main hand.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory setItemInHand(KelpItem item) {
- versionTemplate.setItemInHand(player.getBukkitPlayer(), item);
- return this;
- }
-
- /**
- * Gets the item that is currently in the player's off hand
- * (the player's left hand).
- *
- * Please note that off hands were introduced in {code MC 1.9} and are
- * therefore not available on 1.8 servers. But this method won't throw
- * an error if you do it anyways.
- *
- * If the player has no item in his off hand, {@code null} will be returned.
- *
- * @return The item that is stored in the player's off hand right now.
- */
- public KelpItem getItemInOffHand() {
- return versionTemplate.getItemInOffHand(player.getBukkitPlayer());
- }
-
- /**
- * Sets the item in the player's off hand (the player's left hand).
- *
- * Please note that off hands were introduced in {code MC 1.9} and are
- * therefore not available on 1.8 servers. But this method won't throw
- * an error if you do it anyways.
- *
- * @param item The item to set in the player's off hand.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory setItemInOffHand(KelpItem item) {
- versionTemplate.setItemInOffHand(player.getBukkitPlayer(), item);
- return this;
- }
-
- /**
- * Adds a new {@link SimpleWidget} to the player's inventory.
- * This method does not immediately render the widget, but only
- * adds it to the cache. To make the widget appear, call
- * {@link #updateWidgets()} first.
- *
- * @param simpleWidget The simple widget you want to add to the inventory.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory addWidget(SimpleWidget simpleWidget) {
- simpleWidgets.put(player.getUUID(), simpleWidget);
- return this;
- }
-
- /**
- * Adds a new {@link GroupedWidget} to the player's inventory.
- * This method does not immediately render the widget, but only
- * adds it to the cache. To make the widget appear, call
- * {@link #updateWidgets()} first.
- *
- * @param groupedWidget The grouped widget you want to add to the inventory.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory addWidget(GroupedWidget groupedWidget) {
- groupedWidgets.put(player.getUUID(), groupedWidget);
- return this;
- }
-
- /**
- * Removes all {@link SimpleWidget simple widgets} of a certain type.
- * This method removes the widget from the cache as well as the inventory,
- * so that no items are there anymore.
- *
- * @param widgetClass The class of the widget type you want to remove.
- * If you pass {@code ToggleableWidget.class} here,
- * all {@link de.pxav.kelp.core.inventory.widget.ToggleableWidget ToggleableWidgets}
- * will be removed from the inventory.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory removeSimpleWidget(Class extends SimpleWidget> widgetClass) {
- simpleWidgets.get(player.getUUID()).forEach(widget -> {
- if (widgetClass.getName().equalsIgnoreCase(widget.getClass().getName())) {
- removeWidget(widget);
- }
- });
- return this;
- }
-
- /**
- * Removes all {@link GroupedWidget grouped widgets} of a certain type.
- * This method removes the widget from the cache as well as the inventory,
- * so that no items are there anymore.
- *
- * @param widgetClass The class of the widget type you want to remove.
- * If you pass {@code Pagination.class} here,
- * all {@link de.pxav.kelp.core.inventory.widget.Pagination Paginations}
- * will be removed from the inventory.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory removeGroupedWidget(Class extends GroupedWidget> widgetClass) {
- groupedWidgets.get(player.getUUID()).forEach(widget -> {
- if (widgetClass.getName().equalsIgnoreCase(widget.getClass().getName())) {
- removeWidget(widget);
- }
- });
- return this;
- }
-
- /**
- * Removes a specific {@link SimpleWidget} from the inventory.
- * This method removes the widget from the cache as well as
- * the inventory itself, so there won't be any items rendered by
- * this widget anymore.
- *
- * @param widget The object of the widget you want to remove.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory removeWidget(SimpleWidget widget) {
- player.getBukkitPlayer().getInventory().clear(widget.getCoveredSlot());
- widget.onRemove();
- simpleWidgets.remove(player.getUUID(), widget);
- return this;
- }
-
- /**
- * Removes a specific {@link GroupedWidget} from the inventory.
- * This method removes the widget from the cache as well as
- * the inventory itself, so there won't be any items rendered by
- * this widget anymore.
- *
- * @param widget The object of the widget you want to remove.
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory removeWidget(GroupedWidget widget) {
- widget.getCoveredSlots().forEach(slot -> player.getBukkitPlayer().getInventory().clear(slot));
- widget.onRemove();
- groupedWidgets.remove(player.getUUID(), widget);
- return this;
- }
-
- /**
- * Removes all widgets from the player's inventory.
- * This will not only remove them from the cache, but also from
- * the visible inventory itself.
- *
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory removeAllWidgets() {
- simpleWidgets.getOrEmpty(player.getUUID()).forEach(this::removeWidget);
- groupedWidgets.getOrEmpty(player.getUUID()).forEach(this::removeWidget);
- return this;
- }
-
- /**
- * Updates all widgets inside this player inventory.
- *
- * This is also equivalent to the {@link KelpInventory#render(KelpPlayer) render method} you
- * already know from KelpInventories, so call this method even if you
- * have just put widgets into the inventory for the first time.
- *
- * @return An instance of the current inventory for fluent builder design.
- */
- public PlayerInventory updateWidgets() {
- for (SimpleWidget current : simpleWidgets.getOrEmpty(player.getUUID())) {
- if (!current.isStateful()) {
- continue;
- }
-
- player.getBukkitPlayer().getInventory().clear(current.getCoveredSlot());
-
- KelpItem item = current.render();
+ Set getHotBarItems();
- // if items are not explicitly stated as interactable
- // cancel interactions by default
- if (!item.hasTagKey("interactionAllowed")) {
- item.cancelInteractions();
- }
+ PlayerInventory addWidget(SimpleWidget simpleWidget);
- setItem(item.getSlot(), item);
- }
+ PlayerInventory addWidget(GroupedWidget groupedWidget);
- for (GroupedWidget current : groupedWidgets.getOrEmpty(player.getUUID())) {
- if (!current.isStateful()) {
- continue;
- }
+ PlayerInventory removeSimpleWidget(Class extends SimpleWidget> widgetClass);
- for (Integer slot : current.getCoveredSlots()) {
- player.getBukkitPlayer().getInventory().clear(slot);
- }
+ PlayerInventory removeGroupedWidget(Class extends GroupedWidget> widgetClass);
- current.render(player).forEach(item -> {
+ PlayerInventory removeWidget(SimpleWidget simpleWidget);
- // if items are not explicitly stated as interactable
- // cancel interactions by default
- if (!item.hasTagKey("interactionAllowed")) {
- item.cancelInteractions();
- }
+ PlayerInventory removeWidget(GroupedWidget groupedWidget);
- setItem(item.getSlot(), item);
- });
- }
+ PlayerInventory removeAllWidgets();
- return this;
- }
+ PlayerInventory updateWidgets();
/**
* Gets the player owning this inventory.
*
* @return The player owning this inventory.
*/
- public KelpPlayer getPlayer() {
- return player;
- }
+ KelpPlayer getPlayer();
}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/SimpleEntityEquipment.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/SimpleEntityEquipment.java
new file mode 100644
index 00000000..9275ff3c
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/SimpleEntityEquipment.java
@@ -0,0 +1,134 @@
+package de.pxav.kelp.core.inventory.type;
+
+import de.pxav.kelp.core.inventory.item.KelpItem;
+
+public interface SimpleEntityEquipment {
+
+ /**
+ * Sets the helmet the player is wearing to the given item.
+ * Specifically for helmets, you can not only use the normal armor items
+ * such as leather helmet, gold helmet, etc. but also blocks, heads or banners
+ * to set them as a player head.
+ *
+ * @param helmet The item of the helmet you want to set. This can be
+ * a normal armor helmet or any banner, head or even some blocks.
+ * @return An instance of the current inventory for fluent builder design.
+ */
+ SimpleEntityEquipment setHelmet(KelpItem helmet);
+
+ /**
+ * Sets the chest plate of the player owning this inventory.
+ * Unlike in the helmet method, you cannot pass other item materials
+ * than chest plates here.
+ *
+ * @param chestPlate The chest plate item you want to set.
+ * @return An instance of the current inventory for fluent builder design.
+ */
+ SimpleEntityEquipment setChestPlate(KelpItem chestPlate);
+
+ /**
+ * Sets the leggings of the player owning this inventory.
+ * Unlike in the helmet method, you cannot pass other item materials
+ * than leggings here.
+ *
+ * @param leggings The leggings item you want to set.
+ * @return An instance of the current inventory for fluent builder design.
+ */
+ SimpleEntityEquipment setLeggings(KelpItem leggings);
+
+ /**
+ * Sets the boots of the player owning this inventory.
+ * Unlike in the helmet method, you cannot pass other item materials
+ * than boots here.
+ *
+ * @param boots The chest plate item you want to set.
+ * @return An instance of the current inventory for fluent builder design.
+ */
+ SimpleEntityEquipment setBoots(KelpItem boots);
+
+ /**
+ * Gets the helmet the player is currently wearing.
+ * Unlike the other armor parts, the helmet can also be of
+ * materials other than normal helmets, but also banners and some
+ * blocks.
+ *
+ * If the player has no helmet, {@code null} will be returned.
+ *
+ * @return The item representing the player's helmet.
+ */
+ KelpItem getHelmet();
+
+ /**
+ * Gets the chest plate the player is currently wearing.
+ *
+ * If the player has no chest plate, {@code null} will be returned.
+ *
+ * @return The item representing the player's chest plate.
+ */
+ KelpItem getChestPlate();
+
+ /**
+ * Gets the leggings the player is currently wearing.
+ *
+ * If the player has no leggings, {@code null} will be returned.
+ *
+ * @return The item representing the player's chest plate.
+ */
+ KelpItem getLeggings();
+
+ /**
+ * Gets the boots the player is currently wearing.
+ *
+ * If the player has no boots, {@code null} will be returned.
+ *
+ * @return The item representing the player's chest plate.
+ */
+ KelpItem getBoots();
+
+ /**
+ * Gets the item that is currently stored in the player's
+ * main hand (the player's right hand).
+ *
+ * If the player has no item in hand, {@code null} will be returned.
+ *
+ * @return The item the player is holding right now.
+ */
+ KelpItem getItemInHand();
+
+ /**
+ * Sets the item in the player's main hand (the player's right hand).
+ *
+ * Unlike the off hand, the main hand can be used in all server versions.
+ *
+ * @param item The item to set in the player's main hand.
+ * @return An instance of the current inventory for fluent builder design.
+ */
+ SimpleEntityEquipment setItemInHand(KelpItem item);
+
+ /**
+ * Gets the item that is currently in the player's off hand
+ * (the player's left hand).
+ *
+ * Please note that off hands were introduced in {code MC 1.9} and are
+ * therefore not available on 1.8 servers. But this method won't throw
+ * an error if you do it anyways.
+ *
+ * If the player has no item in his off hand, {@code null} will be returned.
+ *
+ * @return The item that is stored in the player's off hand right now.
+ */
+ KelpItem getItemInOffHand();
+
+ /**
+ * Sets the item in the player's off hand (the player's left hand).
+ *
+ * Please note that off hands were introduced in {code MC 1.9} and are
+ * therefore not available on 1.8 servers. But this method won't throw
+ * an error if you do it anyways.
+ *
+ * @param item The item to set in the player's off hand.
+ * @return An instance of the current inventory for fluent builder design.
+ */
+ SimpleEntityEquipment setItemInOffHand(KelpItem item);
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/SimpleInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/SimpleInventory.java
index e48335e2..0b516571 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/type/SimpleInventory.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/SimpleInventory.java
@@ -7,7 +7,6 @@
import de.pxav.kelp.core.inventory.widget.GroupedWidget;
import de.pxav.kelp.core.inventory.widget.SimpleWidget;
import de.pxav.kelp.core.player.KelpPlayer;
-import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import java.util.function.Supplier;
@@ -86,22 +85,7 @@ public void updateTitleOnly(KelpPlayer player) {
public Inventory render(KelpPlayer player) {
Inventory inventory = inventoryVersionTemplate.createInventory(this.size, title.get());
- for (SimpleWidget current : simpleWidgets) {
- KelpItem item = current.render();
- if (!item.hasTagKey("interactionAllowed")) {
- item.cancelInteractions();
- }
- inventory.setItem(item.getSlot(), item.getItemStack());
- }
-
- for (GroupedWidget current : groupedWidgets) {
- current.render(player).forEach(item -> {
- if (!item.hasTagKey("interactionAllowed")) {
- item.cancelInteractions();
- }
- inventory.setItem(item.getSlot(), item.getItemStack());
- });
- }
+ widgetsToInventory(inventory, player);
return inventory;
}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/type/StorageInventory.java b/core/src/main/java/de/pxav/kelp/core/inventory/type/StorageInventory.java
new file mode 100644
index 00000000..f741b919
--- /dev/null
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/type/StorageInventory.java
@@ -0,0 +1,89 @@
+package de.pxav.kelp.core.inventory.type;
+
+import de.pxav.kelp.core.entity.LivingKelpEntity;
+import de.pxav.kelp.core.inventory.item.KelpItem;
+import de.pxav.kelp.core.inventory.material.KelpMaterial;
+import org.bukkit.inventory.Inventory;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Set;
+
+public interface StorageInventory> {
+
+ T addItem(KelpItem... items);
+
+ Collection allItemsWith(KelpMaterial material);
+
+ Collection allItemsWith(KelpItem item);
+
+ T clear();
+
+ T remove(int slot);
+
+ default T remove(Set slots) {
+ for (Integer slot : slots) {
+ remove(slot);
+ }
+ return (T) this;
+ }
+
+ boolean contains(KelpItem item);
+
+ boolean contains(KelpMaterial material);
+
+ boolean containsAtLeast(KelpMaterial material, int minimumAmount);
+
+ boolean containsAtLeast(KelpItem item, int combinedMinimumAmount);
+
+ int first(KelpItem item);
+
+ int first(KelpMaterial material);
+
+ int firstEmptySlot();
+
+ Collection getAllItems();
+
+ Collection getStorageItems();
+
+ InventoryOwner getInventoryOwner();
+
+ KelpItem getItemAt(int slot);
+
+ int getMaxStackSize();
+
+ int getSize();
+
+ default int getRows() {
+ return getSize() / 9;
+ }
+
+ Collection> getViewers();
+
+ boolean isEmpty();
+
+ T remove(KelpItem item);
+
+ T remove(KelpMaterial material);
+
+ T setAllItems(Collection items);
+
+ default T setAllItems(KelpItem[] items) {
+ setAllItems(Arrays.asList(items));
+ return (T) this;
+ }
+
+ T setItem(KelpItem item);
+
+ T setMaxStackSize(int maxStackSize);
+
+ T setAllStorageItems(Collection items);
+
+ default T setAllStorageItems(KelpItem[] items) {
+ setAllStorageItems(Arrays.asList(items));
+ return (T) this;
+ }
+
+ Inventory getBukkitInventory();
+
+}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/util/SlotArea.java b/core/src/main/java/de/pxav/kelp/core/inventory/util/SlotArea.java
index 86215a20..b1b613dd 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/util/SlotArea.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/util/SlotArea.java
@@ -9,11 +9,11 @@
* This class is used to easily represent a collection of slots
* inside a {@link de.pxav.kelp.core.inventory.type.KelpInventory}.
*
- * If you want to create a {@link de.pxav.kelp.core.inventory.widget.Pagination pagination}
+ * If you want to create a {@link SimplePagination pagination}
* for example, where you want to use the entire inventory space as pagination area, it would be a pain
* to pass all slots individually. It would be more convenient to just calculate
* a rectangular area and pass all slots of this area in the
- * {@link de.pxav.kelp.core.inventory.widget.Pagination#contentSlots(int...)} method,
+ * {@link SimplePagination#contentSlots(int...)} method,
* which can be achieved using {@link #rectangle(int, int)}.
*
* Other use cases would be if you want to create a line separator inside a GUI.
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/version/InventoryVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/inventory/version/InventoryVersionTemplate.java
index da979907..22049c05 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/version/InventoryVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/version/InventoryVersionTemplate.java
@@ -1,6 +1,7 @@
package de.pxav.kelp.core.inventory.version;
import de.pxav.kelp.core.application.KelpVersionTemplate;
+import de.pxav.kelp.core.inventory.type.StorageInventory;
import org.bukkit.inventory.Inventory;
/**
@@ -22,4 +23,6 @@ public abstract class InventoryVersionTemplate {
*/
public abstract Inventory createInventory(int size, String title);
+ public abstract StorageInventory> getStorageInventory(Inventory bukkitInventory);
+
}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/version/PlayerInventoryVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/inventory/version/StorageInventoryVersionTemplate.java
similarity index 98%
rename from core/src/main/java/de/pxav/kelp/core/inventory/version/PlayerInventoryVersionTemplate.java
rename to core/src/main/java/de/pxav/kelp/core/inventory/version/StorageInventoryVersionTemplate.java
index 67477320..41552ca5 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/version/PlayerInventoryVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/version/StorageInventoryVersionTemplate.java
@@ -14,10 +14,10 @@
* @author pxav
*/
@KelpVersionTemplate
-public abstract class PlayerInventoryVersionTemplate {
+public abstract class StorageInventoryVersionTemplate {
/**
- * Gets all items stored in this player inventory. This includes
+ * Gets all items stored in this inventory. This includes
* all slots (main storage, armor and hot bar).
*
* @param player The player to get the items of.
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/widget/GroupedWidget.java b/core/src/main/java/de/pxav/kelp/core/inventory/widget/GroupedWidget.java
index 6f04d34f..c4f51827 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/widget/GroupedWidget.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/widget/GroupedWidget.java
@@ -4,7 +4,6 @@
import de.pxav.kelp.core.player.KelpPlayer;
import java.util.Collection;
-import java.util.List;
import java.util.Set;
/**
@@ -35,6 +34,8 @@ public interface GroupedWidget extends Widget {
/**
* Gets all slots covered by this widget in the
* target inventory.
+ * IMPORTANT: If your widget has not been rendered at least
+ * once, this must return either {@code null} or an empty set.
*
* @return A set of all slots covered by this widget in the target inventory.
*/
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/widget/Pagination.java b/core/src/main/java/de/pxav/kelp/core/inventory/widget/Pagination.java
index 0ec801cf..928b05aa 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/widget/Pagination.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/widget/Pagination.java
@@ -34,6 +34,9 @@ public class Pagination extends AbstractWidget implements GroupedWid
// that would be returned by the supplier right now.
private List currentContentWidgets = ImmutableList.of();
+ // if the widget has at least been rendered once.
+ private boolean rendered = false;
+
// navigation buttons
private KelpItem nextButton;
private KelpItem previousButton;
@@ -215,6 +218,8 @@ public Collection render(KelpPlayer player) {
output.add(previousButton);
}
+ rendered = true;
+
return output;
}
@@ -225,6 +230,9 @@ public void onRemove() {
@Override
public Set getCoveredSlots() {
+ if (!rendered) {
+ return Sets.newHashSet();
+ }
Set output = Sets.newHashSet(contentSlots);
output.add(nextButton.getSlot());
output.add(previousButton.getSlot());
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/widget/SimpleWidget.java b/core/src/main/java/de/pxav/kelp/core/inventory/widget/SimpleWidget.java
index 92cb3f9c..43cd8411 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/widget/SimpleWidget.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/widget/SimpleWidget.java
@@ -31,6 +31,8 @@ public interface SimpleWidget extends Widget {
/**
* Gets the slot covered by this widget in the target inventory.
+ * IMPORTANT: This number has to be {@link de.pxav.kelp.core.inventory.InventoryConstants#NOT_RENDERED_SIMPLE_WIDGET}
+ * if the widget has not been rendered yet.
*
* @return The slot covered in the target inventory.
*/
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatefulItemWidget.java b/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatefulItemWidget.java
index 54918ca1..86213943 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatefulItemWidget.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatefulItemWidget.java
@@ -1,16 +1,14 @@
package de.pxav.kelp.core.inventory.widget;
-import com.google.common.collect.Sets;
+import de.pxav.kelp.core.inventory.InventoryConstants;
import de.pxav.kelp.core.inventory.item.KelpItem;
-import de.pxav.kelp.core.inventory.listener.KelpClickEvent;
-import java.util.Set;
-import java.util.function.Consumer;
import java.util.function.Supplier;
public class StatefulItemWidget extends AbstractWidget implements SimpleWidget {
private Supplier itemSupplier;
+ private int slot = InventoryConstants.NOT_RENDERED_SIMPLE_WIDGET;
public static StatefulItemWidget create() {
return new StatefulItemWidget();
@@ -29,12 +27,13 @@ public boolean isStateful() {
@Override
public KelpItem render() {
KelpItem item = itemSupplier.get();
+ slot = item.getSlot();
return item;
}
@Override
public int getCoveredSlot() {
- return itemSupplier.get().getSlot();
+ return slot;
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatelessItemWidget.java b/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatelessItemWidget.java
index 515b24f1..7061b9f3 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatelessItemWidget.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/widget/StatelessItemWidget.java
@@ -1,11 +1,7 @@
package de.pxav.kelp.core.inventory.widget;
-import com.google.common.collect.Sets;
+import de.pxav.kelp.core.inventory.InventoryConstants;
import de.pxav.kelp.core.inventory.item.KelpItem;
-import de.pxav.kelp.core.inventory.listener.KelpClickEvent;
-
-import java.util.Set;
-import java.util.function.Consumer;
/**
* This widget is used to create single items and put them into
@@ -18,6 +14,7 @@ public class StatelessItemWidget extends AbstractWidget imp
// the item to be set into the inventory.
private KelpItem item;
+ private int slot = InventoryConstants.NOT_RENDERED_SIMPLE_WIDGET;
public static StatelessItemWidget create() {
return new StatelessItemWidget();
@@ -48,12 +45,13 @@ public boolean isStateful() {
*/
@Override
public KelpItem render() {
+ slot = item.getSlot();
return item;
}
@Override
public int getCoveredSlot() {
- return item.getSlot();
+ return slot;
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/inventory/widget/ToggleableWidget.java b/core/src/main/java/de/pxav/kelp/core/inventory/widget/ToggleableWidget.java
index 618c6a36..8709095f 100644
--- a/core/src/main/java/de/pxav/kelp/core/inventory/widget/ToggleableWidget.java
+++ b/core/src/main/java/de/pxav/kelp/core/inventory/widget/ToggleableWidget.java
@@ -1,6 +1,7 @@
package de.pxav.kelp.core.inventory.widget;
import com.google.common.base.Preconditions;
+import de.pxav.kelp.core.inventory.InventoryConstants;
import de.pxav.kelp.core.inventory.item.KelpItem;
import java.util.function.Supplier;
@@ -36,7 +37,7 @@ public class ToggleableWidget extends AbstractWidget implement
// The item which is displayed when the condition is false.
private KelpItem whenFalse;
- private int slot;
+ private int slot = InventoryConstants.NOT_RENDERED_SIMPLE_WIDGET;
ToggleableWidget() {}
@@ -167,4 +168,5 @@ public KelpItem render() {
public int getCoveredSlot() {
return slot;
}
+
}
diff --git a/core/src/main/java/de/pxav/kelp/core/npc/KelpNpc.java b/core/src/main/java/de/pxav/kelp/core/npc/KelpNpc.java
index db99a6e4..c59fe183 100644
--- a/core/src/main/java/de/pxav/kelp/core/npc/KelpNpc.java
+++ b/core/src/main/java/de/pxav/kelp/core/npc/KelpNpc.java
@@ -14,7 +14,6 @@
import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.world.KelpLocation;
import org.bukkit.Bukkit;
-import org.bukkit.Location;
import java.util.Collection;
import java.util.List;
diff --git a/core/src/main/java/de/pxav/kelp/core/npc/KelpNpcRepository.java b/core/src/main/java/de/pxav/kelp/core/npc/KelpNpcRepository.java
index 7b0f5cd9..9c2e7ba7 100644
--- a/core/src/main/java/de/pxav/kelp/core/npc/KelpNpcRepository.java
+++ b/core/src/main/java/de/pxav/kelp/core/npc/KelpNpcRepository.java
@@ -7,16 +7,12 @@
import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.player.KelpPlayerRepository;
import de.pxav.kelp.core.scheduler.type.RepeatingScheduler;
-import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
/**
* This repository class administrates the player NPCs.
diff --git a/core/src/main/java/de/pxav/kelp/core/npc/activity/AutoSpawnActivity.java b/core/src/main/java/de/pxav/kelp/core/npc/activity/AutoSpawnActivity.java
index cba43e30..8df6b302 100644
--- a/core/src/main/java/de/pxav/kelp/core/npc/activity/AutoSpawnActivity.java
+++ b/core/src/main/java/de/pxav/kelp/core/npc/activity/AutoSpawnActivity.java
@@ -3,7 +3,6 @@
import de.pxav.kelp.core.npc.KelpNpc;
import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.world.KelpLocation;
-import org.bukkit.Location;
public class AutoSpawnActivity extends NpcActivity {
diff --git a/core/src/main/java/de/pxav/kelp/core/particle/effect/ParticleLineEffect.java b/core/src/main/java/de/pxav/kelp/core/particle/effect/ParticleLineEffect.java
index bf476c74..ff8c1af9 100644
--- a/core/src/main/java/de/pxav/kelp/core/particle/effect/ParticleLineEffect.java
+++ b/core/src/main/java/de/pxav/kelp/core/particle/effect/ParticleLineEffect.java
@@ -3,7 +3,6 @@
import de.pxav.kelp.core.particle.type.ParticleType;
import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.world.KelpLocation;
-import org.bukkit.Location;
import org.bukkit.util.Vector;
import java.util.Collection;
@@ -65,7 +64,7 @@ protected void playAnimationOnce(Collection player) {
firstPointBackup.add(x * d, y * d, z * d);
for (KelpPlayer kelpPlayer : player) {
- kelpPlayer.spawnParticle(particleType, true, firstPointBackup, 0, 0, 0, 1, 0, null);
+ kelpPlayer.spawnParticle(particleType, firstPointBackup, 1, 0);
}
firstPointBackup.subtract(x * d, y * d, z * d);
diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java
index 38b26de3..b3e48b52 100644
--- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java
+++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java
@@ -5,10 +5,11 @@
import de.pxav.kelp.core.command.KelpCommandSender;
import de.pxav.kelp.core.entity.KelpEntityType;
import de.pxav.kelp.core.entity.LivingKelpEntity;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
-import de.pxav.kelp.core.entity.version.LivingEntityVersionTemplate;
+import de.pxav.kelp.core.entity.type.general.HumanEntity;
+import de.pxav.kelp.core.entity.type.general.ProjectileLauncher;
import de.pxav.kelp.core.event.kelpevent.sidebar.KelpSidebarRemoveEvent;
import de.pxav.kelp.core.inventory.KelpInventoryRepository;
+import de.pxav.kelp.core.inventory.type.InventoryOwner;
import de.pxav.kelp.core.inventory.type.KelpInventory;
import de.pxav.kelp.core.inventory.type.PlayerInventory;
import de.pxav.kelp.core.particle.type.ParticleType;
@@ -23,16 +24,15 @@
import de.pxav.kelp.core.player.prompt.chat.SimpleChatPrompt;
import de.pxav.kelp.core.player.prompt.sign.SignPrompt;
import de.pxav.kelp.core.player.prompt.sign.SignPromptVersionTemplate;
-import de.pxav.kelp.core.sidebar.SidebarRepository;
import de.pxav.kelp.core.sidebar.type.KelpSidebar;
import de.pxav.kelp.core.sound.KelpSound;
import de.pxav.kelp.core.world.KelpLocation;
import org.bukkit.Bukkit;
-import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Scoreboard;
+import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.UUID;
@@ -61,69 +61,14 @@
* @see KelpPlayerRepository
* @author pxav
*/
-public class KelpPlayer extends LivingKelpEntity implements KelpCommandSender {
-
- private PlayerVersionTemplate playerVersionTemplate;
- private SidebarRepository sidebarRepository;
- private KelpInventoryRepository inventoryRepository;
- private ParticleVersionTemplate particleVersionTemplate;
- private SignPromptVersionTemplate signPromptVersionTemplate;
- private AnvilPromptVersionTemplate anvilPromptVersionTemplate;
- private ChatPromptVersionTemplate chatPromptVersionTemplate;
-
- private Player bukkitPlayer;
-
- // caches the view distance configured in the player's video settings
- private int clientViewDistance;
-
- // caches the language of the player's client
- private String clientLanguage;
-
- // caches the chat visibility configured by the player in the chat settings tab
- private PlayerChatVisibility playerChatVisibility;
-
- private boolean playerChatColorEnabled;
-
- private String tabListHeader;
- private String tabListFooter;
-
- private KelpSidebar kelpSidebar;
-
- public KelpPlayer(Player bukkitPlayer,
- PlayerVersionTemplate playerVersionTemplate,
- KelpInventoryRepository inventoryRepository,
- KelpPlayerRepository kelpPlayerRepository,
- ParticleVersionTemplate particleVersionTemplate,
- SignPromptVersionTemplate signPromptVersionTemplate,
- AnvilPromptVersionTemplate anvilPromptVersionTemplate,
- ChatPromptVersionTemplate chatPromptVersionTemplate,
- EntityVersionTemplate entityVersionTemplate,
- LivingEntityVersionTemplate livingEntityVersionTemplate,
- UUID uuid,
- Location location,
- int entityId) {
- super(kelpPlayerRepository.getMinecraftEntity(uuid),
- KelpEntityType.PLAYER,
- location,
- entityId,
- entityVersionTemplate,
- livingEntityVersionTemplate,
- bukkitPlayer);
- this.bukkitPlayer = bukkitPlayer;
- this.playerVersionTemplate = playerVersionTemplate;
- this.inventoryRepository = inventoryRepository;
- this.particleVersionTemplate = particleVersionTemplate;
- this.signPromptVersionTemplate = signPromptVersionTemplate;
- this.chatPromptVersionTemplate = chatPromptVersionTemplate;
- this.anvilPromptVersionTemplate = anvilPromptVersionTemplate;
- }
+public interface KelpPlayer extends HumanEntity, ProjectileLauncher, InventoryOwner, KelpCommandSender {
- public static KelpPlayer from(UUID player) {
+ static KelpPlayer from(UUID player) {
KelpPlayerRepository repository = KelpPlugin.getInjector().getInstance(KelpPlayerRepository.class);
return repository.getKelpPlayer(player);
}
- public static KelpPlayer from(String name) {
+ static KelpPlayer from(String name) {
Player player = Bukkit.getPlayer(name);
if (player == null) {
return null;
@@ -131,24 +76,20 @@ public static KelpPlayer from(String name) {
return KelpPlayer.from(player);
}
- public static KelpPlayer from(Player player) {
+ static KelpPlayer from(Player player) {
return KelpPlayer.from(player.getUniqueId());
}
- public SignPrompt openSignPrompt() {
- return new SignPrompt(this.getBukkitPlayer(), this.signPromptVersionTemplate);
- }
-
- public AnvilPrompt openAnvilPrompt() {
- return new AnvilPrompt(this.getBukkitPlayer(), this.anvilPromptVersionTemplate);
+ default SignPrompt openSignPrompt() {
+ return new SignPrompt(this.getBukkitPlayer(), Dependencies.getSignPromptVersionTemplate());
}
- public SimpleChatPrompt openSimpleChatPrompt() {
- return new SimpleChatPrompt(this.getBukkitPlayer(), this.chatPromptVersionTemplate);
+ default AnvilPrompt openAnvilPrompt() {
+ return new AnvilPrompt(this.getBukkitPlayer(), Dependencies.getAnvilPromptVersionTemplate());
}
- public PlayerInventory getInventory() {
- return PlayerInventory.of(this);
+ default SimpleChatPrompt openSimpleChatPrompt() {
+ return new SimpleChatPrompt(this.getBukkitPlayer(), Dependencies.getChatPromptVersionTemplate());
}
/**
@@ -157,8 +98,8 @@ public PlayerInventory getInventory() {
*
* @return {@code true} if the player has a scoreboard with an objective.
*/
- public boolean hasScoreboard() {
- Scoreboard scoreboard = bukkitPlayer.getScoreboard();
+ default boolean hasScoreboard() {
+ Scoreboard scoreboard = getBukkitPlayer().getScoreboard();
return scoreboard.getObjective(DisplaySlot.SIDEBAR) != null
|| scoreboard.getObjective(DisplaySlot.BELOW_NAME) != null
|| scoreboard.getObjective(DisplaySlot.PLAYER_LIST) != null;
@@ -170,33 +111,43 @@ public boolean hasScoreboard() {
* to it (such as title animation). This method does not effect other parts
* of the scoreboard such as the tab list.
*/
- public void removeSidebar() {
+ default KelpPlayer removeSidebar() {
setSidebarInternally(null);
Bukkit.getPluginManager().callEvent(new KelpSidebarRemoveEvent(this));
- playerVersionTemplate.removeSidebar(bukkitPlayer);
+ removeScoreboard();
+ return this;
}
/**
- * Caches the sidebar object of the player locally. This does not
- * render nor update the given sidebar. It simply changes the internal
- * sidebar object which can then be retrieved to update it for
- * example using {@link #getCurrentSidebar()}.
+ * Removes the player's bukkit scoreboard no matter if this is a {@link KelpSidebar}
+ * or a simple {@link org.bukkit.scoreboard.Scoreboard}. This can be used universally.
*
- * @param sidebar The current sidebar of the player.
+ * But if the sidebar is a kelp sidebar, this method won't call the corresponding
+ * {@link KelpSidebarRemoveEvent} unlike the {@link #removeSidebar()} method.
+ *
+ * @return
*/
- public void setSidebarInternally(KelpSidebar sidebar) {
- this.kelpSidebar = sidebar;
- }
+ KelpPlayer removeScoreboard();
/**
- * Gets the sidebar the player is currently seeing.
- * Will return {@code null} of the player has no sidebar.
+ * Sets the internal sidebar instance for the current player.
+ * This won't actually update the sidebar content itself nor call
+ * the {@link de.pxav.kelp.core.event.kelpevent.sidebar.KelpSidebarRenderEvent}
+ * or {@link de.pxav.kelp.core.event.kelpevent.sidebar.KelpSidebarUpdateEvent}.
*
- * @return The current sidebar of the player.
+ * @param sidebar The new sidebar instance to set internally.
*/
- public KelpSidebar getCurrentSidebar() {
- return kelpSidebar;
- }
+ void setSidebarInternally(KelpSidebar> sidebar);
+
+ /**
+ * Gets the sidebar that is currently rendered to the player.
+ *
+ * @return The sidebar that is currently rendered to the player.
+ * {@code null} if the player has no sidebar.
+ */
+ KelpSidebar> getCurrentSidebar();
+
+ PlayerInventory getInventory();
/**
* Opens a {@link KelpInventory} to the player. This
@@ -206,8 +157,8 @@ public KelpSidebar getCurrentSidebar() {
* @param inventory The inventory you want to show to the player
* @return the current instance of the player
*/
- public KelpPlayer openInventory(KelpInventory> inventory) {
- this.inventoryRepository.openInventory(inventory, this);
+ default KelpPlayer openInventory(KelpInventory> inventory) {
+ Dependencies.getInventoryRepository().openInventory(inventory, this);
return this;
}
@@ -220,8 +171,22 @@ public KelpPlayer openInventory(KelpInventory> inventory) {
*
* @return the current instance of the player.
*/
- public KelpPlayer updateKelpInventory() {
- this.inventoryRepository.updateInventory(this);
+ default KelpPlayer updateKelpInventory() {
+ Dependencies.getInventoryRepository().updateInventory(this);
+ return this;
+ }
+
+ /**
+ * Updates the title of the player's {@link de.pxav.kelp.core.inventory.type.SimpleInventory}.
+ * This inventory takes its title as {@link com.google.common.base.Supplier} and the
+ * content is therefore updatable. If the player has an animated inventory, the updating process
+ * is handled by the {@link de.pxav.kelp.core.inventory.type.AnimatedInventory} class and
+ * executing this method will have no effect.
+ *
+ * @return An instance of the the current player.
+ */
+ default KelpPlayer updateKelpInventoryTitle() {
+ Dependencies.getInventoryRepository().updateInventoryTitle(this);
return this;
}
@@ -233,8 +198,8 @@ public KelpPlayer updateKelpInventory() {
*
* @return the current instance of the player.
*/
- public KelpPlayer closeInventory() {
- this.inventoryRepository.closeInventory(this);
+ default KelpPlayer closeInventory() {
+ Dependencies.getInventoryRepository().closeInventory(this);
return this;
}
@@ -248,668 +213,946 @@ public KelpPlayer closeInventory() {
*
* @return the current instance of the player
*/
- public KelpPlayer forceInventoryClose() {
- bukkitPlayer.closeInventory();
- return this;
- }
+ KelpPlayer forceInventoryClose();
- /**
- * Checks whether the current player has a {@link KelpInventory} open.
- * Having opened a normal {@link PlayerInventory} using the {@code E} key
- * on the keyboard does not count for this method. It will only return
- * true if the player really has an external kelp inventory (GUI) opened.
- *
- * @return {@code true} if the player has opened a {@link KelpInventory}.
- */
- public boolean hasKelpInventory() {
- return this.inventoryRepository.hasInventory(this);
+ default boolean hasKelpInventory() {
+ return Dependencies.getInventoryRepository().hasInventory(this);
}
- /**
- * Updates the title of the player's {@link de.pxav.kelp.core.inventory.type.SimpleInventory}.
- * This inventory takes its title as {@link com.google.common.base.Supplier} and the
- * content is therefore updatable. If the player has an animated inventory, the updating process
- * is handled by the {@link de.pxav.kelp.core.inventory.type.AnimatedInventory} class and
- * executing this method will have no effect.
- *
- * @return An instance of the the current player.
- */
- public KelpPlayer updateKelpInventoryTitle() {
- if (!hasKelpInventory()) {
- return this;
- }
-
- inventoryRepository.updateInventoryTitle(this);
+ default KelpPlayer playSound(KelpSound sound) {
+ playSound(sound, getLocation(), 2, 0);
return this;
}
- public KelpPlayer playSound(KelpSound sound) {
- playerVersionTemplate.playSound(bukkitPlayer, sound, getLocation(), 3, 0);
+ default KelpPlayer playSound(KelpSound sound, KelpLocation location) {
+ playSound(sound, location, 2, 0);
return this;
}
- public KelpPlayer playSound(KelpSound sound, KelpLocation location) {
- playerVersionTemplate.playSound(bukkitPlayer, sound, location, 3, 0);
+ default KelpPlayer playSound(KelpSound sound, float volume) {
+ playSound(sound, getLocation(), volume, 0);
return this;
}
- public KelpPlayer playSound(KelpSound sound, float volume) {
- playerVersionTemplate.playSound(bukkitPlayer, sound, getLocation(), volume, 0);
+ default KelpPlayer playSound(KelpSound sound, float volume, float pitch) {
+ playSound(sound, volume, pitch);
return this;
}
- public KelpPlayer playSound(KelpSound sound, float volume, float pitch) {
- playerVersionTemplate.playSound(bukkitPlayer, sound, getLocation(), volume, pitch);
- return this;
- }
+ KelpPlayer playSound(KelpSound sound, KelpLocation from, float volume, float pitch);
- public KelpPlayer playSound(KelpSound sound, KelpLocation location, float volume, float pitch) {
- playerVersionTemplate.playSound(bukkitPlayer, sound, location, volume, pitch);
- return this;
- }
+ /**
+ * Sends an action bar message to the player.
+ * The action bar is a line of text, which is displayed
+ * above the player's hotbar.
+ *
+ * @param message The message you want to send.
+ */
+ KelpPlayer sendActionbar(String message);
- public KelpPlayer sendTitle(String title, String subTitle) {
- playerVersionTemplate.sendTitle(bukkitPlayer, title, subTitle, 20, 60, 20);
- return this;
- }
+ /**
+ * Sends a title to a player. A title is a big text displayed
+ * right in the middle of the player's screen.
+ *
+ * @param title The upper title text (will be displayed slightly bigger than the sub title).
+ * @param subTitle The lower title text (will be displayed slightly smaller than the main title).
+ * @param fadeIn How long should it take to fade the title in? (in ticks)
+ * @param stay How long should the title stay in 100% opacity? (in ticks)
+ * @param fadeOut How long should it take to fade the title out? (in ticks)
+ */
+ KelpPlayer sendTitle(String title, String subTitle, int fadeIn, int stay, int fadeOut);
- public KelpPlayer sendTitle(String title, String subTitle, int fadeIn, int stay, int fadeOut) {
- playerVersionTemplate.sendTitle(bukkitPlayer, title, subTitle, fadeIn, stay, fadeOut);
+ default KelpPlayer sendTitle(String title, String subTitle) {
+ sendTitle(title, subTitle, 20, 60, 20);
return this;
}
- public KelpPlayer sendActionbar(String message) {
- playerVersionTemplate.sendActionBar(bukkitPlayer, message);
+ default KelpPlayer sendSuddenTitle(String title, String subTitle) {
+ sendTitle(title, subTitle, 0, 60, 0);
return this;
}
- public KelpPlayer spawnParticle(ParticleType particleType, boolean longDistance, float offsetX, float offsetY, float offsetZ, int count) {
- particleVersionTemplate.spawnParticle(this,
- particleType,
- longDistance,
- getLocation().getX(),
- getLocation().getY(),
- getLocation().getZ(),
- offsetX, offsetY,
- offsetZ,
- 0,
- count,
- null);
- return this;
- }
+ KelpPlayer spawnParticle(ParticleType particleType,
+ double x,
+ double y,
+ double z,
+ float offsetX,
+ float offsetY,
+ float offsetZ,
+ int count,
+ float particleData,
+ Object generalData);
- public KelpPlayer spawnParticle(ParticleType particleType, float offsetX, float offsetY, float offsetZ) {
- particleVersionTemplate.spawnParticle(this,
+ default KelpPlayer spawnParticle(ParticleType particleType, KelpLocation location) {
+ spawnParticle(
particleType,
- false,
- getLocation().getX(),
- getLocation().getY(),
- getLocation().getZ(),
- offsetX, offsetY,
- offsetZ,
+ location.getX(),
+ location.getY(),
+ location.getZ(),
+ 0,
+ 0,
0,
1,
+ 0,
null);
return this;
}
- public KelpPlayer spawnParticle(ParticleType particleType, boolean longDistance, float offsetX, float offsetY, float offsetZ, int count, float particleData, Object generalData) {
- particleVersionTemplate.spawnParticle(this,
+ default KelpPlayer spawnParticle(ParticleType particleType, KelpLocation location, int count, float offset) {
+ spawnParticle(
particleType,
- longDistance,
- getLocation().getX(),
- getLocation().getY(),
- getLocation().getZ(),
- offsetX, offsetY,
- offsetZ,
- particleData,
- count,
- generalData);
- return this;
- }
-
- public KelpPlayer spawnParticle(ParticleType particleType, boolean longDistance, KelpLocation location, float offsetX, float offsetY, float offsetZ, int count, float particleData, Object generalData) {
- particleVersionTemplate.spawnParticle(this,
- particleType,
- longDistance,
location.getX(),
location.getY(),
location.getZ(),
- offsetX, offsetY,
- offsetZ,
- particleData,
+ offset,
+ offset,
+ offset,
count,
- generalData);
+ 0,
+ null);
return this;
}
- public KelpPlayer spawnParticle(ParticleType particleType, boolean longDistance, double x, double y, double z, float offsetX, float offsetY, float offsetZ, int count, float particleData, Object generalData) {
- particleVersionTemplate.spawnParticle(this,
+ default KelpPlayer spawnParticle(ParticleType particleType,
+ KelpLocation location,
+ int count,
+ float offsetX,
+ float offsetY,
+ float offsetZ) {
+ spawnParticle(
particleType,
- longDistance,
- x,
- y,
- z,
- offsetX, offsetY,
+ location.getX(),
+ location.getY(),
+ location.getZ(),
+ offsetX,
+ offsetY,
offsetZ,
- particleData,
count,
- generalData);
+ 0,
+ null);
return this;
}
- public UUID getUUID() {
- return playerVersionTemplate.getUniqueId(bukkitPlayer);
- }
-
- public String getName() {
- return bukkitPlayer.getName();
- }
+ UUID getUUID();
- public KelpPlayer setHealth(int health) {
- playerVersionTemplate.setHealth(bukkitPlayer, health);
- return this;
- }
+ String getName();
- public boolean isInWater() {
- return playerVersionTemplate.isInWater(bukkitPlayer);
- }
-
- public boolean isInCobweb() {
- return playerVersionTemplate.isInCobweb(bukkitPlayer);
- }
+ /**
+ * Sets the player's health.
+ *
+ * @param health How many health points the player should have.
+ * 2 health points equal 1 heart.
+ * So 20 health points equal the full 10 hearts.
+ */
+ KelpPlayer setHealth(int health);
- public KelpPlayer chat(String message) {
- playerVersionTemplate.chat(bukkitPlayer, message);
- return this;
- }
+ /**
+ * Sends a chat message from the given player.
+ * This means you can send a message as if the player itself
+ * typed in this message. This also works with commands, if
+ * you add a slash in front of the message.
+ *
+ * @param message The message you want to send.
+ */
+ KelpPlayer chat(String message);
- public KelpPlayer clearChat() {
+ default KelpPlayer clearChat() {
for (int i = 0; i < 103; i++) {
sendMessage(" ");
}
return this;
}
- public boolean mayFly() {
- return playerVersionTemplate.getAllowFlight(bukkitPlayer);
- }
+ /**
+ * Gets the socket address of a specific player.
+ *
+ * @return The {@code InetSocketAddress} object of the player's address.
+ */
+ InetSocketAddress getSocketAddress();
- public String getDisplayName() {
- return playerVersionTemplate.getDisplayName(bukkitPlayer);
- }
+ /**
+ * Determines if the Player is allowed to fly via
+ * jump key double-tap like in creative mode.
+ *
+ * If a player flies without permission, they will get kicked
+ * by the server automatically.
+ *
+ * @return {@code true} if the player is allowed to fly.
+ */
+ boolean mayFly();
- public KelpPlayer setDisplayName(String displayName) {
- playerVersionTemplate.setDisplayName(bukkitPlayer, displayName);
- return this;
- }
+ /**
+ * Gets the display name of a player.
+ * The display name is a name which - unlike the normal name -
+ * can be modified during the server runtime. You can use this
+ * to include custom prefixes, ...
+ *
+ * @return The display name.
+ */
+ String getDisplayName();
- public String getTabListName() {
- return playerVersionTemplate.getPlayerTabListName(bukkitPlayer);
- }
+ /**
+ * Sets the display name of a player
+ * The display name is a name which - unlike the normal name -
+ * can be modified during the server runtime. You can use this
+ * to include custom prefixes, ...
+ *
+ * @param displayName The display name you want to set.
+ */
+ KelpPlayer setDisplayName(String displayName);
- public KelpPlayer setTabListName(String tabListName) {
- playerVersionTemplate.setPlayerTabListName(bukkitPlayer, tabListName);
- return this;
- }
+ /**
+ * Gets the tab-list name of the player.
+ * The tab-list name is the name which is used to represent
+ * the player in the tab-list of online players.
+ *
+ * @return The tab-list name.
+ */
+ String getTabListName();
- // TODO make tablist name hideable
+ /**
+ * Sets the tab-list name of the player.
+ * The tab-list name is the name which is used to represent
+ * the player in the tab-list of online players.
+ *
+ * @param tabListName The tab-list name you want to set.
+ */
+ KelpPlayer setTabListName(String tabListName);
- // TODO TAB LIST HEADER AND FOOTER
+ /**
+ * Sets the compass target of the player.
+ * The compass target is the location, where the compass needle
+ * points to. By default this is the spawn location of the world,
+ * but you could set this to specific player locations as well.
+ *
+ * @param target The location, where the compass should point to.
+ */
+ KelpPlayer setCompassTarget(KelpLocation target);
- public KelpPlayer setCompassTarget(KelpLocation target) {
- playerVersionTemplate.setCompassTarget(bukkitPlayer, target);
- return this;
- }
+ /**
+ * Gets the compass target of the player.
+ * The compass target is the location, where the compass needle
+ * points to. By default this is the spawn location of the world.
+ *
+ * @return The target location of the player's compass.
+ */
+ KelpLocation getCompassTarget();
- public KelpPlayer kickPlayer(String kickMessage) {
- playerVersionTemplate.kickPlayer(bukkitPlayer, kickMessage);
- return this;
- }
+ /**
+ * Kicks the given player from the server.
+ *
+ * @param kickMessage The message, which should be received by the player.
+ * Could also be named kick reason.
+ */
+ KelpPlayer kickPlayer(String kickMessage);
- public boolean isSneaking() {
- return playerVersionTemplate.isSneaking(bukkitPlayer);
- }
+ /**
+ * Checks if the player is currently sneaking/crouching.
+ * @return {@code true} if the player is sneaking.
+ */
+ boolean isSneaking();
- public KelpPlayer sneak() {
- playerVersionTemplate.setSneaking(bukkitPlayer, true);
- return this;
- }
+ /**
+ * Modifies the sneak state of the player.
+ *
+ * @param sneaking {@code true} if you want to make the player sneak.
+ * {@code false}, if not.
+ */
+ KelpPlayer setSneaking(boolean sneaking);
- public KelpPlayer unSneak() {
- playerVersionTemplate.setSneaking(bukkitPlayer, false);
+ default KelpPlayer toggleSneak() {
+ setSneaking(!isSneaking());
return this;
}
- public KelpPlayer toggleSneak() {
- if (this.isSneaking()) {
- this.unSneak();
- } else {
- this.sneak();
- }
+ default KelpPlayer sneak() {
+ setSneaking(true);
return this;
}
- public KelpPlayer setSneaking(boolean sneaking) {
- playerVersionTemplate.setSneaking(bukkitPlayer, sneaking);
+ default KelpPlayer unSneak() {
+ setSneaking(false);
return this;
}
- public boolean isSprinting() {
- return playerVersionTemplate.isSprinting(bukkitPlayer);
- }
+ /**
+ * Checks if the player is currently sprinting.
+ * Sprinting is active when the player has double-pressed the
+ * walking key or pressed the walking and sprinting key at
+ * once.
+ *
+ * @return {@code true} if the player is currently sprinting.
+ */
+ boolean isSprinting();
- public KelpPlayer sprint() {
- playerVersionTemplate.setSprinting(bukkitPlayer, true);
- return this;
- }
+ /**
+ * Changes the sprinting state of a player.
+ * Sprinting is active when the player has double-pressed the
+ * walking key or pressed the walking and sprinting key at
+ * once.
+ *
+ * @param sprinting {@code true} if the player should be sprinting.
+ */
+ KelpPlayer setSprinting(boolean sprinting);
- public KelpPlayer stopSprinting() {
- playerVersionTemplate.setSprinting(bukkitPlayer, false);
+ default KelpPlayer toggleSprinting() {
+ setSneaking(!isSneaking());
return this;
}
- public KelpPlayer toggleSprint() {
- if (this.isSprinting()) {
- this.stopSprinting();
- } else {
- this.sprint();
- }
+ default KelpPlayer sprint() {
+ setSprinting(true);
return this;
}
- public KelpPlayer setSprinting(boolean sprinting) {
- playerVersionTemplate.setSprinting(bukkitPlayer, sprinting);
+ default KelpPlayer unSprint() {
+ setSprinting(false);
return this;
}
- public boolean isSleepingIgnored() {
- return playerVersionTemplate.isSprinting(bukkitPlayer);
- }
+ /**
+ * Checks if the player is ignored when the server checks who is sleeping.
+ *
+ * When it is night, normally all players have to sleep so that the
+ * time can jump to morning. If you don't want all players to sleep,
+ * you can give specific players this flag and they don't have to sleep
+ * anymore.
+ *
+ * If you give this flag to all players, nothing will happen at night.
+ * So there has to be at least one player sleeping at night.
+ *
+ * @return {@code true} if the player has the ignore flag.
+ */
+ boolean isSleepingIgnored();
- public KelpPlayer ignoreSleeping() {
- playerVersionTemplate.setSleepingIgnored(bukkitPlayer, true);
+ default KelpPlayer ignoreSleeping() {
+ setSleepingIgnored(true);
return this;
}
- public KelpPlayer unignoreSleeping() {
- playerVersionTemplate.setSleepingIgnored(bukkitPlayer, false);
+ default KelpPlayer unIgnoreSleeping() {
+ setSleepingIgnored(false);
return this;
}
- public KelpPlayer toggleIgnoreSleeping() {
- if (this.isSleepingIgnored()) {
- this.unignoreSleeping();
- } else {
- this.ignoreSleeping();
- }
+ default KelpPlayer toggleIgnoreSleeping() {
+ setSleepingIgnored(!isSleepingIgnored());
return this;
}
- public KelpPlayer setSleepingIgnored(boolean sleepingIgnored) {
- playerVersionTemplate.setSleepingIgnored(bukkitPlayer, sleepingIgnored);
- return this;
- }
+ /**
+ * Sets the player ignored when the server checks who is sleeping.
+ *
+ * When it is night, normally all players have to sleep so that the
+ * time can jump to morning. If you don't want all players to sleep,
+ * you can give specific players this flag and they don't have to sleep
+ * anymore.
+ *
+ * If you give this flag to all players, nothing will happen at night.
+ * So there has to be at least one player sleeping at night.
+ *
+ * @param sleepingIgnored {@code true} if the player should be ignored when sleeping.
+ */
+ KelpPlayer setSleepingIgnored(boolean sleepingIgnored);
- public KelpPlayer setRelativePlayerTime(long time) {
- playerVersionTemplate.setPlayerTime(bukkitPlayer, time, true);
- return this;
- }
+ KelpPlayer setRelativePlayerTime(long time);
- public KelpPlayer setPlayerTime(long time) {
- playerVersionTemplate.setPlayerTime(bukkitPlayer, time, false);
- return this;
- }
+ /**
+ * Sets the player time. Each player can have an individual time
+ * - even if they are in the same world.
+ *
+ * @param time If {@code relative} is set to {@code true}, this is the
+ * time offset to the server time in ticks. If {@code relative}
+ * is set to {@code false} it is the absolute day time ticks.
+ */
+ KelpPlayer setPlayerTime(long time);
- public long getPlayerTime() {
- return playerVersionTemplate.getPlayerTime(bukkitPlayer);
- }
+ /**
+ * Gets the current player time. Each player can have an
+ * individual time - even if they are in the same world.
+ *
+ * @return The current time of the player in ticks.
+ */
+ long getPlayerTime();
- public long getPlayerTimeOffset() {
- return playerVersionTemplate.getPlayerTimeOffset(bukkitPlayer);
- }
+ /**
+ * If the player time was set with {@code relative} to {@code true},
+ * then it will get the offset of the player time to the current server
+ * time. If {@code relative} was set to {@code false}, it will simply
+ * return the current player time.
+ *
+ * @return The player's time (offset).
+ */
+ long getPlayerTimeOffset();
- public boolean isPlayerTimeRelative() {
- return playerVersionTemplate.isPlayerTimeRelative(bukkitPlayer);
- }
+ /**
+ * Checks if the player time set for the player is relative
+ * to the server time. More information can be found
+ * at {@code #setPlayerTime(player, time, relative)}
+ *
+ * @return {@code true} if player time is relative to server time.
+ */
+ boolean isPlayerTimeRelative();
- public KelpPlayer resetPlayerTime() {
- playerVersionTemplate.resetPlayerTime(bukkitPlayer);
- return this;
- }
+ /**
+ * Resets the player time back to the current server
+ * time. So the times of both are synchronized again.
+ *
+ */
+ KelpPlayer resetPlayerTime();
- public KelpPlayer giveExperience(int amount) {
- playerVersionTemplate.giveExperience(bukkitPlayer, amount);
+ /**
+ * Gives the player the given amount of experience.
+ * This method simply adds the given amount to the player's
+ * current exp count and does not overwrite anything.
+ *
+ * @param amount The amount of experience to give.
+ */
+ default KelpPlayer giveExperience(int amount) {
+ setExperience(getExperience() + amount);
return this;
}
- public KelpPlayer giveExperienceLevels(int amount) {
- playerVersionTemplate.giveExperienceLevels(bukkitPlayer, amount);
+ /**
+ * Gives or takes the player the given amount of experience.
+ * Negative amounts express that levels should be taken
+ * away from the player, positive amounts will be added.
+ *
+ * @param amount The amount of levels to give or take.
+ */
+ default KelpPlayer giveExperienceLevels(int amount) {
+ setLevel(getLevel() + amount);
return this;
}
- public float getExperience() {
- return playerVersionTemplate.getExperience(bukkitPlayer);
- }
+ /**
+ * Gets the current experience of the given player.
+ *
+ * Experience is a percentage value (ranging from 0 to 1)
+ * indicating the progress to the next full level.
+ * 0 means he has just reached a new level and has made no
+ * progress since then, wile 1 says the player is just about
+ * to reach a new level.
+ *
+ * Inside Minecraft, the experience is represented by the
+ * green bar above the hotbar.
+ *
+ * @return The current experience progress (from 0 to 1).
+ */
+ float getExperience();
- public KelpPlayer setExperience(float experience) {
- playerVersionTemplate.setExperience(bukkitPlayer, experience);
- return this;
- }
+ /**
+ * Sets the current experience of the given player.
+ *
+ * Experience is a percentage value (ranging from 0 to 1)
+ * indicating the progress to the next full level.
+ * 0 means he has just reached a new level and has made no
+ * progress since then, wile 1 says the player is just about
+ * to reach a new level.
+ *
+ * Inside Minecraft, the experience is represented by the
+ * green bar above the hotbar.
+ *
+ * @param experience The experience value you want to set.
+ * May range from 0 to 1.
+ */
+ KelpPlayer setExperience(float experience);
- public KelpPlayer setLevel(int level) {
- playerVersionTemplate.setLevel(bukkitPlayer, level);
- return this;
- }
+ /**
+ * Sets the current amount of the player's levels.
+ *
+ * Levels are reached when the experience count reaches 1.
+ * The amount of levels is represented by the small green
+ * number above the level bar.
+ *
+ * @param level The new level count to set.
+ */
+ KelpPlayer setLevel(int level);
- public int getLevel() {
- return playerVersionTemplate.getLevel(bukkitPlayer);
- }
+ /**
+ * Gets the current amount of the player's levels.
+ *
+ * Levels are reached when the experience count reaches 1.
+ * The amount of levels is represented by the small green
+ * number above the level bar.
+ *
+ * @return The current amount of levels.
+ */
+ int getLevel();
- public int getTotalExperience() {
- return playerVersionTemplate.getTotalExperience(bukkitPlayer);
- }
+ /**
+ * Gets the players total experience points.
+ *
+ * This refers to the total amount of experience
+ * the player has collected over time and is not currently
+ * displayed to the client.
+ *
+ * @return The total experience points amount.
+ */
+ int getTotalExperience();
- public KelpPlayer setTotalExperience(int experience) {
- playerVersionTemplate.setTotalExperience(bukkitPlayer, experience);
- return this;
- }
+ /**
+ * Sets the players total experience points.
+ *
+ * This refers to the total amount of experience
+ * the player has collected over time and is not currently
+ * displayed to the client.
+ *
+ * @param experience The new amount of total experience.
+ */
+ KelpPlayer setTotalExperience(int experience);
- public float getExhaustionLevel() {
- return playerVersionTemplate.getExhaustion(bukkitPlayer);
- }
+ /**
+ * Gets the player's current exhaustion level.
+ * Exhaustion controls how fast the food level drops.
+ * While you have a certain amount of exhaustion,
+ * your saturation will drop to zero, and then your
+ * food will drop to zero.
+ *
+ * @return The exhaustion level of the current player.
+ */
+ float getExhaustionLevel();
- public KelpPlayer setExhaustionLevel(float exhaustionLevel) {
- playerVersionTemplate.setExhaustion(bukkitPlayer, exhaustionLevel);
- return this;
- }
+ /**
+ * Sets the player's current exhaustion level.
+ * Exhaustion controls how fast the food level drops.
+ * While you have a certain amount of exhaustion,
+ * your saturation will drop to zero, and then your
+ * food will drop to zero.
+ *
+ * @param exhaustionLevel The exhaustion level you want to set.
+ */
+ KelpPlayer setExhaustionLevel(float exhaustionLevel);
- public KelpPlayer setSaturationLevel(float saturationLevel) {
- playerVersionTemplate.setSaturation(bukkitPlayer, saturationLevel);
- return this;
- }
+ /**
+ * Sets the saturation level of a player.
+ * Saturation is a buffer for food level.
+ * Your food level will not drop if you are saturated > 0.
+ *
+ * @param saturationLevel The saturation level you want to set.
+ */
+ KelpPlayer setSaturationLevel(float saturationLevel);
- public float getSaturationLevel() {
- return playerVersionTemplate.getSaturation(bukkitPlayer);
- }
+ /**
+ * Gets the saturation level of a player.
+ * Saturation is a buffer for food level.
+ * Your food level will not drop if you are saturated > 0.
+ *
+ * @return The saturation of the player.
+ */
+ float getSaturationLevel();
- public int getFoodLevel() {
- return playerVersionTemplate.getFoodLevel(bukkitPlayer);
- }
+ /**
+ * Gets the current food level of the player. The
+ * food level indicates how full the food bar is.
+ * 20 means a full food bar, 0 an empty food bar.
+ *
+ * @return The food level of the player.
+ */
+ int getFoodLevel();
- public KelpPlayer setFoodLevel(int foodLevel) {
- playerVersionTemplate.setFoodLevel(bukkitPlayer, foodLevel);
- return this;
- }
+ /**
+ * Sets the food level of a player.
+ * The food level indicates how full the food bar is.
+ * 20 means a full food bar, 0 an empty food bar.
+ *
+ * @param foodLevel The absolute food level you want to set.
+ */
+ KelpPlayer setFoodLevel(int foodLevel);
- public KelpPlayer setAllowFlight(boolean allowed) {
- playerVersionTemplate.setAllowFlight(bukkitPlayer, allowed);
- return this;
- }
+ /**
+ * Sets if the player is allowed to fly as if he was in creative
+ * mode
+ *
+ * @param allowed {@code true} if you want to allow, {@code false}
+ * if not.
+ */
+ KelpPlayer setAllowFlight(boolean allowed);
- public KelpPlayer allowFlying() {
- playerVersionTemplate.setAllowFlight(bukkitPlayer, true);
+ default KelpPlayer allowFlying() {
+ setAllowFlight(true);
return this;
}
- public KelpPlayer disallowFlying() {
- playerVersionTemplate.setAllowFlight(bukkitPlayer, false);
+ default KelpPlayer disallowFlying() {
+ setAllowFlight(false);
return this;
}
- public KelpPlayer hidePlayer(KelpPlayer toHide) {
- playerVersionTemplate.hidePlayer(bukkitPlayer, toHide.getBukkitPlayer());
- return this;
- }
+ /**
+ * Hides a player from another player, so they become invisible
+ * for the other player.
+ *
+ * @param toHide The player you want to hide.
+ */
+ KelpPlayer hidePlayer(KelpPlayer toHide);
- public KelpPlayer showPlayer(KelpPlayer toShow) {
- playerVersionTemplate.showPlayer(bukkitPlayer, toShow.getBukkitPlayer());
- return this;
- }
+ /**
+ * Shows a player to another player again, so they become visible
+ * for the other player.
+ *
+ * @param toShow The player you want to show.
+ */
+ KelpPlayer showPlayer(KelpPlayer toShow);
- public boolean canSee(KelpPlayer toCheck) {
- return playerVersionTemplate.canSee(bukkitPlayer, toCheck.getBukkitPlayer());
- }
+ /**
+ * Checks if the given player can see the targeted player.
+ * This does not check if the player currently really sees
+ * the given target player, but if the player is not hidden.
+ *
+ * @param toCheck The player to check if he is visible for the
+ * other player.
+ * @return {@code true} if {@code player} can see {@code toCheck}.
+ */
+ boolean canSee(KelpPlayer toCheck);
- public boolean isFlying() {
- return playerVersionTemplate.isFlying(bukkitPlayer);
- }
+ /**
+ * Checks if the player is currently flying.
+ *
+ * @return {@code true} if the player is flying.
+ */
+ boolean isFlying();
- public KelpPlayer makeFlying() {
- playerVersionTemplate.setFlying(bukkitPlayer, true);
+ default KelpPlayer makeFlying() {
+ setFlying(true);
return this;
}
- public KelpPlayer stopFlying() {
- playerVersionTemplate.setFlying(bukkitPlayer, false);
+ default KelpPlayer stopFlying() {
+ setFlying(false);
return this;
}
- public KelpPlayer toggleFlying() {
- if (this.isFlying()) {
- this.stopFlying();
- } else {
- this.makeFlying();
- }
+ default KelpPlayer toggleFlying() {
+ setFlying(!isFlying());
return this;
}
- public KelpPlayer setFlying(boolean flying) {
- playerVersionTemplate.setFlying(bukkitPlayer, flying);
- return this;
- }
+ /**
+ * Changes the flying state of the player.
+ *
+ * @param flying {@code true} if you want to make the player fly.
+ * {@code false} if you don't want to make the player fly.
+ */
+ KelpPlayer setFlying(boolean flying);
- public KelpPlayer setFlySpeed(float flySpeed) {
- playerVersionTemplate.setFlySpeed(bukkitPlayer, flySpeed);
- return this;
- }
+ /**
+ * Sets the current fly speed of a player. The higher
+ * the value the higher the speed. Negative values
+ * indicate reverse directions.
+ *
+ * @param flySpeed The desired fly speed. The value may
+ * range from -1 to 1.
+ */
+ KelpPlayer setFlySpeed(float flySpeed);
- public float getFlySpeed() {
- return playerVersionTemplate.getFlySpeed(bukkitPlayer);
- }
+ /**
+ * Gets the current speed a player can fly. The higher
+ * the value the higher the speed. Negative values
+ * indicate reverse directions.
+ *
+ * @return The current fly speed of a player.
+ * Value can range from -1 to 1
+ */
+ float getFlySpeed();
- public float getWalkSpeed() {
- return playerVersionTemplate.getWalkSpeed(bukkitPlayer);
- }
+ /**
+ * Gets the current speed a player can walk. The higher
+ * the value the higher the speed. Negative values
+ * indicate reverse directions.
+ *
+ * @return The current walk speed of a player.
+ * Value can range from -1 to 1
+ */
+ float getWalkSpeed();
- public KelpPlayer setResourcePack(String url) {
- playerVersionTemplate.setResourcePack(bukkitPlayer, url);
- return this;
- }
+ /**
+ * Sets the current walk speed of a player. The higher
+ * the value the higher the speed. Negative values
+ * indicate reverse directions.
+ *
+ * @param walkSpeed The desired walk speed. The value may
+ * range from -1 to 1.
+ */
+ KelpPlayer setWalkSpeed(float walkSpeed);
- public KelpPlayer setResourcePack(String url, byte[] hash) {
- playerVersionTemplate.setResourcePack(bukkitPlayer, url, hash);
- return this;
- }
+ KelpPlayer resetWalkSpeed();
- public boolean isHealthScaled() {
- return playerVersionTemplate.isHealthScaled(bukkitPlayer);
- }
+ /**
+ * Request that the player's client download and switch resource packs.
+ *
+ * The player's client will download the new resource pack asynchronously
+ * in the background, if the request was accepted, and will automatically switch to it once the download
+ * is complete. If the client has downloaded and cached a resource pack
+ * with the same hash in the past it will not download but directly apply
+ * the cached pack. When this request is sent for the very first time
+ * from a given server, the client will first display a confirmation GUI
+ * to the player before proceeding with the download.
+ *
+ * @param url The URL from which the client will download the resource pack.
+ * The string must contain only US-ASCII characters
+ * and should be encoded as per RFC 1738.
+ */
+ KelpPlayer setResourcePack(String url);
- public KelpPlayer setHealthScale(double healthScale) {
- playerVersionTemplate.setHealthScale(bukkitPlayer, healthScale);
- return this;
- }
+ /**
+ * Request that the player's client download and switch resource packs.
+ *
+ * The player's client will download the new resource pack asynchronously
+ * in the background, if the request was accepted, and will automatically switch to it once the download
+ * is complete. If the client has downloaded and cached a resource pack
+ * with the same hash in the past it will not download but directly apply
+ * the cached pack. When this request is sent for the very first time
+ * from a given server, the client will first display a confirmation GUI
+ * to the player before proceeding with the download.
+ *
+ * @param url The URL from which the client will download the resource pack.
+ * The string must contain only US-ASCII characters
+ * and should be encoded as per RFC 1738.
+ * @param hash The sha1 hash sum of the resource pack file
+ * which is used to apply a cached version of the pack
+ * directly without downloading if it is available.
+ * Has to be 20 bytes long!
+ */
+ KelpPlayer setResourcePack(String url, byte[] hash);
- public double getHealthScale() {
- return playerVersionTemplate.getHealthScale(bukkitPlayer);
- }
+ /**
+ * Sets if the player is shown the scaled health bar.
+ * If you modify your health scale with {@code setHealthScale},
+ * you have to say the server to send this new scaled health
+ * to the player.
+ *
+ * @param scaled {@code true} whether the health should be scaled.
+ */
+ KelpPlayer setHealthScaled(boolean scaled);
- public KelpPlayer resetTitle() {
- playerVersionTemplate.resetTitle(bukkitPlayer);
- return this;
- }
+ /**
+ * Checks if the player has received the scaled health bar
+ * from the server.
+ *
+ * @return {@code true} if the player's health bar scale is up to date.
+ */
+ boolean isHealthScaled();
- public KelpPlayer setClientViewDistanceInternally(int clientViewDistance) {
- this.clientViewDistance = clientViewDistance;
- return this;
- }
+ /**
+ * Sets the health scale of the given player. The health
+ * scale is the maximum amount of hearts displayed to the
+ * client.
+ * 2 means one heart is displayed. If you choose values
+ * above 20, the player will get additional hearts.
+ * Consider changing the max health as well.
+ *
+ * This method will automatically set {@code setHealthScaled} to
+ * {@code true}.
+ *
+ * @param healthScale The amount of scaled health you want to set.
+ */
+ KelpPlayer setHealthScale(double healthScale) ;
- public int getClientViewDistance() {
- return this.clientViewDistance;
- }
+ /**
+ * Gets the number of scaled health points,
+ * which are currently displayed to the client.
+ *
+ * @return The number of scaled health if health
+ * scaling was set to {@code true} earlier.
+ */
+ double getHealthScale();
- public KelpPlayer setClientLanguageInternally(String clientLanguage) {
- this.clientLanguage = clientLanguage;
- return this;
- }
+ /**
+ * Cancels the title animation for a player. The current
+ * title is removed immediately.
+ */
+ KelpPlayer resetTitle();
- public String getClientLanguage() {
- return clientLanguage;
- }
+ KelpPlayer setClientViewDistanceInternally(int clientViewDistance);
- public KelpPlayer setPlayerChatVisibilityInternally(PlayerChatVisibility playerChatVisibility) {
- this.playerChatVisibility = playerChatVisibility;
- return this;
- }
+ int getClientViewDistance();
- public PlayerChatVisibility getPlayerChatVisibility() {
- return playerChatVisibility;
- }
+ KelpPlayer setClientLanguageInternally(String clientLanguage);
- public KelpPlayer setPlayerChatColorEnabledInternally(boolean playerChatColorEnabled) {
- this.playerChatColorEnabled = playerChatColorEnabled;
- return this;
- }
+ String getClientLanguage();
- public boolean isPlayerChatColorEnabled() {
- return this.playerChatColorEnabled;
- }
+ KelpPlayer setPlayerChatVisibilityInternally(PlayerChatVisibility playerChatVisibility);
- public KelpPlayer setTabListHeader(String header) {
- playerVersionTemplate.setPlayerListHeader(bukkitPlayer, header);
- this.tabListHeader = header;
- return this;
- }
+ PlayerChatVisibility getPlayerChatVisibility();
+
+ KelpPlayer setPlayerChatColorEnabledInternally(boolean playerChatColorEnabled);
- public KelpPlayer setTabListFooter(String footer) {
- playerVersionTemplate.setPlayerListHeader(bukkitPlayer, footer);
- this.tabListFooter = footer;
+ boolean isPlayerChatColorEnabled();
+
+ default KelpPlayer setTabListHeader(String header) {
+ setTabListHeaderAndFooter(header, getTabListFooter());
return this;
}
- public KelpPlayer setTabListHeaderAndFooter(String header, String footer) {
- setTabListHeader(header).setTabListFooter(footer);
+ default KelpPlayer setTabListFooter(String footer) {
+ setTabListHeaderAndFooter(getTabListHeader(), footer);
return this;
}
- public String getTabListFooter() {
- return tabListFooter;
- }
+ /**
+ * Sets the tab header and footer of player. The tab header is
+ * a text displayed above the player list in the tab, while
+ * the tab footer is a message displayed below the player list.
+ *
+ * The messages may contain '\n' to create new lines inside the
+ * message.
+ *
+ * @param header The header message you want to send.
+ * @param footer The footer message you want to send.
+ */
+ KelpPlayer setTabListHeaderAndFooter(String header, String footer);
- public String getTabListHeader() {
- return tabListHeader;
- }
+ String getTabListFooter();
- public boolean isOperator() {
- return playerVersionTemplate.isOperator(bukkitPlayer);
- }
+ String getTabListHeader();
- public KelpPlayer makeOperator() {
- playerVersionTemplate.setOperator(bukkitPlayer, true);
- return this;
- }
+ /**
+ * Gets the version number of the client's protocol. You
+ * can convert this information to the release name with the
+ * help of this list: https://wiki.vg/Protocol_version_numbers
+ * Please note that you should use the versions after the Netty
+ * rewrite.
+ *
+ * @return The protocol version number.
+ */
+ int getProtocolVersion();
- public KelpPlayer removeOperator() {
- playerVersionTemplate.setOperator(bukkitPlayer, false);
- return this;
- }
+ /**
+ * Checks if the given player is a server operator. A server operator
+ * is a player, who has all permissions and can execute every
+ * command.
+ *
+ * @return {@code true} if the player is a server operator.
+ */
+ boolean isOperator();
- public KelpPlayer toggleOperator() {
- if (this.isOperator()) {
- this.removeOperator();
- } else {
- this.makeOperator();
- }
+ default KelpPlayer makeOperator() {
+ setOperator(true);
return this;
}
- public KelpPlayer setOperator(boolean operator) {
- playerVersionTemplate.setOperator(bukkitPlayer, operator);
+ default KelpPlayer removeOperator() {
+ setOperator(false);
return this;
}
- public KelpPlayer grantPermission(String permissionName) {
- playerVersionTemplate.givePermission(bukkitPlayer, permissionName);
+ default KelpPlayer toggleOperator() {
+ setOperator(!isOperator());
return this;
}
- public KelpPlayer removePermission(String permissionName) {
- playerVersionTemplate.removePermission(bukkitPlayer, permissionName);
- return this;
- }
+ /**
+ * Sets the player to a server operator. A server operator
+ * is a player, who has all permissions and can execute every
+ * command.
+ *
+ * @param operator {@code true} If you want to make the player an operator.
+ */
+ KelpPlayer setOperator(boolean operator);
- public boolean hasPermission(String permissionName) {
- return playerVersionTemplate.hasPermission(bukkitPlayer, permissionName);
- }
+ /**
+ * Gives the player the desired permission.
+ *
+ * @param permission The name of the permission you want to give the player.
+ */
+ KelpPlayer grantPermission(String permission);
- public boolean isBannedByBukkit() {
- return playerVersionTemplate.isBannedByBukkit(bukkitPlayer);
- }
+ /**
+ * Removes the specified permission from the given player.
+ *
+ * @param permission The name of the permission you want to remove.
+ */
+ KelpPlayer removePermission(String permission);
- public boolean isWhitelisted() {
- return playerVersionTemplate.isWhitelisted(bukkitPlayer);
- }
+ /**
+ * Checks if the given player has the desired permission.
+ *
+ * @param permission The permission you want to check for.
+ * @return {@code true} if the player has the permission.
+ */
+ boolean hasPermission(String permission);
- public KelpPlayer whitelist() {
- playerVersionTemplate.setOperator(bukkitPlayer, true);
- return this;
- }
+ /**
+ * Checks if the given player is currently banned from the server.
+ * This does only check if the player was banned by the
+ * bukkit server using the normal {@code /ban} command. If another
+ * plugin has banned the player, this is ignored.
+ *
+ * @return {@code true} if the player has been banned by the bukkit server.
+ */
+ boolean isBannedByBukkit();
- public KelpPlayer removeFromWhitelist() {
- playerVersionTemplate.setOperator(bukkitPlayer, false);
- return this;
- }
+ /**
+ * Checks if the player is on the bukkit whitelist.
+ *
+ * @return {@code true} if the player is whitelisted.
+ */
+ boolean isWhitelisted();
- public KelpPlayer toggleWhitelist() {
- if (this.isOperator()) {
- this.removeOperator();
- } else {
- this.makeOperator();
- }
+ default KelpPlayer whitelist() {
+ setWhitelisted(true);
return this;
}
- public KelpPlayer setWhitelisted(boolean whitelisted) {
- playerVersionTemplate.setWhitelisted(bukkitPlayer, whitelisted);
+ default KelpPlayer removeFromWhitelist() {
+ setWhitelisted(false);
return this;
}
- @Override
- public KelpPlayer sendMessage(String message) {
- playerVersionTemplate.sendMessage(bukkitPlayer, message);
+ default KelpPlayer toggleWhitelist() {
+ setWhitelisted(!isWhitelisted());
return this;
}
- public KelpPlayer sendMessages(String... messages) {
+ /**
+ * Sets the player whitelisted or not whitelisted to the server.
+ *
+ * The whitelist determines which players are allowed to join the server
+ * and which are not. It has to be enabled manually by the server owner.
+ *
+ * @param whitelisted {@code true} if the player should be whitelisted.
+ */
+ KelpPlayer setWhitelisted(boolean whitelisted);
+
+ KelpLocation getBedSpawnLocation();
+
+ /**
+ * Sends the given player a message into their chat.
+ *
+ * @param message The message itself. May contain color codes.
+ */
+ KelpPlayer sendMessage(String message);
+
+ default KelpPlayer sendMessages(String... messages) {
for (String message : messages) {
- playerVersionTemplate.sendMessage(bukkitPlayer, message);
+ sendMessage(message);
}
return this;
}
- public KelpPlayer sendMessages(Collection messages) {
+ default KelpPlayer sendMessages(Collection messages) {
for (String message : messages) {
- playerVersionTemplate.sendMessage(bukkitPlayer, message);
+ sendMessage(message);
}
return this;
}
- public KelpPlayer sendPrefixedMessages(String prefix, String... messages) {
+ default KelpPlayer sendPrefixedMessages(String prefix, String... messages) {
for (String message : messages) {
sendMessage(prefix + message);
}
return this;
}
- public KelpPlayer sendPrefixedMessages(String prefix, Collection messages) {
+ default KelpPlayer sendPrefixedMessages(String prefix, Collection messages) {
for (String message : messages) {
sendMessage(prefix + message);
}
return this;
}
- public void sendCenteredMessage(String message) {
+ default KelpPlayer sendCenteredMessage(String message) {
Preconditions.checkNotNull(message);
if(message.equals("")) {
this.sendMessage("");
@@ -946,21 +1189,24 @@ public void sendCenteredMessage(String message) {
compensated += spaceLength;
}
this.sendMessage(sb.toString() + message);
+ return this;
}
- public void sendCenteredMessages(String... messages) {
+ default KelpPlayer sendCenteredMessages(String... messages) {
for (String s : messages) {
this.sendCenteredMessage(s);
}
+ return this;
}
- public void sendCenteredMessages(Collection messages) {
+ default KelpPlayer sendCenteredMessages(Collection messages) {
for (String s : messages) {
this.sendCenteredMessage(s);
}
+ return this;
}
- public void sendCenteredMessages(String header, String footer, String... messages) {
+ default KelpPlayer sendCenteredMessages(String header, String footer, String... messages) {
if (header != null) {
this.sendMessage(header);
}
@@ -970,9 +1216,10 @@ public void sendCenteredMessages(String header, String footer, String... message
if (footer != null) {
this.sendMessage(footer);
}
+ return this;
}
- public void sendCenteredMessages(String header, Collection messages, String footer) {
+ default KelpPlayer sendCenteredMessages(String header, Collection messages, String footer) {
if (header != null) {
this.sendMessage(header);
}
@@ -982,6 +1229,7 @@ public void sendCenteredMessages(String header, Collection messages, Str
if (footer != null) {
this.sendMessage(footer);
}
+ return this;
}
/**
@@ -1000,9 +1248,7 @@ public void sendCenteredMessages(String header, Collection messages, Str
* style, no exception will be thrown, but {@code SOLID} is chosen
* automatically.
*/
- public void sendBossBar(String message, float health, BossBarColor barColor, BossBarStyle barStyle) {
- playerVersionTemplate.sendBossBar(bukkitPlayer, message, health, barColor, barStyle);
- }
+ KelpPlayer sendBossBar(String message, float health, BossBarColor barColor, BossBarStyle barStyle);
/**
* Sends a boss bar to the player by spawning a boss entity near it.
@@ -1012,8 +1258,8 @@ public void sendBossBar(String message, float health, BossBarColor barColor, Bos
*
* @param message The message you want to be displayed above the boss bar.
*/
- public void sendBossBar(String message) {
- playerVersionTemplate.sendBossBar(bukkitPlayer, message, 300f, BossBarColor.PURPLE, BossBarStyle.SOLID);
+ default KelpPlayer sendBossBar(String message) {
+ return sendBossBar(message, 300f, BossBarColor.PURPLE, BossBarStyle.SOLID);
}
/**
@@ -1025,9 +1271,7 @@ public void sendBossBar(String message) {
*
* @param health The health of the boss bar entity.
*/
- public void setBossBarProgressHealth(float health) {
- playerVersionTemplate.setBossBarProgress(bukkitPlayer, health);
- }
+ KelpPlayer setBossBarProgressHealth(float health);
/**
* Sets the progress of the player's boss bar, where 1 means
@@ -1036,9 +1280,10 @@ public void setBossBarProgressHealth(float health) {
*
* @param percentage The percentage value of the progress between 0 and 1.
*/
- public void setBossBarProgress(double percentage) {
+ default KelpPlayer setBossBarProgress(double percentage) {
float health = 300f * (float) percentage;
setBossBarProgressHealth(health);
+ return this;
}
/**
@@ -1052,9 +1297,10 @@ public void setBossBarProgress(double percentage) {
* @param current The current state of reaching the maximum in absolute numbers.
* @param max The maximum value that is reachable for parameter {@code current}.
*/
- public void setBossBarProgress(int current, int max) {
+ default KelpPlayer setBossBarProgress(int current, int max) {
double percentage = (double) current / (double) max;
setBossBarProgress(percentage);
+ return this;
}
/**
@@ -1068,17 +1314,16 @@ public void setBossBarProgress(int current, int max) {
* @param current The current state of reaching the maximum in absolute numbers.
* @param max The maximum value that is reachable for parameter {@code current}.
*/
- public void setBossBarProgress(double current, double max) {
+ default KelpPlayer setBossBarProgress(double current, double max) {
double percentage = current / max;
setBossBarProgress(percentage);
+ return this;
}
/**
* Makes the boss bar disappear for the player.
*/
- public void removeBossBar() {
- playerVersionTemplate.removeBossBar(bukkitPlayer);
- }
+ KelpPlayer removeBossBar();
/**
* Sends an interactive message to the player. An interactive message is a message
@@ -1089,18 +1334,46 @@ public void removeBossBar() {
*
* @param interactiveMessage The interactive message you want to send to the player.
*/
- public void sendInteractiveMessage(InteractiveMessage interactiveMessage) {
- playerVersionTemplate.sendInteractiveMessage(bukkitPlayer, interactiveMessage);
- }
+ KelpPlayer sendInteractiveMessage(InteractiveMessage interactiveMessage);
/**
- * Gets the bukkit instance of the current {@link Player}. Be aware that
- * by using this, you might lose version independence.
+ * Gets the bukkit instance of this player.
+ * This can be used to access bukkit methods if you cannot
+ * find the appropriate kelp equivalent in this class.
*
- * @return The current bukkit player instance.
+ * @return The instance of the bukkit player equivalent to this kelp player.
*/
- public Player getBukkitPlayer() {
- return bukkitPlayer;
+ Player getBukkitPlayer();
+
+ /**
+ * This class allows for hidden access for dependencies used in the
+ * {@link KelpPlayer} class. Instead of creating interface methods
+ * that should not be publicly available, they are wrapped into this
+ * class as private interface methods are only compatible with Java
+ * 1.9 upwards.
+ *
+ * This should give the incentive to developers to avoid using
+ * one of those methods as version templates are not safe and might change
+ * over time.
+ *
+ * @author pxav
+ */
+ final class Dependencies {
+ private static SignPromptVersionTemplate getSignPromptVersionTemplate() {
+ return KelpPlugin.getInjector().getInstance(SignPromptVersionTemplate.class);
+ }
+ private static KelpInventoryRepository getInventoryRepository() {
+ return KelpPlugin.getInjector().getInstance(KelpInventoryRepository.class);
+ }
+ private static ParticleVersionTemplate getParticleVersionTemplate() {
+ return KelpPlugin.getInjector().getInstance(ParticleVersionTemplate.class);
+ }
+ private static AnvilPromptVersionTemplate getAnvilPromptVersionTemplate() {
+ return KelpPlugin.getInjector().getInstance(AnvilPromptVersionTemplate.class);
+ }
+ private static ChatPromptVersionTemplate getChatPromptVersionTemplate() {
+ return KelpPlugin.getInjector().getInstance(ChatPromptVersionTemplate.class);
+ }
}
}
diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java
index 4e0605f1..6f463a9e 100644
--- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java
+++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java
@@ -3,22 +3,16 @@
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import de.pxav.kelp.core.entity.version.EntityVersionTemplate;
-import de.pxav.kelp.core.entity.version.LivingEntityVersionTemplate;
import de.pxav.kelp.core.inventory.KelpInventoryRepository;
import de.pxav.kelp.core.logger.KelpLogger;
-import de.pxav.kelp.core.logger.LogLevel;
import de.pxav.kelp.core.particle.version.ParticleVersionTemplate;
import de.pxav.kelp.core.player.prompt.anvil.AnvilPromptVersionTemplate;
import de.pxav.kelp.core.player.prompt.chat.ChatPromptVersionTemplate;
import de.pxav.kelp.core.player.prompt.sign.SignPromptVersionTemplate;
import de.pxav.kelp.core.sidebar.SidebarRepository;
-import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
-import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
@@ -44,34 +38,24 @@ public class KelpPlayerRepository {
// provided by this map.
private ConcurrentMap playerEntities = Maps.newConcurrentMap();
- private PlayerVersionTemplate playerVersionTemplate;
private SidebarRepository sidebarRepository;
private KelpInventoryRepository inventoryRepository;
private KelpLogger logger;
- private EntityVersionTemplate entityVersionTemplate;
- private LivingEntityVersionTemplate livingEntityVersionTemplate;
private ParticleVersionTemplate particleVersionTemplate;
private SignPromptVersionTemplate signPromptVersionTemplate;
private AnvilPromptVersionTemplate anvilPromptVersionTemplate;
private ChatPromptVersionTemplate chatPromptVersionTemplate;
@Inject
- public KelpPlayerRepository(PlayerVersionTemplate playerVersionTemplate,
- //SidebarRepository sidebarRepository,
- KelpInventoryRepository inventoryRepository,
+ public KelpPlayerRepository(KelpInventoryRepository inventoryRepository,
KelpLogger logger,
- EntityVersionTemplate entityVersionTemplate,
- LivingEntityVersionTemplate livingEntityVersionTemplate,
ParticleVersionTemplate particleVersionTemplate,
SignPromptVersionTemplate signPromptVersionTemplate,
AnvilPromptVersionTemplate anvilPromptVersionTemplate,
ChatPromptVersionTemplate chatPromptVersionTemplate) {
- this.playerVersionTemplate = playerVersionTemplate;
//this.sidebarRepository = sidebarRepository;
this.inventoryRepository = inventoryRepository;
this.logger = logger;
- this.entityVersionTemplate = entityVersionTemplate;
- this.livingEntityVersionTemplate = livingEntityVersionTemplate;
this.particleVersionTemplate = particleVersionTemplate;
this.signPromptVersionTemplate = signPromptVersionTemplate;
this.anvilPromptVersionTemplate = anvilPromptVersionTemplate;
@@ -144,64 +128,7 @@ public KelpPlayer getKelpPlayer(UUID uuid) {
* {@code null} will be returned.
*/
public KelpPlayer getKelpPlayer(Player bukkitPlayer) {
- UUID uuid = playerVersionTemplate.getUniqueId(bukkitPlayer);
- return getKelpPlayer(uuid);
- }
-
- /**
- * Creates a new {@code KelpPlayer} instance based on the
- * player's bukkit object.
- *
- * Generally it is not recommended to create new KelpPlayer
- * instances as an application developer, because this is handled
- * by the version templates. They intercept settings packets when
- * a player sends them and put this information into a map.
- *
- * If you always create new instances it is not guaranteed that
- * this information is accessible for you, because it has never
- * been set. If you try to query it, exceptions might be thrown.
- *
- * If you do not know what you're doing, use {@code #getKelpPlayer}
- * methods instead.
- *
- * @param bukkitPlayer The bukkit player object of the player you
- * want to create an instance of.
- * @return The final {@code KelpPlayer} object. If the player is not
- * online, {@code null} will be returned.
- */
- public KelpPlayer newKelpPlayer(Player bukkitPlayer) {
- return this.newKelpPlayerFrom(bukkitPlayer);
- }
-
- /**
- * Creates a new {@code KelpPlayer} instance based on the
- * player's UUID.
- *
- * Generally it is not recommended to create new KelpPlayer
- * instances as an application developer, because this is handled
- * by the version templates. They intercept settings packets when
- * a player sends them and put this information into a map.
- *
- * If you always create new instances it is not guaranteed that
- * this information is accessible for you, because it has never
- * been set. If you try to query it, exceptions might be thrown.
- *
- * If you do not know what you're doing, use {@code #getKelpPlayer}
- * methods instead.
- *
- * @param uuid The UUID of the player you want to create an
- * instance of.
- * @return The final {@code KelpPlayer} object. If the player is not
- * online, {@code null} will be returned.
- */
- public KelpPlayer newKelpPlayer(UUID uuid) {
- Player bukkitPlayer = Bukkit.getPlayer(uuid);
- if (bukkitPlayer == null) {
- logger.log(LogLevel.WARNING, "Given player UUID for getting a new KelpPlayer failed." +
- "This player is not online, returning null!");
- return null;
- }
- return this.newKelpPlayerFrom(bukkitPlayer);
+ return getKelpPlayer(bukkitPlayer.getUniqueId());
}
/**
@@ -215,30 +142,4 @@ public void removeKelpPlayer(UUID uuid) {
this.kelpPlayers.remove(uuid);
}
- /**
- * Creates a new {@code KelpPlayer} instance and automatically
- * injects all dependencies needed.
- *
- * @param bukkitPlayer The bukkit player object you want to create
- * the {@code KelpPlayer} from.
- * @return The final {@code KelpPlayer} object.
- */
- private KelpPlayer newKelpPlayerFrom(Player bukkitPlayer) {
- return new KelpPlayer(bukkitPlayer,
- playerVersionTemplate,
- //sidebarRepository,
- inventoryRepository,
- this,
- particleVersionTemplate,
- signPromptVersionTemplate,
- anvilPromptVersionTemplate,
- chatPromptVersionTemplate,
- entityVersionTemplate,
- livingEntityVersionTemplate,
- playerVersionTemplate.getUniqueId(bukkitPlayer),
- entityVersionTemplate.getLocation(bukkitPlayer).getBukkitLocation(),
- entityVersionTemplate.getEntityId(bukkitPlayer)
- );
- }
-
}
diff --git a/core/src/main/java/de/pxav/kelp/core/player/PlayerVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/player/PlayerVersionTemplate.java
deleted file mode 100644
index 7cb9938d..00000000
--- a/core/src/main/java/de/pxav/kelp/core/player/PlayerVersionTemplate.java
+++ /dev/null
@@ -1,930 +0,0 @@
-package de.pxav.kelp.core.player;
-
-import de.pxav.kelp.core.application.KelpVersionTemplate;
-import de.pxav.kelp.core.player.bossbar.BossBarColor;
-import de.pxav.kelp.core.player.bossbar.BossBarStyle;
-import de.pxav.kelp.core.player.message.InteractiveMessage;
-import de.pxav.kelp.core.sound.KelpSound;
-import de.pxav.kelp.core.world.KelpLocation;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-import java.net.InetSocketAddress;
-import java.util.UUID;
-
-/**
- * This is a version template for the {@code KelpPlayer}.
- * It contains template methods for all version specific
- * stuff a player can do.
- *
- * @see KelpPlayer
- * @author pxav
- * @author Etrayed
- */
-@KelpVersionTemplate
-public abstract class PlayerVersionTemplate {
-
- /**
- * Sends a title to a player. A title is a big text displayed
- * right in the middle of the player's screen.
- *
- * @param player The player who should see the title.
- * @param title The upper title text (will be displayed slightly bigger than the sub title).
- * @param subTitle The lower title text (will be displayed slightly smaller than the main title).
- * @param fadeIn How long should it take to fade the title in? (in ticks)
- * @param stay How long should the title stay in 100% opacity? (in ticks)
- * @param fadeOut How long should it take to fade the title out? (in ticks)
- */
- public abstract void sendTitle(Player player, String title, String subTitle, int fadeIn, int stay, int fadeOut);
-
- /**
- * Sends an action bar message to the player.
- * The action bar is a line of text, which is displayed
- * above the player's hotbar.
- *
- * @param player The player who should receive the message.
- * @param message The message you want to send.
- */
- public abstract void sendActionBar(Player player, String message);
-
- /**
- * Sets the tab header and footer of player. The tab header is
- * a text displayed above the player list in the tab, while
- * the tab footer is a message displayed below the player list.
- *
- * The messages may contain '\n' to create new lines inside the
- * message.
- *
- * @param player The player who should see the messages.
- * @param header The header message you want to send.
- * @param footer The footer message you want to send.
- */
- public abstract void sendTabHeaderAndFooter(Player player, String header, String footer);
-
- /**
- * Plays a sound to the player.
- *
- * @param player The player who should hear the sound.
- * @param sound The sound you want to play.
- * @param location The location, where the sound should come from.
- * @param volume How loud the sound should be.
- * @param pitch How strong the sound should be pitched.
- */
- public abstract void playSound(Player player, KelpSound sound, KelpLocation location, float volume, float pitch);
-
- /**
- * Sets the player's health.
- *
- * @param player The player whose health you want to change.
- * @param health How many health points the player should have.
- * 2 health points equal 1 heart.
- * So 20 health points equal the full 10 hearts.
- */
- public abstract void setHealth(Player player, int health);
-
- /**
- * @param player The player whose UUID you want to get.
- * @return The player's uuid.
- */
- public abstract UUID getUniqueId(Player player);
-
- /**
- * Checks if the player is currently stuck in a cobweb.
- *
- * @param player The player you want to check.
- * @return {@code true} if the player is currently stuck in a cobweb.
- */
- public abstract boolean isInCobweb(Player player);
-
- /**
- * Checks if the player is currently located in water.
- *
- * @param player The player you want to check.
- * @return {@code true} if the player is currently in water.
- */
- public abstract boolean isInWater(Player player);
-
- // TODO can see -> handle via kelpPlayer class
-
- /**
- * Sends a chat message from the given player.
- * This means you can send a message as if the player itself
- * typed in this message. This also works with commands, if
- * you add a slash in front of the message.
- *
- * @param player The player from whom the message should be sent.
- * @param message The message you want to send.
- */
- public abstract void chat(Player player, String message);
-
- /**
- * Gets the socket address of a specific player.
- *
- * @param player The player whose socket address you want to get.
- * @return The {@code InetSocketAddress} object of the player's address.
- */
- public abstract InetSocketAddress getSocketAddress(Player player);
-
- // TODO advancement/achievement
-
- // TODO statistics and achievements
-
- /**
- * Determines if the Player is allowed to fly via
- * jump key double-tap like in creative mode.
- *
- * If a player flies without permission, they will get kicked
- * by the server automatically.
- *
- * @param player The player you want to check.
- * @return {@code true} if the player is allowed to fly.
- */
- public abstract boolean getAllowFlight(Player player);
-
- // TODO client view distance
-
- /**
- * Gets the display name of a player.
- * The display name is a name which - unlike the normal name -
- * can be modified during the server runtime. You can use this
- * to include custom prefixes, ...
- *
- * @param player The player whose display name you want to get.
- * @return The display name.
- */
- public abstract String getDisplayName(Player player);
-
- /**
- * Sets the display name of a player
- * The display name is a name which - unlike the normal name -
- * can be modified during the server runtime. You can use this
- * to include custom prefixes, ...
- *
- * @param player The player whose display name you want to set.
- * @param displayName The display name you want to set.
- */
- public abstract void setDisplayName(Player player, String displayName);
-
- /**
- * Gets the tab-list name of the player.
- * The tab-list name is the name which is used to represent
- * the player in the tab-list of online players.
- *
- * @param player The player whose tab-list name you want to get.
- * @return The tab-list name.
- */
- public abstract String getPlayerTabListName(Player player);
-
- /**
- * Sets the tab-list name of the player.
- * The tab-list name is the name which is used to represent
- * the player in the tab-list of online players.
- *
- * @param player The player whose tab-list name you want to set.
- * @param tabListName The tab-list name you want to set.
- */
- public abstract void setPlayerTabListName(Player player, String tabListName);
-
- /**
- * Gets the tab-list header of the player.
- * The tab-list header is a text displayed above the
- * list of online players, which is shown when you press tab.
- *
- * @param player The player whose header you want to get.
- * @return The tab-list header string.
- */
- public abstract String getPlayerListHeader(Player player);
-
- /**
- * Gets the tab-list footer of the player.
- * The tab-list footer is a text displayed below the
- * list of online players, which is shown when you press tab.
- *
- * @param player The player whose footer you want to get.
- * @return The tab-list footer string.
- */
- public abstract String getPlayerListFooter(Player player);
-
- /**
- * Sets the tab-list header of the player.
- * The tab-list header is a text displayed above the
- * list of online players, which is shown when you press tab.
- *
- * @param player The player whose header you want to set.
- * @param header The header you want to set. You may use \n
- * to create new lines within this header.
- */
- public abstract void setPlayerListHeader(Player player, String header);
-
- /**
- * Sets the tab-list footer of the player.
- * The tab-list footer is a text displayed below the
- * list of online players, which is shown when you press tab.
- *
- * @param player The player whose footer you want to set.
- * @param footer The footer you want to set. You may use \n
- * to create new lines within this footer.
- */
- public abstract void setPlayerListFooter(Player player, String footer);
-
- /**
- * Sets the compass target of the player.
- * The compass target is the location, where the compass needle
- * points to. By default this is the spawn location of the world,
- * but you could set this to specific player locations as well.
- *
- * @param player The player whose target location you want to update.
- * @param target The location, where the compass should point to.
- */
- public abstract void setCompassTarget(Player player, KelpLocation target);
-
- /**
- * Gets the compass target of the player.
- * The compass target is the location, where the compass needle
- * points to. By default this is the spawn location of the world.
- *
- * @param player The player whose compass target you want to set.
- * @return The target location of the player's compass.
- */
- public abstract KelpLocation getCompassTarget(Player player);
-
- /**
- * Kicks the given player from the server.
- *
- * @param player The player who should be kicked.
- * @param kickMessage The message, which should be received by the player.
- * Could also be named kick reason.
- */
- public abstract void kickPlayer(Player player, String kickMessage);
-
- /**
- * Checks if the player is currently sneaking/crouching.
- * @return {@code true} if the player is sneaking.
- */
- public abstract boolean isSneaking(Player player);
-
- /**
- * Modifies the sneak state of the player.
- *
- * @param player The player whose sneak state you want to change.
- * @param sneaking {@code true} if you want to make the player sneak.
- * {@code false}, if not.
- */
- public abstract void setSneaking(Player player, boolean sneaking);
-
- /**
- * Checks if the player is currently sprinting.
- * Sprinting is active when the player has double-pressed the
- * walking key or pressed the walking and sprinting key at
- * once.
- *
- * @return {@code true} if the player is currently sprinting.
- */
- public abstract boolean isSprinting(Player player);
-
- /**
- * Changes the sprinting state of a player.
- * Sprinting is active when the player has double-pressed the
- * walking key or pressed the walking and sprinting key at
- * once.
- *
- * @param player The player you want to change the sprinting state of.
- * @param sprinting {@code true} if the player should be sprinting.
- */
- public abstract void setSprinting(Player player, boolean sprinting);
-
- // void saveData();
-
- // void loadData();
-
- /**
- * Sets the player ignored when the server checks who is sleeping.
- *
- * When it is night, normally all players have to sleep so that the
- * time can jump to morning. If you don't want all players to sleep,
- * you can give specific players this flag and they don't have to sleep
- * anymore.
- *
- * If you give this flag to all players, nothing will happen at night.
- * So there has to be at least one player sleeping at night.
- *
- * @param player The player you want to change the ignoring state of.
- * @param ignored {@code true} if the player should be ignored when sleeping.
- */
- public abstract void setSleepingIgnored(Player player, boolean ignored);
-
- /**
- * Checks if the player is ignored when the server checks who is sleeping.
- *
- * When it is night, normally all players have to sleep so that the
- * time can jump to morning. If you don't want all players to sleep,
- * you can give specific players this flag and they don't have to sleep
- * anymore.
- *
- * If you give this flag to all players, nothing will happen at night.
- * So there has to be at least one player sleeping at night.
- *
- * @param player The player you want to change the ignoring state of.
- * @return {@code true} if the player has the ignore flag.
- */
- public abstract boolean isSleepingIgnored(Player player);
-
-// public abstract void playNote(Player player, Location from, Instrument instrument, Note note);
-//
-// public abstract void sendBlockChange(Player player, Location blockLocation, @NotNull BlockData var2);
-//
-// public abstract void sendSignChange(@NotNull Location var1, @Nullable String[] var2) throws IllegalArgumentException;
-//
-// public abstract void sendSignChange(@NotNull Location var1, @Nullable String[] var2, @NotNull DyeColor var3) throws IllegalArgumentException;
-//
-// public abstract void sendMap(@NotNull MapView var1);
-
- /**
- * Sets the player time. Each player can have an individual time
- * - even if they are in the same world.
- *
- * @param player The player whose time you want to set.
- * @param time If {@code relative} is set to {@code true}, this is the
- * time offset to the server time in ticks. If {@code relative}
- * is set to {@code false} it is the absolute day time ticks.
- * @param relative {@code true} if the {@code time} should stay relative
- * to the server time.
- */
- public abstract void setPlayerTime(Player player, long time, boolean relative);
-
- /**
- * Gets the current player time. Each player can have an
- * individual time - even if they are in the same world.
- *
- * @param player The player whose time you want to get.
- * @return The current time of the player in ticks.
- */
- public abstract long getPlayerTime(Player player);
-
- /**
- * If the player time was set with {@code relative} to {@code true},
- * then it will get the offset of the player time to the current server
- * time. If {@code relative} was set to {@code false}, it will simply
- * return the current player time.
- *
- * @param player The player whose time (offset) you want to check.
- * @return The player's time (offset).
- */
- public abstract long getPlayerTimeOffset(Player player);
-
- /**
- * Checks if the player time set for the player is relative
- * to the server time. More information can be found
- * at {@code #setPlayerTime(player, time, relative)}
- *
- * @param player The player you want to check.
- * @return {@code true} if player time is relative to server time.
- */
- public abstract boolean isPlayerTimeRelative(Player player);
-
- /**
- * Resets the player time back to the current server
- * time. So the times of both are synchronized again.
- *
- * @param player The player whose time you want to reset.
- */
- public abstract void resetPlayerTime(Player player);
-
- // public abstract void setPlayerWeather(@NotNull WeatherType var1);
-
- // public abstract WeatherType getPlayerWeather();
-
- // public abstract void resetPlayerWeather();
-
- /**
- * Gives the player the given amount of experience.
- * This method simply adds the given amount to the player's
- * current exp count and does not overwrite anything.
- *
- * @param player The player you want to give the experience to.
- * @param amount The amount of experience to give.
- */
- public abstract void giveExperience(Player player, int amount);
-
- /**
- * Gives or takes the player the given amount of experience.
- * Negative amounts express that levels should be taken
- * away from the player, positive amounts will be added.
- *
- * @param player The player you want to give the levels to.
- * @param amount The amount of levels to give or take.
- */
- public abstract void giveExperienceLevels(Player player, int amount);
-
- /**
- * Gets the current experience of the given player.
- *
- * Experience is a percentage value (ranging from 0 to 1)
- * indicating the progress to the next full level.
- * 0 means he has just reached a new level and has made no
- * progress since then, wile 1 says the player is just about
- * to reach a new level.
- *
- * Inside Minecraft, the experience is represented by the
- * green bar above the hotbar.
- *
- * @param player The player whose experience you want to get.
- * @return The current experience progress (from 0 to 1).
- */
- public abstract float getExperience(Player player);
-
- /**
- * Sets the current experience of the given player.
- *
- * Experience is a percentage value (ranging from 0 to 1)
- * indicating the progress to the next full level.
- * 0 means he has just reached a new level and has made no
- * progress since then, wile 1 says the player is just about
- * to reach a new level.
- *
- * Inside Minecraft, the experience is represented by the
- * green bar above the hotbar.
- *
- * @param player The player whose experience you want to set.
- * @param experience The experience value you want to set.
- * May range from 0 to 1.
- */
- public abstract void setExperience(Player player, float experience);
-
- /**
- * Gets the current amount of the player's levels.
- *
- * Levels are reached when the experience count reaches 1.
- * The amount of levels is represented by the small green
- * number above the level bar.
- *
- * @param player The player whose levels you want to get.
- * @return The current amount of levels.
- */
- public abstract int getLevel(Player player);
-
- /**
- * Sets the current amount of the player's levels.
- *
- * Levels are reached when the experience count reaches 1.
- * The amount of levels is represented by the small green
- * number above the level bar.
- *
- * @param player The player whose levels you want to set.
- * @param level The new level count to set.
- */
- public abstract void setLevel(Player player, int level);
-
- /**
- * Gets the players total experience points.
- *
- * This refers to the total amount of experience
- * the player has collected over time and is not currently
- * displayed to the client.
- *
- * @param player The player whose total experience you want to get.
- * @return The total experience points amount.
- */
- public abstract int getTotalExperience(Player player);
-
- /**
- * Sets the players total experience points.
- *
- * This refers to the total amount of experience
- * the player has collected over time and is not currently
- * displayed to the client.
- *
- * @param player The player whose total experience you want to get.
- * @param experience The new amount of total experience.
- */
- public abstract void setTotalExperience(Player player, int experience);
-
- /**
- * Gets the player's current exhaustion level.
- * Exhaustion controls how fast the food level drops.
- * While you have a certain amount of exhaustion,
- * your saturation will drop to zero, and then your
- * food will drop to zero.
- *
- * @param player The player you want to get the exhaustion level of.
- * @return The exhaustion level of the current player.
- */
- public abstract float getExhaustion(Player player);
-
- /**
- * Sets the player's current exhaustion level.
- * Exhaustion controls how fast the food level drops.
- * While you have a certain amount of exhaustion,
- * your saturation will drop to zero, and then your
- * food will drop to zero.
- *
- * @param exhaustionLevel The exhaustion level you want to set.
- */
- public abstract void setExhaustion(Player player, float exhaustionLevel);
-
- /**
- * Gets the saturation level of a player.
- * Saturation is a buffer for food level.
- * Your food level will not drop if you are saturated > 0.
- *
- * @param player The player whose saturation level you want to get.
- * @return The saturation of the player.
- */
- public abstract float getSaturation(Player player);
-
- /**
- * Sets the saturation level of a player.
- * Saturation is a buffer for food level.
- * Your food level will not drop if you are saturated > 0.
- *
- * @param player The player whose saturation level you want
- * to set.
- * @param saturation The saturation level you want to set.
- */
- public abstract void setSaturation(Player player, float saturation);
-
- /**
- * Gets the current food level of the player. The
- * food level indicates how full the food bar is.
- * 20 means a full food bar, 0 an empty food bar.
- *
- * @param player The player whose food bar you want to change.
- * @return The food level of the player.
- */
- public abstract int getFoodLevel(Player player);
-
- /**
- * Sets the food level of a player.
- * The food level indicates how full the food bar is.
- * 20 means a full food bar, 0 an empty food bar.
- *
- * @param player The player whose food level you want to change.
- * @param foodLevel The absolute food level you want to set.
- */
- public abstract void setFoodLevel(Player player, int foodLevel);
-
- /**
- * Sets if the player is allowed to fly as if he was in creative
- * mode
- *
- * @param player The player you want to allow/disallow flying
- * for.
- * @param allowFlight {@code true} if you want to allow, {@code false}
- * if not.
- */
- public abstract void setAllowFlight(Player player, boolean allowFlight);
-
- /**
- * Hides a player from another player, so they become invisible
- * for the other player.
- *
- * @param player The player who should not see {@code toHide}
- * anymore.
- * @param toHide The player you want to hide.
- */
- public abstract void hidePlayer(Player player, Player toHide);
-
- /**
- * Shows a player to another player again, so they become visible
- * for the other player.
- *
- * @param player The player who should see {@code toShow}
- * again.
- * @param toShow The player you want to show.
- */
- public abstract void showPlayer(Player player, Player toShow);
-
- /**
- * Checks if the given player can see the targeted player.
- * This does not check if the player currently really sees
- * the given target player, but if the player is not hidden.
- *
- * @param player The player who should see the target player.
- * @param toCheck The player to check if he is visible for the
- * other player.
- * @return {@code true} if {@code player} can see {@code toCheck}.
- */
- public abstract boolean canSee(Player player, Player toCheck);
-
- /**
- * Checks if the player is currently flying.
- *
- * @return {@code true} if the player is flying.
- */
- public abstract boolean isFlying(Player player);
-
- /**
- * Changes the flying state of the player.
- *
- * @param player The player you want to change the flying state of.
- * @param flying {@code true} if you want to make the player fly.
- * {@code false} if you don't want to make the player fly.
- */
- public abstract void setFlying(Player player, boolean flying);
-
- /**
- * Sets the current fly speed of a player. The higher
- * the value the higher the speed. Negative values
- * indicate reverse directions.
- *
- * @param player The player whose speed you want to set.
- * @param flySpeed The desired fly speed. The value may
- * range from -1 to 1.
- */
- public abstract void setFlySpeed(Player player, float flySpeed);
-
- /**
- * Sets the current walk speed of a player. The higher
- * the value the higher the speed. Negative values
- * indicate reverse directions.
- *
- * @param player The player whose speed you want to set.
- * @param walkSpeed The desired walk speed. The value may
- * range from -1 to 1.
- */
- public abstract void setWalkSpeed(Player player, float walkSpeed);
-
- /**
- * Gets the current speed a player can fly. The higher
- * the value the higher the speed. Negative values
- * indicate reverse directions.
- *
- * @return The current fly speed of a player.
- * Value can range from -1 to 1
- */
- public abstract float getFlySpeed(Player player);
-
- /**
- * Gets the current speed a player can walk. The higher
- * the value the higher the speed. Negative values
- * indicate reverse directions.
- *
- * @return The current walk speed of a player.
- * Value can range from -1 to 1
- */
- public abstract float getWalkSpeed(Player player);
-
- /**
- * Request that the player's client download and switch resource packs.
- *
- * The player's client will download the new resource pack asynchronously
- * in the background, if the request was accepted, and will automatically switch to it once the download
- * is complete. If the client has downloaded and cached a resource pack
- * with the same hash in the past it will not download but directly apply
- * the cached pack. When this request is sent for the very first time
- * from a given server, the client will first display a confirmation GUI
- * to the player before proceeding with the download.
- *
- * @param player The player who should download the Resource pack.
- * @param url The URL from which the client will download the resource pack.
- * The string must contain only US-ASCII characters
- * and should be encoded as per RFC 1738.
- */
- public abstract void setResourcePack(Player player, String url);
-
- /**
- * Request that the player's client download and switch resource packs.
- *
- * The player's client will download the new resource pack asynchronously
- * in the background, if the request was accepted, and will automatically switch to it once the download
- * is complete. If the client has downloaded and cached a resource pack
- * with the same hash in the past it will not download but directly apply
- * the cached pack. When this request is sent for the very first time
- * from a given server, the client will first display a confirmation GUI
- * to the player before proceeding with the download.
- *
- * @param player The player who should download the Resource pack.
- * @param url The URL from which the client will download the resource pack.
- * The string must contain only US-ASCII characters
- * and should be encoded as per RFC 1738.
- * @param hash The sha1 hash sum of the resource pack file
- * which is used to apply a cached version of the pack
- * directly without downloading if it is available.
- * Has to be 20 bytes long!
- */
- public abstract void setResourcePack(Player player, String url, byte[] hash);
-
- /**
- * Checks if the player has received the scaled health bar
- * from the server.
- *
- * @return {@code true} if the player's health bar scale is up to date.
- */
- public abstract boolean isHealthScaled(Player player);
-
- /**
- * Sets if the player is shown the scaled health bar.
- * If you modify your health scale with {@code setHealthScale},
- * you have to say the server to send this new scaled health
- * to the player.
- *
- * @param player The player you want to scale the health of.
- * @param scaled {@code true} whether the health should be scaled.
- */
- public abstract void setHealthScaled(Player player, boolean scaled);
-
- /**
- * Sets the health scale of the given player. The health
- * scale is the maximum amount of hearts displayed to the
- * client.
- * 2 means one heart is displayed. If you choose values
- * above 20, the player will get additional hearts.
- * Consider changing the max health as well.
- *
- * This method will automatically set {@code setHealthScaled} to
- * {@code true}.
- *
- * @param player The player whose amount of scaled health you want
- * to set.
- * @param healthScale The amount of scaled health you want to set.
- */
- public abstract void setHealthScale(Player player, double healthScale);
-
- /**
- * Gets the number of scaled health points,
- * which are currently displayed to the client.
- *
- * @param player The player whose health scale you want to get.
- * @return The number of scaled health if health
- * scaling was set to {@code true} earlier.
- */
- public abstract double getHealthScale(Player player);
-
-// public abstract Entity getSpectatorTarget();
-//
-// public abstract void setSpectatorTarget(Player player, Entity entity);
-
- /**
- * Cancels the title animation for a player. The current
- * title is removed immediately.
- *
- * @param player The player whose title should be reset.
- */
- public abstract void resetTitle(Player player);
-
- // TODO update commands
-
- public abstract void openBook(Player player, ItemStack book);
-
- /**
- * Gets the version number of the client's protocol. You
- * can convert this information to the release name with the
- * help of this list: https://wiki.vg/Protocol_version_numbers
- * Please note that you should use the versions after the Netty
- * rewrite.
- *
- * @param player The player whose protocol version you want to get.
- * @return The protocol version number.
- */
- public abstract int getProtocolVersion(Player player);
-
- /**
- * Sets the player to a server operator. A server operator
- * is a player, who has all permissions and can execute every
- * command.
- *
- * @param player The player you want to change the operator state of.
- * @param value {@code true} If you want to make the player an operator.
- */
- public abstract void setOperator(Player player, boolean value);
-
- /**
- * Checks if the given player is a server operator. A server operator
- * is a player, who has all permissions and can execute every
- * command.
- *
- * @param player The player you want to check the operator state of.
- * @return {@code true} if the player is a server operator.
- */
- public abstract boolean isOperator(Player player);
-
- /**
- * Gives the player the desired permission.
- *
- * @param player The player who should get the permission.
- * @param permission The name of the permission you want to give the player.
- */
- public abstract void givePermission(Player player, String permission);
-
- /**
- * Removes the specified permission from the given player.
- *
- * @param player The player you want to remove the permission from.
- * @param permission The name of the permission you want to remove.
- */
- public abstract void removePermission(Player player, String permission);
-
- /**
- * Checks if the given player has the desired permission.
- *
- * @param player The player you want to check.
- * @param permission The permission you want to check for.
- * @return {@code true} if the player has the permission.
- */
- public abstract boolean hasPermission(Player player, String permission);
-
- /**
- * Checks if the given player is currently banned from the server.
- * This does only check if the player was banned by the
- * bukkit server using the normal {@code /ban} command. If another
- * plugin has banned the player, this is ignored.
- *
- * @param player The player you want to check.
- * @return {@code true} if the player has been banned by the bukkit server.
- */
- public abstract boolean isBannedByBukkit(Player player);
-
- /**
- * Checks if the player is on the bukkit whitelist.
- *
- * @param player The player you want to check.
- * @return {@code true} if the player is whitelisted.
- */
- public abstract boolean isWhitelisted(Player player);
-
- /**
- * Sets the player whitelisted or not whitelisted.
- *
- * @param player The player you want to whitelist/unwhitelist.
- * @param whitelisted {@code true} if the player should be whitelisted.
- */
- public abstract void setWhitelisted(Player player, boolean whitelisted);
-
- /**
- * Gets the bed spawn location of the player.
- * This is the location, where the player has slept for the
- * last time. A location is only returned if the player has
- * already slept at least once and the location is valid.
- *
- * @param player The player you want to get the bed spawn location of.
- * @return The spawn location, {@code null} if the player has not slept or location is invalid.
- */
- public abstract KelpLocation getBedSpawnLocation(Player player);
-
- /**
- * Sends the given player a message into their chat.
- *
- * @param player The player who should receive the message.
- * @param message The message itself. May contain color codes.
- */
- public abstract void sendMessage(Player player, String message);
-
- /**
- * Sends a boss bar to the player by spawning a boss entity near it. If you use this
- * method in 1.8, please keep in mind that bar colors other than {@code PURPLE} and bar styles
- * other than {@code SOLID} are not supported.
- *
- * @param player The player you want to send the message to.
- * @param message The message you want to be displayed above the boss bar.
- * @param health How much the boss bar should be loaded (equivalent to how much
- * health the boss entity has. 300f is a full boss bar and 0f an empty one).
- * @param barColor The color of the boss bar. Please note that in 1.8 only
- * {@code PURPLE} is allowed. If you use any color, no exception
- * is thrown but purple will be chosen automatically.
- * @param barStyle The style of the boss bar (how many segments?, ...). Note that
- * in 1.8 only {@code SOLID} is supported. If you use any different
- * style, no exception will be thrown, but {@code SOLID} is chosen
- * automatically.
- */
- public abstract void sendBossBar(Player player, String message, float health, BossBarColor barColor, BossBarStyle barStyle);
-
- /**
- * Sets the progress of the player's boss bar by modifying the
- * health of the boss bar entity. As withers are used for that
- * purpose, the maximum value {@code 300f} represents full boss
- * bar and {@code 0f} would be an empty boss bar (equivalent to
- * the wither dieing.)
- *
- * @param health The health of the boss bar entity.
- */
- public abstract void setBossBarProgress(Player player, float health);
-
- /**
- * Makes the boss bar disappear for the given player.
- *
- * @param player The player whose boss bar you want to remove.
- */
- public abstract void removeBossBar(Player player);
-
- /**
- * Sends an interactive message to the player. An interactive message is a message
- * the player can click on and events (execute a command, open a url, ...) are triggered.
- * You can also add hover events to it. You can add as many components as you want.
- * More detailed information about how to build an interactive message can be found out
- * in {@link InteractiveMessage}.
- *
- * @param player The player who should receive this message and be able
- * to interact with it.
- * @param interactiveMessage The actual message you want to send to the player.
- */
- public abstract void sendInteractiveMessage(Player player, InteractiveMessage interactiveMessage);
-
- /**
- * If the player currently sees a sidebar, it will be hidden for the given
- * player. This mostly happens by replacing it with a new, empty scoreboard.
- *
- * @param player The player whose sidebar you want to hide/remove.
- */
- public abstract void removeSidebar(Player player);
-
-}
diff --git a/core/src/main/java/de/pxav/kelp/core/player/prompt/anvil/AnvilPromptVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/player/prompt/anvil/AnvilPromptVersionTemplate.java
index 5709af28..bac88f42 100644
--- a/core/src/main/java/de/pxav/kelp/core/player/prompt/anvil/AnvilPromptVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/player/prompt/anvil/AnvilPromptVersionTemplate.java
@@ -2,7 +2,6 @@
import de.pxav.kelp.core.application.KelpVersionTemplate;
import de.pxav.kelp.core.inventory.material.KelpMaterial;
-import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.player.prompt.PromptTimeout;
import de.pxav.kelp.core.player.prompt.SimplePromptResponseHandler;
import org.bukkit.entity.Player;
diff --git a/core/src/main/java/de/pxav/kelp/core/player/prompt/chat/ChatPromptVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/player/prompt/chat/ChatPromptVersionTemplate.java
index 0089deb2..b82daa63 100644
--- a/core/src/main/java/de/pxav/kelp/core/player/prompt/chat/ChatPromptVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/player/prompt/chat/ChatPromptVersionTemplate.java
@@ -1,12 +1,6 @@
package de.pxav.kelp.core.player.prompt.chat;
import de.pxav.kelp.core.application.KelpVersionTemplate;
-import de.pxav.kelp.core.player.KelpPlayer;
-import de.pxav.kelp.core.player.prompt.PromptTimeout;
-import de.pxav.kelp.core.player.prompt.SimplePromptResponseHandler;
-import org.bukkit.entity.Player;
-
-import java.util.Collection;
/**
* This version template is used for handling the simple chat prompt for players.
diff --git a/core/src/main/java/de/pxav/kelp/core/player/prompt/sign/SignPromptVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/player/prompt/sign/SignPromptVersionTemplate.java
index dc690941..be11cb34 100644
--- a/core/src/main/java/de/pxav/kelp/core/player/prompt/sign/SignPromptVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/player/prompt/sign/SignPromptVersionTemplate.java
@@ -1,7 +1,6 @@
package de.pxav.kelp.core.player.prompt.sign;
import de.pxav.kelp.core.application.KelpVersionTemplate;
-import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.player.prompt.PromptTimeout;
import org.bukkit.entity.Player;
diff --git a/core/src/main/java/de/pxav/kelp/core/reflect/ReflectionUtil.java b/core/src/main/java/de/pxav/kelp/core/reflect/ReflectionUtil.java
index c92a8e70..2d200336 100644
--- a/core/src/main/java/de/pxav/kelp/core/reflect/ReflectionUtil.java
+++ b/core/src/main/java/de/pxav/kelp/core/reflect/ReflectionUtil.java
@@ -1,6 +1,10 @@
package de.pxav.kelp.core.reflect;
+import com.google.common.base.Preconditions;
+
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
/**
* A class description goes here.
@@ -9,7 +13,7 @@
*/
public class ReflectionUtil {
- public Object getValue(Object object, String fieldName) {
+ public static Object getValue(Object object, String fieldName) {
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
@@ -20,7 +24,7 @@ public Object getValue(Object object, String fieldName) {
return null;
}
- public void setValue(Object object, String fieldName, Object value) {
+ public static void setValue(Object object, String fieldName, Object value) {
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
@@ -30,4 +34,54 @@ public void setValue(Object object, String fieldName, Object value) {
}
}
+ // method name without "(" and ")"
+ public static void invokeMethod(Object holdingObject, String methodName, Object... parameters) {
+ Preconditions.checkNotNull(holdingObject);
+ Preconditions.checkNotNull(methodName);
+ try {
+
+ Method method;
+
+ if (parameters.length > 0) {
+ Class>[] parameterTypes = new Class[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ parameterTypes[i] = parameters[i].getClass();
+ }
+ method = holdingObject.getClass().getDeclaredMethod(methodName, parameterTypes);
+ } else {
+ method = holdingObject.getClass().getDeclaredMethod(methodName);
+ }
+
+ method.setAccessible(true);
+ method.invoke(holdingObject);
+ } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // method name without "(" and ")"
+ public static void invokeStaticMethod(Class> holdingClass, String methodName, Object... parameters) {
+ Preconditions.checkNotNull(holdingClass);
+ Preconditions.checkNotNull(methodName);
+ try {
+
+ Method method;
+
+ if (parameters.length > 0) {
+ Class>[] parameterTypes = new Class[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ parameterTypes[i] = parameters[i].getClass();
+ }
+ method = holdingClass.getDeclaredMethod(methodName, parameterTypes);
+ } else {
+ method = holdingClass.getDeclaredMethod(methodName);
+ }
+
+ method.setAccessible(true);
+ method.invoke(null);
+ } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
}
diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java
index 152e8a7b..27d60347 100755
--- a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java
+++ b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java
@@ -2,12 +2,7 @@
import de.pxav.kelp.core.application.KelpVersionTemplate;
import de.pxav.kelp.core.player.KelpPlayer;
-import de.pxav.kelp.core.sidebar.component.SidebarComponent;
-import de.pxav.kelp.core.sidebar.type.AnimatedSidebar;
import de.pxav.kelp.core.sidebar.type.KelpSidebar;
-import org.bukkit.entity.Player;
-import org.bukkit.scoreboard.Objective;
-import org.bukkit.scoreboard.Scoreboard;
/**
*
diff --git a/core/src/main/java/de/pxav/kelp/core/version/KelpVersion.java b/core/src/main/java/de/pxav/kelp/core/version/KelpVersion.java
index 6b121608..1d9c400e 100644
--- a/core/src/main/java/de/pxav/kelp/core/version/KelpVersion.java
+++ b/core/src/main/java/de/pxav/kelp/core/version/KelpVersion.java
@@ -53,7 +53,15 @@ public enum KelpVersion {
public boolean isFullVersion() { return true; }
},
MC_1_15_1(34, "1.15.1-R0.1-SNAPSHOT"),
- MC_1_15_2(35, "1.15.2-R0.1-SNAPSHOT")
+ MC_1_15_2(35, "1.15.2-R0.1-SNAPSHOT"),
+ MC_1_16_0(36, "1.16-R0.1-SNAPSHOT") {
+ public boolean isFullVersion() { return true; }
+ },
+ MC_1_16_1(37, "1.16.1-R0.1-SNAPSHOT"),
+ MC_1_16_2(38, "1.16.2-R0.1-SNAPSHOT"),
+ MC_1_16_3(39, "1.16.3-R0.1-SNAPSHOT"),
+ MC_1_16_4(40, "1.16.4-R0.1-SNAPSHOT"),
+ MC_1_16_5(41, "1.16.5-R0.1-SNAPSHOT"),
;
private int id;
diff --git a/core/src/main/java/de/pxav/kelp/core/world/KelpBlock.java b/core/src/main/java/de/pxav/kelp/core/world/KelpBlock.java
index 9f72e83a..75109a87 100644
--- a/core/src/main/java/de/pxav/kelp/core/world/KelpBlock.java
+++ b/core/src/main/java/de/pxav/kelp/core/world/KelpBlock.java
@@ -196,6 +196,45 @@ public KelpBlock getRelative(CardinalDirection direction) {
return null;
}
+ /**
+ * Gets the block that is directly attached to this block
+ * to the given face. If you pass {@link KelpBlockFace#UP} for example, then
+ * the block above this block will be returned, and so on.
+ * This is similar to {@link #getRelative(CardinalDirection)} with the main
+ * difference that you can get the block above and below the current block
+ * as you are independent from cardinal directions.
+ *
+ * @param face The face of the block you want to get.
+ * @return The block relative to this block in the given direction.
+ */
+ public KelpBlock getRelative(KelpBlockFace face) {
+ switch (face) {
+ case NORTH:
+ return getNorthernBlock();
+ case NORTH_EAST:
+ return getNorthEasternBlock();
+ case EAST:
+ return getEasternBlock();
+ case SOUTH_EAST:
+ return getSouthEasternBlock();
+ case SOUTH:
+ return getSouthernBlock();
+ case SOUTH_WEST:
+ return getSouthWesternBlock();
+ case WEST:
+ return getWesternBlock();
+ case NORTH_WEST:
+ return getNorthWesternBlock();
+ case UP:
+ return getBlockAbove();
+ case DOWN:
+ return getBlockBelow();
+ case SELF:
+ return this;
+ }
+ return null;
+ }
+
/**
* Gets the block in front of this block relative to the given direction.
*
diff --git a/core/src/main/java/de/pxav/kelp/core/world/KelpWorld.java b/core/src/main/java/de/pxav/kelp/core/world/KelpWorld.java
index 2925f564..fd042115 100644
--- a/core/src/main/java/de/pxav/kelp/core/world/KelpWorld.java
+++ b/core/src/main/java/de/pxav/kelp/core/world/KelpWorld.java
@@ -1,8 +1,9 @@
package de.pxav.kelp.core.world;
import de.pxav.kelp.core.KelpPlugin;
+import de.pxav.kelp.core.entity.KelpEntity;
import de.pxav.kelp.core.entity.type.DroppedItemEntity;
-import de.pxav.kelp.core.entity.type.ItemDropType;
+import de.pxav.kelp.core.entity.util.ItemDropType;
import de.pxav.kelp.core.inventory.item.KelpItem;
import de.pxav.kelp.core.player.KelpPlayer;
import de.pxav.kelp.core.world.util.ExplosionPower;
@@ -11,7 +12,6 @@
import org.bukkit.Bukkit;
import org.bukkit.Difficulty;
import org.bukkit.World;
-import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import java.util.Collection;
import java.util.UUID;
@@ -376,6 +376,18 @@ public Collection