custom entity

This commit is contained in:
zimzaza4
2024-04-20 13:26:39 +08:00
parent e722c3b07f
commit 90f3c699cb
6 changed files with 77 additions and 50 deletions

View File

@@ -7,6 +7,7 @@ import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
@@ -42,6 +43,16 @@ public final class GeyserModelEngine extends JavaPlugin {
@Getter
private Cache<Player, Boolean> joinedPlayer;
@Getter
@Setter
private boolean spawningModelEntity = false;
@Getter
@Setter
private ModelEntity currentModel = null;
@Getter
private int joinSendDelay;

View File

@@ -4,9 +4,17 @@ 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;
@@ -14,6 +22,7 @@ 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() {
@@ -22,18 +31,17 @@ public class AddEntityPacketListener extends PacketAdapter {
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
StructureModifier<Entity> 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 (isBedrock) {
if (packet.getMeta("delayed").isPresent()) {
System.out.println("SENT");
return;
}

View File

@@ -7,16 +7,21 @@ import com.ticxo.modelengine.api.events.AnimationPlayEvent;
import com.ticxo.modelengine.api.events.RemoveModelEvent;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
import me.zimzaza4.geyserutils.spigot.api.PlayerUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
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.EntitySpawnEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerJoinEvent;
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;
@@ -30,6 +35,7 @@ public class ModelListener implements Listener {
public void onAddModel(AddModelEvent event) {
if (event.isCancelled()) {
return;
}
Bukkit.getScheduler().runTask(GeyserModelEngine.getInstance(), () -> {
@@ -37,10 +43,11 @@ public class ModelListener implements Listener {
});
}
@EventHandler
public void onRemoveModel(RemoveModelEvent event) {
event.getTarget().getBase();
// todo?
}
@EventHandler
@@ -94,6 +101,28 @@ 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());
}
}
}
}
@EventHandler
public void onModelEntityHurt(EntityDamageEvent event) {
Map<ActiveModel, ModelEntity> model = ModelEntity.ENTITIES.get(event.getEntity().getEntityId());

View File

@@ -88,7 +88,7 @@ public class EntityTask {
public void run() {
entity.remove();
}
}.runTaskLater(GeyserModelEngine.getInstance(), Math.min(Math.max(playAnimation(animation, 99) - 1, 0), 200));
}.runTaskLater(GeyserModelEngine.getInstance(), Math.min(Math.max(playAnimation(animation, 99, 50f) - 1, 0), 200));
} else {
new BukkitRunnable() {
@Override
@@ -199,34 +199,32 @@ public class EntityTask {
}
public void sendEntityData(Player player, int delay) {
System.out.println("SEND CUSTOM ENTITY");
PlayerUtils.setCustomEntity(player, model.getEntity().getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName());
Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> {
// PlayerUtils.sendCustomSkin(player, model.getEntity(), model.getActiveModel().getBlueprint().getName());
playBedrockAnimation("animation." + model.getActiveModel().getBlueprint().getName() + "." + lastAnimation, looping);
playBedrockAnimation("animation." + model.getActiveModel().getBlueprint().getName() + "." + lastAnimation, 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) {
@@ -234,7 +232,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, 5f);
}
public int playAnimation(String animation, int p, float blendTime) {
ActiveModel activeModel = model.getActiveModel();
@@ -282,9 +284,9 @@ public class EntityTask {
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("animation." + activeModel.getBlueprint().getName() + "." + animationProperty.getName(), looping, blendTime), 2);
} else {
playBedrockAnimation(id, looping);
playBedrockAnimation(id, looping, blendTime);
}
}
return animationCooldown.get();
@@ -319,7 +321,7 @@ public class EntityTask {
*/
private void playBedrockAnimation(String animationId, boolean loop) {
private void playBedrockAnimation(String animationId, boolean loop, float blendTime) {
// model.getViewers().forEach(viewer -> viewer.sendActionBar("CURRENT AN:" + animationId));
@@ -328,7 +330,7 @@ public class EntityTask {
Animation.AnimationBuilder animation = Animation.builder()
.animation(animationId)
.blendOutTime(0f)
.blendOutTime(blendTime)
.controller("controller.animation.armor_stand.wiggle");
if (loop) {

View File

@@ -5,26 +5,14 @@ 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.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import me.zimzaza4.geyserutils.spigot.api.PlayerUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.geysermc.floodgate.api.FloodgateApi;
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
@@ -82,22 +70,11 @@ public class ModelEntity {
public LivingEntity spawnEntity() {
ModelEntity model = this;
int lastEntityId = ReflectionManager.getNewEntityId();
// int lastEntityId = ReflectionManager.getNewEntityId();
// System.out.println("RID:" + entityId);
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) {
PlayerUtils.setCustomEntity(onlinePlayer, lastEntityId + 1, "modelengine:" + model.getActiveModel().getBlueprint().getName());
}
}
GeyserModelEngine.getInstance().setSpawningModelEntity(true);
GeyserModelEngine.getInstance().setCurrentModel(model);
entity = (LivingEntity) modeledEntity.getBase().getLocation().getWorld().spawnEntity(modeledEntity.getBase().getLocation(), GeyserModelEngine.getInstance().getModelEntityType());
int id = entity.getEntityId();
MODEL_ENTITIES.put(id, model);
applyFeatures(entity, "model." + activeModel.getBlueprint().getName());
controllerEntity = new BukkitEntity(entity);
return entity;
}
@@ -108,7 +85,7 @@ 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);