package electrosphere.menu.debug; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.joml.Quaterniond; import org.joml.Vector3d; import org.ode4j.ode.DBody; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.server.ServerPlayerViewDirTree; import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.debug.DebugVisualizerUtils; import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorAnimationMask; import electrosphere.renderer.actor.ActorMeshMask; import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.Animation; import electrosphere.renderer.model.Bone; import electrosphere.renderer.model.Mesh; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; import electrosphere.server.datacell.utils.EntityLookupUtils; import electrosphere.server.poseactor.PoseActor; import electrosphere.server.poseactor.PoseModel; import imgui.ImGui; /** * Macros for creating imgui windows relating to entity debugging */ public class ImGuiEntityMacros { //window for selecting entities to view protected static ImGuiWindow clientEntityListWindow; private static boolean filterToCreatures = true; //filters the entity list to just creatures //window for viewing details about an entity protected static ImGuiWindow clientEntityDetailWindow; private static Entity detailViewEntity = null; //tree node values private static boolean showDataTab = false; //show all data names stored in the entity private static boolean showActorTab = false; //show the actor tab private static boolean showPoseActorTab = false; //show the pose actor tab private static boolean showEquipStateTab = false; //actor details private static boolean showFirstPersonTab = false; //first person tab private static boolean showLinkedEntitiesTab = false;//show linked entities private static boolean showServerViewDirTab = false; //show server view dir private static boolean showPhysicsTab = false; //show physics values /** * Creates the windows in this file */ protected static void createClientEntityWindows(){ createClientEntityDetailWindow(); createClientEntitySelectionWindow(); } /** * Client scene entity view */ protected static void createClientEntitySelectionWindow(){ clientEntityListWindow = new ImGuiWindow("Client Entities"); clientEntityListWindow.setCallback(new ImGuiWindowCallback() { @Override public void exec() { //audio engine details ImGui.text("Client Entities"); if(ImGui.checkbox("Filter to Creatures", filterToCreatures)){ filterToCreatures = !filterToCreatures; } for(Entity entity : Globals.clientSceneWrapper.getScene().getEntityList()){ //filters if(filterToCreatures && !CreatureUtils.isCreature(entity)){ continue; } ImGui.beginGroup(); ImGui.pushID(entity.getId()); ImGui.text("Id: " + entity.getId() + " (" + getEntityName(entity) + ")"); if(ImGui.button("Details")){ showEntity(entity); } ImGui.popID(); ImGui.endGroup(); } } }); clientEntityListWindow.setOpen(false); Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(clientEntityListWindow); } /** * View details about a client entity */ protected static void createClientEntityDetailWindow(){ clientEntityDetailWindow = new ImGuiWindow("Entity Data"); clientEntityDetailWindow.setCallback(new ImGuiWindowCallback() { @Override public void exec() { ImGui.text("Current ID: " + detailViewEntity.getId()); if(ImGui.treeNode("Views")){ if(ImGui.checkbox("Data View", showDataTab)){ showDataTab = !showDataTab; } if(EntityUtils.getActor(detailViewEntity) != null && ImGui.checkbox("Actor Details", showActorTab)){ showActorTab = !showActorTab; } if(EntityUtils.getPoseActor(detailViewEntity) != null && ImGui.checkbox("Pose Actor Details", showPoseActorTab)){ showPoseActorTab = !showPoseActorTab; } if(ClientEquipState.hasEquipState(detailViewEntity) && ImGui.checkbox("Equip State", showEquipStateTab)){ showEquipStateTab = !showEquipStateTab; } if(FirstPersonTree.hasTree(detailViewEntity) && ImGui.checkbox("First Person", showFirstPersonTab)){ showFirstPersonTab = !showFirstPersonTab; } if( (AttachUtils.hasChildren(detailViewEntity) || AttachUtils.getParent(detailViewEntity) != null || detailViewEntity == Globals.firstPersonEntity || detailViewEntity == Globals.playerEntity) && ImGui.checkbox("Linked entities`", showLinkedEntitiesTab) ){ showLinkedEntitiesTab = !showLinkedEntitiesTab; } if(ServerPlayerViewDirTree.hasTree(detailViewEntity) && ImGui.checkbox("Server View Dir", showServerViewDirTab)){ showServerViewDirTab = !showServerViewDirTab; } if(PhysicsEntityUtils.getDBody(detailViewEntity) != null && ImGui.checkbox("Physics", showPhysicsTab)){ showPhysicsTab = !showPhysicsTab; } ImGui.treePop(); } ImGui.nextColumn(); drawActorView(); drawPoseActor(); drawEquipState(); drawFirstPersonView(); drawLinkedEntities(); drawServerViewDir(); drawPhysicsDetails(); drawDataView(); } }); clientEntityDetailWindow.setOpen(false); Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(clientEntityDetailWindow); } /** * Shows the entity window for a specific entity * @param entity The entity */ protected static void showEntity(Entity entity){ detailViewEntity = entity; clientEntityDetailWindow.setOpen(true); } /** * Draws the data view */ protected static void drawDataView(){ if(showDataTab && ImGui.collapsingHeader("Data View")){ if(detailViewEntity != null){ for(String key : detailViewEntity.getKeys()){ ImGui.text(key); } } } } /** * Client scene entity view */ protected static void drawActorView(){ if(showActorTab && ImGui.collapsingHeader("Actor Details")){ ImGui.indent(); if(detailViewEntity != null && EntityUtils.getActor(detailViewEntity) != null){ Actor actor = EntityUtils.getActor(detailViewEntity); //mesh mask if(ImGui.collapsingHeader("Mesh Mask")){ ActorMeshMask meshMask = actor.getMeshMask(); ImGui.text("To Draw Meshes:"); for(Mesh mesh : meshMask.getToDrawMeshes()){ ImGui.text(mesh.getMeshName()); } ImGui.text("Blocked Meshes:"); for(String blocked : meshMask.getBlockedMeshes()){ ImGui.text(blocked); } } //animation queue if(ImGui.collapsingHeader("Animation Queue")){ Set animationQueue = actor.getAnimationQueue(); for(ActorAnimationMask mask : animationQueue){ ImGui.text(mask.getAnimationName() + " - " + mask.getPriority()); ImGui.text(mask.getDuration() + " " + mask.getTime()); } } //bone values if(ImGui.collapsingHeader("Bone Values")){ for(Bone bone : actor.getBoneValues()){ ImGui.text(bone.boneID); ImGui.text("Position: " + actor.getBonePosition(bone.boneID)); ImGui.text("Rotation: " + actor.getBoneRotation(bone.boneID)); ImGui.text(bone.getFinalTransform() + ""); } } //Draws all the bones in the world if(ImGui.button("Draw Bones")){ Globals.renderingEngine.getDebugContentPipeline().getDebugBonesPipeline().setEntity(detailViewEntity); } //Browsable list of all animations with their data if(ImGui.collapsingHeader("Animation Channel Data")){ Model model = Globals.assetManager.fetchModel(actor.getModelPath()); ImGui.indent(); for(Animation animation : model.getAnimations()){ if(ImGui.collapsingHeader(animation.name)){ for(AnimChannel channel : animation.channels){ ImGui.pushID(channel.getNodeID()); if(ImGui.button("Fully describe")){ channel.fullDescribeChannel(); } ImGui.text("=" + channel.getNodeID() + "="); ImGui.text("" + channel.getCurrentPosition()); ImGui.text("" + channel.getCurrentRotation()); ImGui.text("" + channel.getCurrentScale()); ImGui.popID(); } } } ImGui.unindent(); } //print data macros if(ImGui.collapsingHeader("Print Data")){ //print bone values if(ImGui.button("Print current bone values")){ for(Bone bone : actor.getBoneValues()){ LoggerInterface.loggerRenderer.DEBUG(bone.boneID); LoggerInterface.loggerRenderer.DEBUG("" + bone.getFinalTransform()); } } //print animation keys if(ImGui.button("Print animation keys")){ Model model = Globals.assetManager.fetchModel(actor.getModelPath()); model.describeAllAnimations(); } } } ImGui.unindent(); } } /** * Draws pose actor */ protected static void drawPoseActor(){ if(showPoseActorTab && ImGui.collapsingHeader("Pose Actor Details")){ ImGui.indent(); if(detailViewEntity != null && EntityUtils.getPoseActor(detailViewEntity) != null){ PoseActor poseActor = EntityUtils.getPoseActor(detailViewEntity); //animation queue if(ImGui.collapsingHeader("Animation Queue")){ Set animationQueue = poseActor.getAnimationQueue(); for(ActorAnimationMask mask : animationQueue){ ImGui.text(mask.getAnimationName() + " - " + mask.getPriority()); ImGui.text(mask.getDuration() + " " + mask.getTime()); } } //bone values if(ImGui.collapsingHeader("Bone Values")){ for(Bone bone : poseActor.getBoneValues()){ ImGui.text(bone.boneID); ImGui.text("Position: " + poseActor.getBonePosition(bone.boneID)); ImGui.text("Rotation: " + poseActor.getBoneRotation(bone.boneID)); ImGui.text(bone.getFinalTransform() + ""); } } //Draws all the bones in the world if(ImGui.button("Draw Bones")){ Globals.renderingEngine.getDebugContentPipeline().getDebugBonesPipeline().setEntity(detailViewEntity); } //Browsable list of all animations with their data if(ImGui.collapsingHeader("Animation Channel Data")){ Model model = Globals.assetManager.fetchModel(poseActor.getModelPath()); ImGui.indent(); for(Animation animation : model.getAnimations()){ if(ImGui.collapsingHeader(animation.name)){ for(AnimChannel channel : animation.channels){ ImGui.pushID(channel.getNodeID()); if(ImGui.button("Fully describe")){ channel.fullDescribeChannel(); } ImGui.text("=" + channel.getNodeID() + "="); ImGui.text("" + channel.getCurrentPosition()); ImGui.text("" + channel.getCurrentRotation()); ImGui.text("" + channel.getCurrentScale()); ImGui.popID(); } } } ImGui.unindent(); } //print data macros if(ImGui.collapsingHeader("Print Data")){ //print bone values if(ImGui.button("Print current bone values")){ for(Bone bone : poseActor.getBoneValues()){ LoggerInterface.loggerRenderer.DEBUG(bone.boneID); LoggerInterface.loggerRenderer.DEBUG("" + bone.getFinalTransform()); } } //print animation keys if(ImGui.button("Print animation keys")){ PoseModel model = Globals.assetManager.fetchPoseModel(poseActor.getModelPath()); model.describeAllAnimations(); } } } ImGui.unindent(); } } /** * First person data */ protected static void drawFirstPersonView(){ if(showFirstPersonTab && ImGui.collapsingHeader("First Person Tree")){ ImGui.indent(); // FirstPersonTree firstPersonTree = FirstPersonTree.getTree(detailViewEntity); if(ImGui.button("Visualize facing vectors")){ DebugVisualizerUtils.clientSpawnVectorVisualizer((Entity vector) -> { EntityUtils.getPosition(vector).set(EntityUtils.getPosition(Globals.firstPersonEntity)); EntityUtils.getRotation(vector).set(EntityUtils.getRotation(Globals.firstPersonEntity)); }); DebugVisualizerUtils.clientSpawnVectorVisualizer((Entity vector) -> { EntityUtils.getPosition(vector).set(EntityUtils.getPosition(Globals.playerEntity)); EntityUtils.getRotation(vector).set(EntityUtils.getRotation(Globals.playerEntity)); }); DebugVisualizerUtils.clientSpawnVectorVisualizer((Entity vector) -> { int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()); Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); EntityUtils.getPosition(vector).set(EntityUtils.getPosition(serverPlayerEntity)); EntityUtils.getRotation(vector).set(EntityUtils.getRotation(serverPlayerEntity)); }); } ImGui.unindent(); } } //stores the edited rotation values private static float[] rotationValuesFirstPerson = new float[]{ 0,0,0 }; private static float[] rotationValuesThirdPerson = new float[]{ 0,0,0 }; private static float[] vectorValuesFirstPerson = new float[]{ 0,0,0 }; private static float[] vectorValuesThirdPerson = new float[]{ 0,0,0 }; //constraints for vector offset private static final float MAXIMUM_OFFSET = 1; private static final float MINIMUM_OFFSET = -MAXIMUM_OFFSET; /** * Client scene equip state view */ protected static void drawEquipState(){ if(showEquipStateTab && ImGui.collapsingHeader("Equip State Details")){ ImGui.indent(); if(detailViewEntity != null && ClientEquipState.getClientEquipState(detailViewEntity) != null){ ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(detailViewEntity); if(ImGui.collapsingHeader("All Equip Points")){ for(EquipPoint point : clientEquipState.getAllEquipPoints()){ if(ImGui.collapsingHeader(point.getEquipPointId())){ ImGui.text("Has item equipped: " + (clientEquipState.getEquippedItemAtPoint(point.getEquipPointId()) != null)); ImGui.text("Bone (Third Person): " + point.getBone()); ImGui.text("Bone (First Person): " + point.getFirstPersonBone()); //offsets ImGui.text("[Third Person] Offset: " + AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorThirdPerson())); if(ImGui.sliderFloat3("[Third Person] Offset", vectorValuesThirdPerson, MINIMUM_OFFSET, MAXIMUM_OFFSET)){ Vector3d offset = new Vector3d(vectorValuesThirdPerson[0],vectorValuesThirdPerson[1],vectorValuesThirdPerson[2]); List newValues = new LinkedList(); newValues.add((float)offset.x); newValues.add((float)offset.y); newValues.add((float)offset.z); point.setOffsetVectorThirdPerson(newValues); Entity equippedEntity = clientEquipState.getEquippedItemAtPoint(point.getEquipPointId()); if(equippedEntity != null){ AttachUtils.setVectorOffset(equippedEntity, AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorThirdPerson())); } } ImGui.text("[First Person] Offset: " + AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorFirstPerson())); if(ImGui.sliderFloat3("[First Person] Offset", vectorValuesFirstPerson, MINIMUM_OFFSET, MAXIMUM_OFFSET)){ Vector3d offset = new Vector3d(vectorValuesFirstPerson[0],vectorValuesFirstPerson[1],vectorValuesFirstPerson[2]); List newValues = new LinkedList(); newValues.add((float)offset.x); newValues.add((float)offset.y); newValues.add((float)offset.z); point.setOffsetVectorFirstPerson(newValues); Entity equippedEntity = clientEquipState.getEquippedItemAtPoint(point.getEquipPointId()); if(equippedEntity != null){ AttachUtils.setVectorOffset(equippedEntity, AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorFirstPerson())); } } //rotations ImGui.text("[Third Person] Rotation: " + AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationThirdPerson())); if(ImGui.sliderFloat3("[Third Person] Rotation (In Euler along x,y,z)", rotationValuesThirdPerson, 0, (float)(Math.PI * 2))){ Quaterniond rotation = new Quaterniond().rotateXYZ(rotationValuesThirdPerson[0], rotationValuesThirdPerson[1], rotationValuesThirdPerson[2]); List newValues = new LinkedList(); newValues.add((float)rotation.x); newValues.add((float)rotation.y); newValues.add((float)rotation.z); newValues.add((float)rotation.w); point.setOffsetRotationThirdPerson(newValues); Entity equippedEntity = clientEquipState.getEquippedItemAtPoint(point.getEquipPointId()); if(equippedEntity != null){ AttachUtils.setRotationOffset(equippedEntity, AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationThirdPerson())); } } ImGui.text("[First Person] Rotation: " + AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationFirstPerson())); if(ImGui.sliderFloat3("[First Person] Rotation (In Euler along x,y,z)", rotationValuesFirstPerson, 0, (float)(Math.PI * 2))){ Quaterniond rotation = new Quaterniond().rotateXYZ(rotationValuesFirstPerson[0], rotationValuesFirstPerson[1], rotationValuesFirstPerson[2]); List newValues = new LinkedList(); newValues.add((float)rotation.x); newValues.add((float)rotation.y); newValues.add((float)rotation.z); newValues.add((float)rotation.w); point.setOffsetRotationFirstPerson(newValues); Entity equippedEntity = clientEquipState.getEquippedItemAtPoint(point.getEquipPointId()); if(equippedEntity != null){ AttachUtils.setRotationOffset(equippedEntity, AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationFirstPerson())); } } if(ImGui.button("Print transforms")){ LoggerInterface.loggerEngine.WARNING("Third person Offset: " + AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorThirdPerson())); LoggerInterface.loggerEngine.WARNING("First person Offset: " + AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorFirstPerson())); LoggerInterface.loggerEngine.WARNING("Third person Rotation: " + AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationThirdPerson())); LoggerInterface.loggerEngine.WARNING("First person Rotation: " + AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationFirstPerson())); } } } } } ImGui.unindent(); } } /** * Client scene equip state view */ protected static void drawLinkedEntities(){ if(showLinkedEntitiesTab && ImGui.collapsingHeader("Linked entities")){ ImGui.indent(); if(detailViewEntity == Globals.playerEntity && ImGui.button("View Model")){ showEntity(Globals.firstPersonEntity); } if(detailViewEntity == Globals.firstPersonEntity && ImGui.button("3rd Person Model")){ showEntity(Globals.playerEntity); } if(AttachUtils.getParent(detailViewEntity) != null && ImGui.button("Parent")){ showEntity(AttachUtils.getParent(detailViewEntity)); } if(AttachUtils.hasChildren(detailViewEntity) && ImGui.collapsingHeader("Children")){ for(Entity child : AttachUtils.getChildrenList(detailViewEntity)){ if(ImGui.button("Child " + child.getId())){ showEntity(child); } } } if(ClientEquipState.hasEquipState(detailViewEntity) && ImGui.collapsingHeader("Equipped")){ ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(detailViewEntity); for(String equippedPoint : clientEquipState.getEquippedPoints()){ Entity entity = clientEquipState.getEquippedItemAtPoint(equippedPoint); if(ImGui.button("Slot: " + equippedPoint)){ showEntity(entity); } } } if(Globals.clientSceneWrapper.clientToServerMapContainsId(detailViewEntity.getId())){ //detailViewEntity is a client entity //get server entity int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(detailViewEntity.getId()); Entity serverEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); if(serverEntity != null && ImGui.button("Server Entity")){ showEntity(serverEntity); } } else if(Globals.clientSceneWrapper.containsServerId(detailViewEntity.getId())){ //detailViewEntity is a server entity //get client entity int clientId = Globals.clientSceneWrapper.mapServerToClientId(detailViewEntity.getId()); Entity clientEntity = Globals.clientSceneWrapper.getScene().getEntityFromId(clientId); if(clientEntity != null && ImGui.button("Client Entity")){ showEntity(clientEntity); } } ImGui.unindent(); } } /** * Server view dir */ protected static void drawServerViewDir(){ if(showServerViewDirTab && ImGui.collapsingHeader("Server View Dir")){ ImGui.indent(); if(ServerPlayerViewDirTree.hasTree(detailViewEntity)){ ServerPlayerViewDirTree viewDirTree = ServerPlayerViewDirTree.getTree(detailViewEntity); ImGui.text("Yaw: " + viewDirTree.getYaw()); ImGui.text("Pitch: " + viewDirTree.getPitch()); } ImGui.unindent(); } } /** * Physics details */ protected static void drawPhysicsDetails(){ if(showPhysicsTab && ImGui.collapsingHeader("Physics")){ ImGui.indent(); if(PhysicsEntityUtils.getDBody(detailViewEntity) != null){ DBody physicsBody = PhysicsEntityUtils.getDBody(detailViewEntity); if(physicsBody != null){ ImGui.text("Position: " + EntityUtils.getPosition(detailViewEntity)); ImGui.text("Rotation: " + EntityUtils.getRotation(detailViewEntity)); ImGui.text("Velocity: " + physicsBody.getLinearVel()); ImGui.text("Force: " + physicsBody.getForce()); ImGui.text("Angular Velocity: " + physicsBody.getAngularVel()); ImGui.text("Torque: " + physicsBody.getTorque()); ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(detailViewEntity)); ImGui.text("Velocity: " + CreatureUtils.getVelocity(detailViewEntity)); } //synchronized data if(Globals.clientSceneWrapper.getScene().getEntityFromId(detailViewEntity.getId()) != null){ //detailViewEntity is a client entity //get server entity int serverIdForClientEntity = Globals .clientSceneWrapper.mapClientToServerId(detailViewEntity.getId()); Entity serverEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); DBody serverPhysicsBody = PhysicsEntityUtils.getDBody(serverEntity); if(serverPhysicsBody != null){ ImGui.newLine(); ImGui.text("Linked server entity:"); ImGui.text("Position (Server): " + EntityUtils.getPosition(serverEntity)); ImGui.text("Rotation (Server): " + EntityUtils.getRotation(serverEntity)); ImGui.text("Velocity (Server): " + serverPhysicsBody.getLinearVel()); ImGui.text("Force (Server): " + serverPhysicsBody.getForce()); ImGui.text("Angular Velocity: " + serverPhysicsBody.getAngularVel()); ImGui.text("Torque: " + serverPhysicsBody.getTorque()); ImGui.text("Move Vector (Server): "+ CreatureUtils.getFacingVector(serverEntity)); ImGui.text("Velocity (Server): " + CreatureUtils.getVelocity(serverEntity)); } } else if(Globals.clientSceneWrapper.containsServerId(detailViewEntity.getId())){ //detailViewEntity is a server entity //get client entity int clientId = Globals.clientSceneWrapper.mapServerToClientId(detailViewEntity.getId()); Entity clientEntity = Globals.clientSceneWrapper.getScene().getEntityFromId(clientId); DBody clientPhysicsBody = PhysicsEntityUtils.getDBody(clientEntity); if(clientPhysicsBody != null){ ImGui.newLine(); ImGui.text("Linked client entity:"); ImGui.text("Position (Client): " + EntityUtils.getPosition(clientEntity)); ImGui.text("Rotation (Client): " + EntityUtils.getRotation(clientEntity)); ImGui.text("Velocity (Client): " + clientPhysicsBody.getLinearVel()); ImGui.text("Force (Client): " + clientPhysicsBody.getForce()); ImGui.text("Angular Velocity: " + clientPhysicsBody.getAngularVel()); ImGui.text("Torque: " + clientPhysicsBody.getTorque()); ImGui.text("Move Vector (Client): " + CreatureUtils.getFacingVector(clientEntity)); ImGui.text("Velocity (Client): " + CreatureUtils.getVelocity(clientEntity)); } } } ImGui.unindent(); } } /** * Gets the displayed name of an entity (ie creature type, foliage type, terrain, etc) * @param entity * @return */ private static String getEntityName(Entity entity){ if(CreatureUtils.isCreature(entity)){ return CreatureUtils.getType(entity); } if(ItemUtils.isItem(entity)){ return ItemUtils.getType(entity); } if(FoliageUtils.isFoliage(entity)){ return FoliageUtils.getFoliageType(entity).getName(); } return "Entity"; } }