diff --git a/README_EN.md b/README_EN.md
index 8af8718..7d5d976 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -21,7 +21,9 @@ Download the following plugins according to the server core
| GeyserCustomEntity Fork | [Github](https://github.com/zimzaza4/Geyser) | Make Geyser support custom entities |
| GeyserModelEnginePackGenerator | [Github](https://github.com/zimzaza4/GeyserModelEnginePackGenerator) | Help you automatically transform the model to generate resource packs |
-place `GeyserModelEngine` `GeyserCustomEntityFork` in the plugins folder
+replace your Geyser with that Geyser fork
+
+put `GeyserModelEngine` in the plugins folder (only spigot)
and `geyserutils-spigot`/`velocity`/`bungeecord`
diff --git a/libs/geyserutils-spigot-1.0-SNAPSHOT.jar b/libs/geyserutils-spigot-1.0-SNAPSHOT.jar
index d5781c3..ec7de3a 100644
Binary files a/libs/geyserutils-spigot-1.0-SNAPSHOT.jar and b/libs/geyserutils-spigot-1.0-SNAPSHOT.jar differ
diff --git a/pom.xml b/pom.xml
index 4210fee..dc30351 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,7 +112,7 @@
me.zimzaza4
geyserutils-spigot
- 1.0.1
+ 1.0.0
system
${project.basedir}/libs/geyserutils-spigot-1.0-SNAPSHOT.jar
@@ -122,12 +122,6 @@
2.2.2-SNAPSHOT
provided
-
- LibsDisguises
- LibsDisguises
- 10.0.35
- provided
-
com.comphenix.protocol
ProtocolLib
diff --git a/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java b/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java
index 30a02a8..ef7814c 100644
--- a/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java
+++ b/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java
@@ -1,12 +1,15 @@
package re.imc.geysermodelengine;
import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.wrappers.Pair;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
+import com.ticxo.modelengine.api.model.bone.type.Mount;
import lombok.Getter;
+import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
@@ -14,12 +17,13 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import re.imc.geysermodelengine.listener.AddEntityPacketListener;
-import re.imc.geysermodelengine.listener.InteractPacketListener;
import re.imc.geysermodelengine.listener.ModelListener;
+import re.imc.geysermodelengine.listener.MountPacketListener;
import re.imc.geysermodelengine.model.ModelEntity;
import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public final class GeyserModelEngine extends JavaPlugin {
@@ -42,9 +46,27 @@ public final class GeyserModelEngine extends JavaPlugin {
@Getter
private Cache joinedPlayer;
+ @Getter
+ @Setter
+ private boolean spawningModelEntity = false;
+
+
+ @Getter
+ @Setter
+ private ModelEntity currentModel = null;
+
+
@Getter
private int joinSendDelay;
+ @Getter
+ private boolean debug;
+
+ @Getter
+ private Map> drivers = new ConcurrentHashMap<>();
+
+ @Getter
+ private boolean initialized = false;
@Override
public void onEnable() {
// Plugin startup logic
@@ -52,6 +74,7 @@ public final class GeyserModelEngine extends JavaPlugin {
// alwaysSendSkin = getConfig().getBoolean("always-send-skin");
skinSendDelay = getConfig().getInt("skin-send-delay", 0);
viewDistance = getConfig().getInt("skin-view-distance", 60);
+ debug = getConfig().getBoolean("debug", false);
modelEntityType = EntityType.valueOf(getConfig().getString("model-entity-type", "BAT"));
joinSendDelay = getConfig().getInt("join-send-delay", 20);
if (joinSendDelay > 0) {
@@ -59,8 +82,8 @@ public final class GeyserModelEngine extends JavaPlugin {
.expireAfterWrite(joinSendDelay * 50L, TimeUnit.MILLISECONDS).build();
}
instance = this;
- ProtocolLibrary.getProtocolManager().addPacketListener(new InteractPacketListener());
ProtocolLibrary.getProtocolManager().addPacketListener(new AddEntityPacketListener());
+ ProtocolLibrary.getProtocolManager().addPacketListener(new MountPacketListener());
Bukkit.getPluginManager().registerEvents(new ModelListener(), this);
Bukkit.getScheduler()
@@ -76,6 +99,7 @@ public final class GeyserModelEngine extends JavaPlugin {
}
}
}
+ initialized = true;
}, 100);
}
diff --git a/src/main/java/re/imc/geysermodelengine/listener/AddEntityPacketListener.java b/src/main/java/re/imc/geysermodelengine/listener/AddEntityPacketListener.java
index 2bb30ee..fb22064 100644
--- a/src/main/java/re/imc/geysermodelengine/listener/AddEntityPacketListener.java
+++ b/src/main/java/re/imc/geysermodelengine/listener/AddEntityPacketListener.java
@@ -1,16 +1,28 @@
package re.imc.geysermodelengine.listener;
import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.*;
import com.comphenix.protocol.reflect.StructureModifier;
+import com.comphenix.protocol.wrappers.WrappedWatchableObject;
+import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.entity.BukkitEntity;
+import com.ticxo.modelengine.api.entity.Hitbox;
+import com.ticxo.modelengine.api.interaction.DynamicHitbox;
+import com.ticxo.modelengine.api.interaction.InteractionTracker;
+import com.ticxo.modelengine.api.model.bone.type.SubHitbox;
+import com.ticxo.modelengine.api.nms.entity.HitboxEntity;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
import org.geysermc.floodgate.api.FloodgateApi;
import org.jetbrains.annotations.NotNull;
import re.imc.geysermodelengine.GeyserModelEngine;
+import re.imc.geysermodelengine.model.EntityTask;
import re.imc.geysermodelengine.model.ModelEntity;
import java.util.Set;
+import java.util.UUID;
public class AddEntityPacketListener extends PacketAdapter {
public AddEntityPacketListener() {
@@ -19,21 +31,49 @@ public class AddEntityPacketListener extends PacketAdapter {
@Override
public void onPacketSending(PacketEvent event) {
+
PacketContainer packet = event.getPacket();
StructureModifier modifier = packet.getEntityModifier(event);
Entity entity = modifier.readSafely(0);
+
if (entity == null) {
return;
}
+ boolean isBedrock = FloodgateApi.getInstance().isFloodgatePlayer(event.getPlayer().getUniqueId());
ModelEntity model = ModelEntity.MODEL_ENTITIES.get(entity.getEntityId());
+
if (model != null) {
- if (FloodgateApi.getInstance().isFloodgatePlayer(event.getPlayer().getUniqueId())) {
- if (GeyserModelEngine.getInstance().getJoinedPlayer() != null && GeyserModelEngine.getInstance().getJoinedPlayer().getIfPresent(event.getPlayer()) != null) {
- model.getTask().sendEntityData(event.getPlayer(), GeyserModelEngine.getInstance().getJoinSendDelay());
- } else {
- model.getTask().sendEntityData(event.getPlayer(), GeyserModelEngine.getInstance().getSkinSendDelay());
+ if (isBedrock) {
+ if (packet.getMeta("delayed").isPresent()) {
+ if (model.getTask().isLooping()) {
+
+ String lastAnimation = model.getTask().getLastAnimation();
+ model.getTask().playBedrockAnimation(lastAnimation, Set.of(event.getPlayer()), true, 0f);
+ }
+ return;
}
+
+ EntityTask task = model.getTask();
+ int delay = 1;
+ boolean firstJoined = GeyserModelEngine.getInstance().getJoinedPlayer().getIfPresent(event.getPlayer()) != null;
+ if (firstJoined) {
+ delay = GeyserModelEngine.getInstance().getJoinSendDelay();
+ }
+ if (task == null || firstJoined) {
+ Bukkit.getScheduler().runTaskLater(GeyserModelEngine.getInstance(), () -> {
+ model.getTask().sendEntityData(event.getPlayer(), GeyserModelEngine.getInstance().getSkinSendDelay());
+ }, delay);
+ } else {
+ task.sendEntityData(event.getPlayer(), GeyserModelEngine.getInstance().getSkinSendDelay());
+ }
+
+ event.setCancelled(true);
+
+ Bukkit.getScheduler().runTaskLater(GeyserModelEngine.getInstance(), () -> {
+ packet.setMeta("delayed", 1);
+ ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet);
+ }, delay + 2);
} else {
event.setCancelled(true);
}
diff --git a/src/main/java/re/imc/geysermodelengine/listener/InteractPacketListener.java b/src/main/java/re/imc/geysermodelengine/listener/InteractPacketListener.java
deleted file mode 100644
index 596286f..0000000
--- a/src/main/java/re/imc/geysermodelengine/listener/InteractPacketListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package re.imc.geysermodelengine.listener;
-
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.events.*;
-import com.comphenix.protocol.reflect.StructureModifier;
-import com.ticxo.modelengine.api.entity.BukkitEntity;
-import com.ticxo.modelengine.api.entity.BukkitPlayer;
-import org.bukkit.entity.Entity;
-import re.imc.geysermodelengine.GeyserModelEngine;
-import re.imc.geysermodelengine.model.ModelEntity;
-
-import java.util.Set;
-
-public class InteractPacketListener extends PacketAdapter {
- public InteractPacketListener() {
- super(GeyserModelEngine.getInstance(), ListenerPriority.HIGHEST, Set.of(PacketType.Play.Client.USE_ENTITY), ListenerOptions.SYNC);
- }
-
-
- @Override
- public void onPacketReceiving(PacketEvent event) {
- PacketContainer packet = event.getPacket();
- StructureModifier modifier = packet.getEntityModifier(event);
- Entity entity = modifier.readSafely(0);
- if (entity == null) {
- return;
- }
- ModelEntity model = ModelEntity.MODEL_ENTITIES.get(entity.getEntityId());
-
- if (model != null && model.getModeledEntity().getBase() instanceof BukkitEntity bukkitEntity) {
- modifier.writeSafely(0, bukkitEntity.getOriginal());
-
- event.setPacket(packet);
- }
-
- }
-
-
-}
diff --git a/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java b/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java
index 3b0c2a9..0706c72 100644
--- a/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java
+++ b/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java
@@ -1,28 +1,36 @@
package re.imc.geysermodelengine.listener;
+import com.comphenix.protocol.wrappers.Pair;
+import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
import com.ticxo.modelengine.api.ModelEngineAPI;
-import com.ticxo.modelengine.api.events.AddModelEvent;
-import com.ticxo.modelengine.api.events.AnimationEndEvent;
-import com.ticxo.modelengine.api.events.AnimationPlayEvent;
-import com.ticxo.modelengine.api.events.RemoveModelEvent;
+import com.ticxo.modelengine.api.events.*;
+import com.ticxo.modelengine.api.generator.blueprint.ModelBlueprint;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
+import com.ticxo.modelengine.api.model.render.ModelRenderer;
+import me.zimzaza4.geyserutils.spigot.api.PlayerUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
-import org.bukkit.event.entity.EntityDamageEvent;
-import org.bukkit.event.entity.ProjectileHitEvent;
+import org.bukkit.event.entity.*;
import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.EntitiesLoadEvent;
import org.bukkit.metadata.FixedMetadataValue;
+import org.geysermc.floodgate.api.FloodgateApi;
import re.imc.geysermodelengine.GeyserModelEngine;
import re.imc.geysermodelengine.model.EntityTask;
import re.imc.geysermodelengine.model.ModelEntity;
import java.util.Map;
import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
public class ModelListener implements Listener {
@@ -32,36 +40,50 @@ public class ModelListener implements Listener {
return;
}
+ if (!GeyserModelEngine.getInstance().isInitialized()) {
+ return;
+ }
+
Bukkit.getScheduler().runTask(GeyserModelEngine.getInstance(), () -> {
ModelEntity.create(event.getTarget(), event.getModel());
});
}
+
+
@EventHandler
public void onRemoveModel(RemoveModelEvent event) {
- event.getTarget().getBase();
-
}
- @EventHandler
- public void onEntityLoad(EntitiesLoadEvent event) {
- Bukkit.getScheduler()
- .runTaskLater(GeyserModelEngine.getInstance(), () -> {
- for (Entity entity : event.getEntities()) {
- if (!ModelEntity.ENTITIES.containsKey(entity.getEntityId())) {
- ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
- if (modeledEntity != null) {
- Optional model = modeledEntity.getModels().values().stream().findFirst();
- model.ifPresent(m -> ModelEntity.create(modeledEntity, m));
- }
- }
- }
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void onModelMount(ModelMountEvent event) {
+ Map map = ModelEntity.ENTITIES.get(event.getVehicle().getModeledEntity().getBase().getEntityId());
+ if (map == null) {
+ return;
+ }
+ if (!event.isDriver()) {
+ return;
+ }
+ ModelEntity model = map.get(event.getVehicle());
- }, 20);
+ if (model != null && event.getPassenger() instanceof Player player) {
+ GeyserModelEngine.getInstance().getDrivers().put(player, new Pair<>(event.getVehicle(), event.getSeat()));
+ }
}
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void onModelDismount(ModelDismountEvent event) {
+ if (event.getPassenger() instanceof Player player) {
+ GeyserModelEngine.getInstance().getDrivers().remove(player);
+ }
+ }
+
+
@EventHandler
public void onAnimationPlay(AnimationPlayEvent event) {
+ if (event.getModel().getModeledEntity() == null) {
+ return;
+ }
Map map = ModelEntity.ENTITIES.get(event.getModel().getModeledEntity().getBase().getEntityId());
if (map == null) {
return;
@@ -91,6 +113,29 @@ public class ModelListener implements Listener {
}
}
+
+ @EventHandler(priority = EventPriority.HIGHEST)
+ public void onModelEntitySpawn(EntitySpawnEvent event) {
+ if (GeyserModelEngine.getInstance().isSpawningModelEntity() && event.getEntity() instanceof LivingEntity entity) {
+ if (event.isCancelled()) {
+ event.setCancelled(false);
+ }
+ ModelEntity model = GeyserModelEngine.getInstance().getCurrentModel();
+ int id = entity.getEntityId();
+ ActiveModel activeModel = model.getActiveModel();
+ ModelEntity.MODEL_ENTITIES.put(id, model);
+ model.applyFeatures(entity, "model." + activeModel.getBlueprint().getName());
+ GeyserModelEngine.getInstance().setCurrentModel(null);
+ GeyserModelEngine.getInstance().setSpawningModelEntity(false);
+
+ for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
+ if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) {
+ PlayerUtils.setCustomEntity(onlinePlayer, entity.getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase());
+ }
+ }
+ }
+ }
+
@EventHandler
public void onModelEntityHurt(EntityDamageEvent event) {
Map model = ModelEntity.ENTITIES.get(event.getEntity().getEntityId());
@@ -143,4 +188,9 @@ public class ModelListener implements Listener {
public void onPlayerJoin(PlayerJoinEvent event) {
GeyserModelEngine.getInstance().getJoinedPlayer().put(event.getPlayer(), true);
}
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ GeyserModelEngine.getInstance().getDrivers().remove(event.getPlayer());
+ }
}
diff --git a/src/main/java/re/imc/geysermodelengine/listener/MountPacketListener.java b/src/main/java/re/imc/geysermodelengine/listener/MountPacketListener.java
new file mode 100644
index 0000000..7d1dbb7
--- /dev/null
+++ b/src/main/java/re/imc/geysermodelengine/listener/MountPacketListener.java
@@ -0,0 +1,66 @@
+package re.imc.geysermodelengine.listener;
+
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.events.ListenerOptions;
+import com.comphenix.protocol.events.ListenerPriority;
+import com.comphenix.protocol.events.PacketAdapter;
+import com.comphenix.protocol.events.PacketEvent;
+import com.comphenix.protocol.wrappers.EnumWrappers;
+import com.comphenix.protocol.wrappers.Pair;
+import com.ticxo.modelengine.api.ModelEngineAPI;
+import com.ticxo.modelengine.api.model.ActiveModel;
+import com.ticxo.modelengine.api.model.bone.type.Mount;
+import org.geysermc.floodgate.api.FloodgateApi;
+import re.imc.geysermodelengine.GeyserModelEngine;
+
+import java.util.Set;
+
+public class MountPacketListener extends PacketAdapter {
+ public MountPacketListener() {
+ super(GeyserModelEngine.getInstance(), ListenerPriority.HIGHEST, Set.of(PacketType.Play.Client.STEER_VEHICLE, PacketType.Play.Client.ENTITY_ACTION), ListenerOptions.SYNC);
+ }
+
+ @Override
+ public void onPacketReceiving(PacketEvent event) {
+ if (!FloodgateApi.getInstance().isFloodgatePlayer(event.getPlayer().getUniqueId())) {
+ return;
+ }
+
+ if (event.getPacket().getType() == PacketType.Play.Client.STEER_VEHICLE) {
+ Pair seat = GeyserModelEngine.getInstance().getDrivers().get(event.getPlayer());
+ if (seat != null) {
+ float pitch = event.getPlayer().getPitch();
+ if (seat.getFirst().getModeledEntity().getBase().isFlying()) {
+ if (pitch < -30) {
+ event.getPacket().getBooleans().writeSafely(0, true);
+ }
+ if (pitch > 45) {
+ event.getPacket().getBooleans().writeSafely(1, true);
+ }
+ } else {
+ if (event.getPlayer().getInventory().getHeldItemSlot() == 0) {
+ event.getPacket().getBooleans().writeSafely(0, true);
+ event.getPlayer().getInventory().setHeldItemSlot(3);
+ event.getPlayer().sendActionBar("jump");
+ }
+ if (pitch > 89 || event.getPlayer().getInventory().getHeldItemSlot() == 1) {
+ event.getPacket().getBooleans().writeSafely(1, true);
+ event.getPlayer().sendActionBar("shift");
+ }
+ if (event.getPlayer().getInventory().getHeldItemSlot() == 8) {
+ event.getPacket().getBooleans().writeSafely(0, true);
+ event.getPlayer().sendActionBar("hold jump");
+ }
+ }
+ }
+ } else {
+ Pair seat = GeyserModelEngine.getInstance().getDrivers().get(event.getPlayer());
+ if (seat != null) {
+ if (event.getPacket().getPlayerActions().read(0) == EnumWrappers.PlayerAction.START_SNEAKING) {
+ event.getPlayer().sendActionBar("leave");
+ ModelEngineAPI.getMountPairManager().tryDismount(event.getPlayer());
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/re/imc/geysermodelengine/model/EntityTask.java b/src/main/java/re/imc/geysermodelengine/model/EntityTask.java
index 4c6c473..452d54c 100644
--- a/src/main/java/re/imc/geysermodelengine/model/EntityTask.java
+++ b/src/main/java/re/imc/geysermodelengine/model/EntityTask.java
@@ -17,6 +17,7 @@ import org.bukkit.util.BoundingBox;
import org.geysermc.floodgate.api.FloodgateApi;
import org.jetbrains.annotations.NotNull;
import re.imc.geysermodelengine.GeyserModelEngine;
+import re.imc.geysermodelengine.listener.ModelListener;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
@@ -38,9 +39,10 @@ public class EntityTask {
boolean firstAnimation = true;
boolean spawnAnimationPlayed = false;
+ boolean removed = false;
String lastAnimation = "";
- boolean looping = false;
+ boolean looping = true;
private BukkitRunnable syncTask;
@@ -59,14 +61,16 @@ public class EntityTask {
}
if (syncTick % 5 == 0) {
+
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (!FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) {
onlinePlayer.hideEntity(GeyserModelEngine.getInstance(), model.getEntity());
}
}
}
- if (model.getEntity().isDead()) {
- model.spawnEntity();
+
+ if (!removed && model.getEntity().isDead() && model.getModeledEntity().getBase().isAlive() && !model.getActiveModel().isRemoved()) {
+ // model.spawnEntity();
}
model.getEntity().setVisualFire(false);
@@ -74,37 +78,55 @@ public class EntityTask {
}
public void runAsync() {
Entity entity = model.getEntity();
+ if (entity.isDead()) {
+ return;
+ }
Set viewers = model.getViewers();
ActiveModel activeModel = model.getActiveModel();
ModeledEntity modeledEntity = model.getModeledEntity();
- if (modeledEntity.isDestroyed() || !modeledEntity.getBase().isAlive()) {
- if (!modeledEntity.isDestroyed() && !modeledEntity.getBase().isAlive()) {
-
- String animation = hasAnimation("death") ? "death" : "idle";
- new BukkitRunnable() {
- @Override
- public void run() {
- entity.remove();
- }
- }.runTaskLater(GeyserModelEngine.getInstance(), Math.max(playAnimation(animation, 99) - 1, 0));
-
+ if (activeModel.isRemoved() || !modeledEntity.getBase().isAlive()) {
+ if (!activeModel.isRemoved() && hasAnimation("death")) {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ removed = true;
+ entity.remove();
+ }
+ }.runTaskLater(GeyserModelEngine.getInstance(), Math.min(Math.max(playAnimation("death", 999, 5f, true) - 3, 0), 200));
+ } else {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ removed = true;
+ entity.remove();
+ }
+ }.runTask(GeyserModelEngine.getInstance());
}
- ENTITIES.remove(modeledEntity.getBase().getEntityId());
- MODEL_ENTITIES.remove(entity.getEntityId());
- cancel();
- return;
- }
- if (model.getEntity().isDead()) {
+
ENTITIES.remove(modeledEntity.getBase().getEntityId());
MODEL_ENTITIES.remove(entity.getEntityId());
cancel();
return;
}
/*
+ if (model.getEntity().isDead()) {
+ ENTITIES.remove(modeledEntity.getBase().getEntityId());
+ MODEL_ENTITIES.remove(entity.getEntityId());
+ cancel();
+ return;
+ }
+
+ */
+ /*
if (waitingTick > 0) {
waitingTick--;
}
*/
+
+ if (!spawnAnimationPlayed) {
+ spawnAnimationPlayed = true;
+ }
+
if (tick > 1 && tick % 5 == 0) {
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
@@ -133,16 +155,6 @@ public class EntityTask {
}
}
-
-
- if (!spawnAnimationPlayed) {
- spawnAnimationPlayed = true;
- if (hasAnimation("spawn")) {
- playAnimation("spawn", 99);
- } else {
- playAnimation("idle", 0);
- }
- }
if (tick % 40 == 0) {
for (Player viewer : Set.copyOf(viewers)) {
@@ -190,32 +202,36 @@ public class EntityTask {
}
public void sendEntityData(Player player, int delay) {
+ // System.out.println("TYPE: " + "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase());
+ PlayerUtils.setCustomEntity(player, model.getEntity().getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase());
+
Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> {
- PlayerUtils.sendCustomSkin(player, model.getEntity(), model.getActiveModel().getBlueprint().getName());
- playBedrockAnimation("animation." + model.getActiveModel().getBlueprint().getName() + "." + lastAnimation, looping);
+ // PlayerUtils.sendCustomSkin(player, model.getEntity(), model.getActiveModel().getBlueprint().getName());
+ if (looping) {
+ playBedrockAnimation(lastAnimation, Set.of(player), looping, 0f);
+ }
sendHitBox(player);
+ sendScale(player);
Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> {
sendHitBox(player);
}, 8);
}, delay);
}
+
+ public void sendScale(Player player) {
+ // todo?
+ }
+
public void sendHitBoxToAll() {
for (Player viewer : model.getViewers()) {
- if (model.getModeledEntity().getBase() instanceof BukkitEntity bukkitEntity) {
- @NotNull BoundingBox box = bukkitEntity.getOriginal().getBoundingBox();
- PlayerUtils.sendCustomHitBox(viewer, model.getEntity(), (float) box.getHeight(), (float) ((box.getWidthX() + box.getWidthZ()) / 2f));
- // huh i dont know how to deal with width
- }
+ PlayerUtils.sendCustomHitBox(viewer, model.getEntity(), 0.01f, 0.01f);
}
}
public void sendHitBox(Player viewer) {
- if (model.getModeledEntity().getBase() instanceof BukkitEntity bukkitEntity) {
- @NotNull BoundingBox box = bukkitEntity.getOriginal().getBoundingBox();
- PlayerUtils.sendCustomHitBox(viewer, model.getEntity(), (float) box.getHeight(), (float) ((box.getWidthX() + box.getWidthZ()) / 2f));
- // huh i dont know how to deal with width
- }
+ PlayerUtils.sendCustomHitBox(viewer, model.getEntity(), 0.01f, 0.01f);
+
}
public boolean hasAnimation(String animation) {
@@ -223,7 +239,11 @@ public class EntityTask {
BlueprintAnimation animationProperty = activeModel.getBlueprint().getAnimations().get(animation);
return !(animationProperty == null);
}
+
public int playAnimation(String animation, int p) {
+ return playAnimation(animation, p, 0, false);
+ }
+ public int playAnimation(String animation, int p, float blendTime, boolean forceLoop) {
ActiveModel activeModel = model.getActiveModel();
@@ -248,7 +268,7 @@ public class EntityTask {
firstAnimation = false;
}
boolean lastLoopState = looping;
- looping = animationProperty.getLoopMode() == BlueprintAnimation.LoopMode.LOOP;;
+ looping = forceLoop || animationProperty.getLoopMode() == BlueprintAnimation.LoopMode.LOOP;;
if (lastAnimation.equals(animation)) {
if (looping) {
@@ -258,6 +278,7 @@ public class EntityTask {
}
+
if (play) {
currentAnimationPriority.set(p);
@@ -266,14 +287,14 @@ public class EntityTask {
// delaySend = true;
}
- String id = "animation." + activeModel.getBlueprint().getName() + "." + animationProperty.getName();
+ String id = "animation." + activeModel.getBlueprint().getName().toLowerCase() + "." + animationProperty.getName().toLowerCase();
lastAnimation = id;
animationCooldown.set((int) (animationProperty.getLength() * 20));
if (delaySend) {
- Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> playBedrockAnimation("animation." + activeModel.getBlueprint().getName() + "." + animationProperty.getName(), looping), 2);
+ Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> playBedrockAnimation(id, model.getViewers(), looping, blendTime), 0);
} else {
- playBedrockAnimation(id, looping);
+ playBedrockAnimation(id, model.getViewers(), looping, blendTime);
}
}
return animationCooldown.get();
@@ -308,17 +329,15 @@ public class EntityTask {
*/
- private void playBedrockAnimation(String animationId, boolean loop) {
+ public void playBedrockAnimation(String animationId, Set viewers, boolean loop, float blendTime) {
// model.getViewers().forEach(viewer -> viewer.sendActionBar("CURRENT AN:" + animationId));
Entity entity = model.getEntity();
- Set viewers = model.getViewers();
Animation.AnimationBuilder animation = Animation.builder()
.animation(animationId)
- .blendOutTime(0f)
- .controller("controller.animation.armor_stand.wiggle");
+ .blendOutTime(blendTime);
if (loop) {
animation.nextState(animationId);
@@ -363,6 +382,17 @@ public class EntityTask {
}
public void run(GeyserModelEngine instance, int i) {
+
+ String id = "";
+ ActiveModel activeModel = model.getActiveModel();
+ if (hasAnimation("spawn")) {
+ id = "animation." + activeModel.getBlueprint().getName().toLowerCase() + ".spawn";
+ } else {
+ id = "animation." + activeModel.getBlueprint().getName().toLowerCase() + ".idle";
+ }
+
+ lastAnimation = id;
+ sendHitBoxToAll();
syncTask = new BukkitRunnable() {
@Override
public void run() {
diff --git a/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java b/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java
index 31b4b0b..1025ddb 100644
--- a/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java
+++ b/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java
@@ -1,23 +1,21 @@
package re.imc.geysermodelengine.model;
import com.google.common.collect.Sets;
+import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.entity.BukkitEntity;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
import lombok.Getter;
-import me.libraryaddict.disguise.DisguiseAPI;
-import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
-import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
-import org.geysermc.floodgate.api.FloodgateApi;
+import org.bukkit.metadata.FixedMetadataValue;
+import org.bukkit.util.Vector;
import re.imc.geysermodelengine.GeyserModelEngine;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@Getter
@@ -54,9 +52,12 @@ public class ModelEntity {
for (Player viewer : viewers) {
viewer.sendActionBar("X:" + modeledEntity.getXHeadRot() + ", Y:" + modeledEntity.getYHeadRot());
}
- */
- entity.teleportAsync(location);
+ */
+ Vector vector = modeledEntity.getBase().getMoveController().getVelocity();
+ ModelEngineAPI.getEntityHandler().setPosition(entity, location.getX(), location.getY(), location.getZ());
+ // ModelEngineAPI.getEntityHandler().movePassenger(entity, location.getX(), location.getY(), location.getZ());
+ controllerEntity.getMoveController().setVelocity(vector.getX(), vector.getY(), vector.getZ());
if (modeledEntity.getBase() instanceof BukkitEntity bukkitEntity && bukkitEntity.getOriginal() instanceof LivingEntity livingEntity) {
controllerEntity.getLookController().setHeadYaw(livingEntity.getEyeLocation().getYaw());
controllerEntity.getLookController().setPitch(livingEntity.getEyeLocation().getPitch());
@@ -68,17 +69,23 @@ public class ModelEntity {
ModelEntity modelEntity = new ModelEntity(entity, model);
int id = entity.getBase().getEntityId();
Map map = ENTITIES.computeIfAbsent(id, k -> new HashMap<>());
+ for (Map.Entry entry : map.entrySet()) {
+ if (entry.getKey() != model && entry.getKey().getBlueprint().getName().equals(model.getBlueprint().getName())) {
+ return null;
+ }
+ }
map.put(model, modelEntity);
return modelEntity;
}
public LivingEntity spawnEntity() {
- entity = (LivingEntity) modeledEntity.getBase().getLocation().getWorld().spawnEntity(modeledEntity.getBase().getLocation(), GeyserModelEngine.getInstance().getModelEntityType());
- applyFeatures(entity, "model." + activeModel.getBlueprint().getName());
ModelEntity model = this;
- int id = entity.getEntityId();
- MODEL_ENTITIES.put(id, model);
+ // int lastEntityId = ReflectionManager.getNewEntityId();
+ // System.out.println("RID:" + entityId);
+ GeyserModelEngine.getInstance().setSpawningModelEntity(true);
+ GeyserModelEngine.getInstance().setCurrentModel(model);
+ entity = (LivingEntity) modeledEntity.getBase().getLocation().getWorld().spawnEntity(modeledEntity.getBase().getLocation(), GeyserModelEngine.getInstance().getModelEntityType());
controllerEntity = new BukkitEntity(entity);
return entity;
}
@@ -89,11 +96,11 @@ public class ModelEntity {
}
- private void applyFeatures(LivingEntity display, String name) {
+ public void applyFeatures(LivingEntity display, String name) {
display.setGravity(false);
display.setMaxHealth(2048);
display.setHealth(2048);
-
+ display.setMetadata("model_entity", new FixedMetadataValue(GeyserModelEngine.getInstance(), true));
//display.setInvulnerable(true);
@@ -102,15 +109,17 @@ public class ModelEntity {
display.setPersistent(false);
// armorStand.setVisible(false);
+
+ /*
String uuid = UUID.randomUUID().toString();
- PlayerDisguise disguise = new PlayerDisguise(name + "_" + uuid);
+ MobDisguise disguise = new MobDisguise(DisguiseType.getType(entity.getType()));
+ disguise.setDisguiseName(uuid);
- DisguiseAPI.disguiseEntity(display, disguise.setNameVisible(false));
+ DisguiseAPI.disguiseEntity(display, disguise);
+ */
}
-
-
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index a1a80e5..eee40f1 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -1,4 +1,5 @@
skin-send-delay: 0
skin-view-distance: 50
join-send-delay: 20
-model-entity-type: BAT # must be a living entity
\ No newline at end of file
+model-entity-type: BAT # must be a living entity
+debug: false
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 2cbdd53..c7c9df6 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -4,5 +4,4 @@ main: re.imc.geysermodelengine.GeyserModelEngine
api-version: '1.19'
depend:
- ModelEngine
- - LibsDisguises
- floodgate
\ No newline at end of file