EntitySpawnPageEventData class

Пакет: com.hypixel.hytale.server.npc.pages

Файл: com/hypixel/hytale/server/npc/pages/EntitySpawnPage.java

Поля (23)

МодификаторыТипИмя
public static final BuilderCodec<EntitySpawnPage.EntitySpawnPageEventData> CODEC
static final String KEY_COUNT
static final String KEY_FREEZE_ON_SPAWN
static final String KEY_ITEM_ID
static final String KEY_ITEM_STACK_ID
static final String KEY_MODEL_ID
static final String KEY_NPC_ROLE
static final String KEY_ROTATION_OFFSET
static final String KEY_SCALE
static final String KEY_SEARCH_QUERY
static final String KEY_TAB
static final String KEY_TYPE
private int count
private boolean freezeOnSpawn
private String itemId
private String itemStackId
private String modelId
private String npcRole
private float rotationOffset
private Float scale
private String searchQuery
private String tab
private String type

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.npc.pages;

class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.common.util.StringCompareUtil;
class="kw">import com.hypixel.hytale.component.AddReason;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.NonSerialized;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.RemoveReason;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.math.vector.Rotation3f;
class="kw">import com.hypixel.hytale.math.vector.Transform;
class="kw">import com.hypixel.hytale.protocol.AnimationSlot;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.Page;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.item.config.Item;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.Model;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
class="kw">import com.hypixel.hytale.server.core.command.system.exceptions.GeneralCommandException;
class="kw">import com.hypixel.hytale.server.core.entity.Frozen;
class="kw">import com.hypixel.hytale.server.core.entity.UUIDComponent;
class="kw">import com.hypixel.hytale.server.core.entity.entities.BlockEntity;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;
class="kw">import com.hypixel.hytale.server.core.inventory.ItemStack;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.EntityScaleComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.PropComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.item.PreventItemMerging;
class="kw">import com.hypixel.hytale.server.core.modules.entity.item.PreventPickup;
class="kw">import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
class="kw">import com.hypixel.hytale.server.core.ui.ItemGridSlot;
class="kw">import com.hypixel.hytale.server.core.ui.Value;
class="kw">import com.hypixel.hytale.server.core.ui.builder.EventData;
class="kw">import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
class="kw">import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.npc.INonPlayerCharacter;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.util.TargetUtil;
class="kw">import com.hypixel.hytale.server.npc.NPCPlugin;
class="kw">import com.hypixel.hytale.server.npc.asset.builder.Builder;
class="kw">import com.hypixel.hytale.server.npc.asset.builder.BuilderInfo;
class="kw">import com.hypixel.hytale.server.npc.entities.NPCEntity;
class="kw">import com.hypixel.hytale.server.npc.role.Role;
class="kw">import com.hypixel.hytale.server.spawning.ISpawnableWithModel;
class="kw">import com.hypixel.hytale.server.spawning.SpawningContext;
class="kw">import it.unimi.dsi.fastutil.Pair;
class="kw">import it.unimi.dsi.fastutil.objects.Object2IntMap;
class="kw">import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
class="kw">import java.util.Comparator;
class="kw">import java.util.HashSet;
class="kw">import java.util.List;
class="kw">import java.util.Locale;
class="kw">import java.util.Set;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.stream.Collectors;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3i;

class="kw">public class EntitySpawnPage class="kw">extends InteractiveCustomUIPage<EntitySpawnPage.EntitySpawnPageEventData> {
   class="kw">private class="kw">static class="kw">final String COMMON_TEXT_BUTTON_DOCUMENT = "Common/TextButton.ui";
   class="kw">private class="kw">static class="kw">final String COMMON_UI_DOCUMENT = "Common.ui";
   class="kw">private class="kw">static class="kw">final Value<String> BUTTON_LABEL_STYLE = Value.ref("Common/TextButton.ui", "LabelStyle");
   class="kw">private class="kw">static class="kw">final Value<String> BUTTON_LABEL_STYLE_SELECTED = Value.ref("Common/TextButton.ui", "SelectedLabelStyle");
   class="kw">private class="kw">static class="kw">final Value<String> TAB_STYLE_ACTIVE = Value.ref("Common.ui", "DefaultTextButtonStyle");
   class="kw">private class="kw">static class="kw">final Value<String> TAB_STYLE_INACTIVE = Value.ref("Common.ui", "SecondaryTextButtonStyle");
   class="kw">private class="kw">static class="kw">final String TAB_NPC = "NPC";
   class="kw">private class="kw">static class="kw">final String TAB_ITEMS = "Items";
   class="kw">private class="kw">static class="kw">final String TAB_MODEL = "Model";
   class="kw">private class="kw">static class="kw">final String KEY_SELECT_AN_ITEM = "server.customUI.entitySpawnPage.selectAnItem";
   class="kw">private class="kw">static class="kw">final String KEY_SELECT_AN_NPC = "server.customUI.entitySpawnPage.selectAnNpc";
   class="kw">private class="kw">static class="kw">final String KEY_SELECT_A_MODEL = "server.customUI.entitySpawnPage.selectAModel";
   class="kw">private class="kw">static class="kw">final int MAX_SPAWN_COUNT = 100;
   class="kw">private class="kw">static class="kw">final int LOOK_RAYCAST_DISTANCE = 4;
   class="kw">private class="kw">static class="kw">final int FALLBACK_RAYCAST_DOWN_DISTANCE = 3;
   class="kw">private class="kw">static class="kw">final double FALLBACK_RAYCAST_Y_OFFSET = 0.5;
   @Nonnull
   class="kw">private String activeTab = "NPC";
   @Nonnull
   class="kw">private String searchQuery = "";
   class="kw">private List<String> npcRoles;
   @Nullable
   class="kw">private String selectedNpcRole;
   class="kw">private List<String> modelIds;
   @Nullable
   class="kw">private String selectedModelId;
   @Nullable
   class="kw">private String selectedItemId;
   @Nullable
   class="kw">private Ref<EntityStore> modelPreview;
   class="kw">private Vector3d position;
   class="kw">private Rotation3f rotation;
   class="kw">private float currentRotationOffset = 0.0F;
   class="kw">private float currentScale = 1.0F;
   class="kw">private float lastPreviewScale = 1.0F;
   class="kw">private long lastScaleUpdateTime = 0L;
   class="kw">private boolean freezeOnSpawn = false;

   class="kw">public EntitySpawnPage(@Nonnull PlayerRef var1) {
      super(var1, CustomPageLifetime.CanDismiss, EntitySpawnPage.EntitySpawnPageEventData.CODEC);
   }

   @Override
   class="kw">public void build(@Nonnull Ref<EntityStore> var1, @Nonnull UICommandBuilder var2, @Nonnull UIEventBuilder var3, @Nonnull Store<EntityStore> var4) {
      var2.append("Pages/EntitySpawnPage.ui");
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#SearchInput", EventData.of("@SearchQuery", "#SearchInput.Value"), false);
      var3.addEventBinding(
         CustomUIEventBindingType.ValueChanged,
         "#RotationOffset",
         new EventData().append("Type", "UpdateRotationOffset").append("@RotationOffset", "#RotationOffset.Value"),
         false
      );
      var3.addEventBinding(
         CustomUIEventBindingType.MouseButtonReleased,
         "#RotationOffset",
         new EventData().append("Type", "RotationReleased").append("@RotationOffset", "#RotationOffset.Value"),
         false
      );
      var3.addEventBinding(
         CustomUIEventBindingType.ValueChanged, "#ScaleSlider", new EventData().append("Type", "UpdateScale").append("@Scale", "#ScaleSlider.Value"), false
      );
      var3.addEventBinding(
         CustomUIEventBindingType.MouseButtonReleased,
         "#ScaleSlider",
         new EventData().append("Type", "ScaleReleased").append("@Scale", "#ScaleSlider.Value"),
         false
      );
      var3.addEventBinding(
         CustomUIEventBindingType.ValueChanged,
         "#FreezeOnSpawn #CheckBox",
         new EventData().append("Type", "FreezeOnSpawn").append("@FreezeOnSpawn", "#FreezeOnSpawn #CheckBox.Value"),
         false
      );
      var3.addEventBinding(
         CustomUIEventBindingType.Activating,
         "#Spawn",
         new EventData().append("Type", "Spawn").append("@Count", "#Count.Value").append("@Scale", "#ScaleSlider.Value"),
         false
      );
      var3.addEventBinding(CustomUIEventBindingType.Activating, "#TabNPC", new EventData().append("Type", "TabSwitch").append("Tab", "NPC"), false);
      var3.addEventBinding(CustomUIEventBindingType.Activating, "#TabItems", new EventData().append("Type", "TabSwitch").append("Tab", "Items"), false);
      var3.addEventBinding(CustomUIEventBindingType.Activating, "#TabModel", new EventData().append("Type", "TabSwitch").append("Tab", "Model"), false);
      var3.addEventBinding(CustomUIEventBindingType.Dropped, "#ItemMaterialSlot", new EventData().append("Type", "SetItemMaterial"), false);
      var3.addEventBinding(CustomUIEventBindingType.Activating, "#ClearMaterial", new EventData().append("Type", "ClearMaterial"), false);
      this.buildList(var1, var4, var2, var3);
   }

   class="kw">public void handleDataEvent(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3) {
      if (var3.searchQuery != null) {
         this.searchQuery = var3.searchQuery.trim().toLowerCase(Locale.ROOT);
         UICommandBuilder var4 = new UICommandBuilder();
         UIEventBuilder var5 = new UIEventBuilder();
         this.buildList(var1, var2, var4, var5);
         this.sendUpdate(var4, var5, false);
      } else if (var3.type != null) {
         class="kw">switch (var3.type) {
            case "TabSwitch":
               if (var3.tab != null && !var3.tab.equals(this.activeTab)) {
                  this.activeTab = var3.tab;
                  this.searchQuery = "";
                  this.clearPreview(var2);
                  UICommandBuilder var17 = new UICommandBuilder();
                  UIEventBuilder var22 = new UIEventBuilder();
                  this.updateTabVisibility(var17);
                  var17.set("#SearchInput.Value", "");
                  this.buildList(var1, var2, var17, var22);
                  this.sendUpdate(var17, var22, false);
               }
               break;
            case "Select":
               this.handleSelect(var1, var2, var3);
               break;
            case "SetItemMaterial":
               this.handleSetItemMaterial(var1, var2, var3);
               break;
            case "ClearMaterial":
               this.clearSelectedItem(var1, var2);
               break;
            case "UpdateRotationOffset":
               float var16 = var3.rotationOffset;
               var3.rotationOffset = Math.clamp(Math.round(var3.rotationOffset), -180, 180);
               this.currentRotationOffset = (float)Math.toRadians(var3.rotationOffset);
               UICommandBuilder var21 = new UICommandBuilder();
               if (var16 != var3.rotationOffset) {
                  var21.set("#RotationOffset.Value", (int)var3.rotationOffset);
               }

               var21.set("#RotationValue.Text", String.format("%d\u00b0", (int)var3.rotationOffset));
               this.sendUpdate(var21, null, false);
               if (this.modelPreview != null && this.modelPreview.isValid()) {
                  TransformComponent var25 = var2.getComponent(this.modelPreview, TransformComponent.getComponentType());
                  var25.getRotation().setYaw(this.rotation.yaw() + this.currentRotationOffset);
                  HeadRotation var9 = var2.getComponent(this.modelPreview, HeadRotation.getComponentType());
                  if (var9 != null) {
                     var9.getRotation().setYaw(this.rotation.yaw() + this.currentRotationOffset);
                  }
               }
               break;
            case "RotationReleased":
               var3.rotationOffset = Math.clamp(Math.round(var3.rotationOffset), -180, 180);
               this.currentRotationOffset = (float)Math.toRadians(var3.rotationOffset);
               UICommandBuilder var15 = new UICommandBuilder();
               var15.set("#RotationValue.Text", String.format("%d\u00b0", (int)var3.rotationOffset));
               this.sendUpdate(var15, null, false);
               if (this.modelPreview != null && this.modelPreview.isValid()) {
                  TransformComponent var20 = var2.getComponent(this.modelPreview, TransformComponent.getComponentType());
                  var20.getRotation().setYaw(this.rotation.yaw() + this.currentRotationOffset);
                  HeadRotation var24 = var2.getComponent(this.modelPreview, HeadRotation.getComponentType());
                  if (var24 != null) {
                     var24.getRotation().setYaw(this.rotation.yaw() + this.currentRotationOffset);
                  }
               }
               break;
            case "UpdateScale":
               if (var3.scale != null && var3.scale >= 0.1F) {
                  float var14 = var3.scale;
                  this.currentScale = Math.clamp(Math.round(var3.scale * 10.0F) / 10.0F, 0.1F, 5.0F);
                  UICommandBuilder var19 = new UICommandBuilder();
                  if (var14 != this.currentScale) {
                     var19.set("#ScaleSlider.Value", this.currentScale);
                  }

                  var19.set("#ScaleValue.Text", String.format("%.1f", this.currentScale));
                  this.sendUpdate(var19, null, false);
                  long var23 = System.currentTimeMillis();
                  if (this.modelPreview != null
                     && this.modelPreview.isValid()
                     && this.currentScale != this.lastPreviewScale
                     && var23 - this.lastScaleUpdateTime >= 200L) {
                     this.lastScaleUpdateTime = var23;
                     this.lastPreviewScale = this.currentScale;
                     this.updatePreviewScale(var1, var2);
                  }
               }
               break;
            case "ScaleReleased":
               if (var3.scale != null && var3.scale >= 0.1F) {
                  this.currentScale = Math.clamp(Math.round(var3.scale * 10.0F) / 10.0F, 0.1F, 5.0F);
                  UICommandBuilder var6 = new UICommandBuilder();
                  var6.set("#ScaleValue.Text", String.format("%.1f", this.currentScale));
                  this.sendUpdate(var6, null, false);
                  if ("Model".equals(this.activeTab) && this.selectedModelId != null) {
                     ModelAsset var13 = ModelAsset.getAssetMap().getAsset(this.selectedModelId);
                     if (var13 != null) {
                        UICommandBuilder var18 = new UICommandBuilder();
                        this.createOrUpdatePreview(var1, var2, var18, Model.createStaticScaledModel(var13, this.currentScale));
                     }
                  } else if ("Items".equals(this.activeTab) && this.selectedItemId != null) {
                     Item var12 = Item.getAssetMap().getAsset(this.selectedItemId);
                     if (var12 != null) {
                        Model var7 = this.getItemModel(var12);
                        if (var7 != null) {
                           UICommandBuilder var8 = new UICommandBuilder();
                           this.createOrUpdatePreview(var1, var2, var8, var7);
                        } else if (var12.hasBlockType()) {
                           this.createOrUpdateBlockPreview(var1, var2, this.selectedItemId);
                        } else {
                           this.createOrUpdateItemPreview(var1, var2, this.selectedItemId);
                        }
                     }
                  } else if ("NPC".equals(this.activeTab) && this.selectedNpcRole != null) {
                     this.updatePreviewScale(var1, var2);
                  }
               }
               break;
            case "FreezeOnSpawn":
               this.freezeOnSpawn = var3.freezeOnSpawn;
               break;
            case "Spawn":
               this.handleSpawn(var1, var2, var3);
         }
      }
   }

   class="kw">private void handleSelect(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3) {
      UICommandBuilder var4 = new UICommandBuilder();
      class="kw">switch (this.activeTab) {
         case "NPC":
            if (var3.npcRole != null) {
               this.selectNPCRole(var1, var2, var3.npcRole, var4);
            }
            break;
         case "Items":
            if (var3.itemId != null) {
               this.selectItem(var1, var2, var3.itemId, var4);
            }
            break;
         case "Model":
            if (var3.modelId != null) {
               this.selectModel(var1, var2, var3.modelId, var4);
            }
      }

      this.sendUpdate(var4, null, false);
   }

   class="kw">private void handleSetItemMaterial(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3) {
      if (var3.itemStackId != null) {
         UICommandBuilder var4 = new UICommandBuilder();
         this.selectItem(var1, var2, var3.itemStackId, var4);
         this.sendUpdate(var4, null, false);
      }
   }

   class="kw">private void clearSelectedItem(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2) {
      this.selectedItemId = null;
      this.clearPreview(var2);
      UICommandBuilder var3 = new UICommandBuilder();
      var3.set("#SelectedName.Text", Message.translation("server.customUI.entitySpawnPage.selectAnItem"));
      var3.set("#ItemMaterialSlot.Slots", new ItemGridSlot[]{new ItemGridSlot()});
      var3.set("#ClearMaterial.Visible", false);
      var3.set("#DropIndicator.Visible", true);
      this.sendUpdate(var3, null, false);
   }

   class="kw">private void handleSpawn(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3) {
      class="kw">switch (this.activeTab) {
         case "NPC":
            this.spawnNPC(var1, var2, var3.count);
            break;
         case "Items":
            this.spawnItem(var1, var2, var3.count);
            break;
         case "Model":
            this.spawnModel(var1, var2, var3.count);
      }

      this.currentScale = 1.0F;
      this.lastPreviewScale = 1.0F;
      this.currentRotationOffset = 0.0F;
   }

   class="kw">private void spawnNPC(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, int var3) {
      if (this.selectedNpcRole != null && this.position != null && this.rotation != null) {
         if (var3 >= 1 && var3 <= 100) {
            this.clearPreview(var2);
            Rotation3f var4 = new Rotation3f(this.rotation);
            var4.setYaw(this.rotation.yaw() + this.currentRotationOffset);

            for (int var5 = 0; var5 < var3; var5++) {
               Pair var6 = NPCPlugin.get().spawnNPC(var2, this.selectedNpcRole, null, this.position, var4);
               if (var6 != null) {
                  var2.putComponent((Ref<EntityStore>)var6.first(), EntityScaleComponent.getComponentType(), new EntityScaleComponent(this.currentScale));
                  if (this.freezeOnSpawn) {
                     var2.ensureComponent((Ref<EntityStore>)var6.first(), Frozen.getComponentType());
                     NPCEntity var7 = var2.getComponent((Ref<EntityStore>)var6.first(), NPCEntity.getComponentType());
                     if (var7 != null) {
                        var7.playAnimation((Ref<EntityStore>)var6.first(), AnimationSlot.Movement, "Idle", var2);
                     }
                  }
               }
            }

            var2.getComponent(var1, Player.getComponentType()).getPageManager().setPage(var1, var2, Page.None);
            this.playerRef
               .sendMessage(
                  Message.translation(var3 == 1 ? "server.npc.spawn.spawnedOne" : "server.npc.spawn.spawnedMany")
                     .param("quantity", var3)
                     .param("type", this.selectedNpcRole)
               );
         }
      }
   }

   class="kw">private void spawnModel(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, int var3) {
      if (this.selectedModelId != null && this.position != null && this.rotation != null) {
         if (var3 >= 1 && var3 <= 100) {
            this.clearPreview(var2);
            ModelAsset var4 = ModelAsset.getAssetMap().getAsset(this.selectedModelId);
            if (var4 != null) {
               Model var5 = Model.createStaticScaledModel(var4, this.currentScale);
               Rotation3f var6 = new Rotation3f(this.rotation);
               var6.setYaw(this.rotation.yaw() + this.currentRotationOffset);

               for (int var7 = 0; var7 < var3; var7++) {
                  Holder var8 = var2.getRegistry().newHolder();
                  var8.addComponent(NetworkId.getComponentType(), new NetworkId(var2.getExternalData().takeNextNetworkId()));
                  var8.addComponent(TransformComponent.getComponentType(), new TransformComponent(this.position, var6));
                  var8.addComponent(ModelComponent.getComponentType(), new ModelComponent(var5));
                  var8.addComponent(
                     PersistentModel.getComponentType(), new PersistentModel(new Model.ModelReference(this.selectedModelId, this.currentScale, null, true))
                  );
                  var8.addComponent(HeadRotation.getComponentType(), new HeadRotation(var6));
                  var8.addComponent(PropComponent.getComponentType(), PropComponent.get());
                  var8.ensureComponent(UUIDComponent.getComponentType());
                  var2.addEntity(var8, AddReason.SPAWN);
               }

               var2.getComponent(var1, Player.getComponentType()).getPageManager().setPage(var1, var2, Page.None);
               this.playerRef
                  .sendMessage(Message.translation("server.customUI.entitySpawnPage.spawnedModel").param("quantity", var3).param("model", this.selectedModelId));
            }
         }
      }
   }

   @Override
   class="kw">public void onDismiss(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2) {
      this.clearPreview(var2);
   }

   class="kw">private void clearPreview(@Nonnull Store<EntityStore> var1) {
      if (this.modelPreview != null && this.modelPreview.isValid()) {
         var1.removeEntity(this.modelPreview, RemoveReason.REMOVE);
      }

      this.modelPreview = null;
   }

   class="kw">private void updateTabVisibility(@Nonnull UICommandBuilder var1) {
      var1.set("#NPCContent.Visible", this.activeTab.equals("NPC"));
      var1.set("#ItemsContent.Visible", this.activeTab.equals("Items"));
      var1.set("#ModelContent.Visible", this.activeTab.equals("Model"));
      var1.set("#TabNPC.Style", this.activeTab.equals("NPC") ? TAB_STYLE_ACTIVE : TAB_STYLE_INACTIVE);
      var1.set("#TabItems.Style", this.activeTab.equals("Items") ? TAB_STYLE_ACTIVE : TAB_STYLE_INACTIVE);
      var1.set("#TabModel.Style", this.activeTab.equals("Model") ? TAB_STYLE_ACTIVE : TAB_STYLE_INACTIVE);
      var1.set("#RotationGroup.Visible", this.activeTab.equals("Model") || this.activeTab.equals("NPC") || this.activeTab.equals("Items"));
      var1.set("#ScaleGroup.Visible", this.activeTab.equals("Model") || this.activeTab.equals("Items") || this.activeTab.equals("NPC"));
      var1.set("#FreezeOnSpawnGroup.Visible", this.activeTab.equals("NPC"));
      if (this.activeTab.equals("Model") || this.activeTab.equals("Items") || this.activeTab.equals("NPC")) {
         int var2 = (int)Math.toDegrees(this.currentRotationOffset);
         var1.set("#RotationOffset.Value", var2);
         var1.set("#RotationValue.Text", String.format("%d\u00b0", var2));
         var1.set("#ScaleSlider.Value", this.currentScale);
         var1.set("#ScaleValue.Text", String.format("%.1f", this.currentScale));
      }
   }

   class="kw">private void buildList(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nonnull UIEventBuilder var4) {
      this.updateTabVisibility(var3);
      class="kw">switch (this.activeTab) {
         case "NPC":
            this.buildNPCList(var1, var2, var3, var4);
            break;
         case "Items":
            this.buildItemsContent(var1, var2, var3);
            break;
         case "Model":
            this.buildModelList(var1, var2, var3, var4);
      }
   }

   class="kw">private void buildNPCList(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nonnull UIEventBuilder var4) {
      var3.clear("#NPCList");
      List var5 = NPCPlugin.get().getRoleTemplateNames(true);
      if (!this.searchQuery.isEmpty()) {
         Object2IntMap var6 = new Object2IntOpenHashMap(var5.size());

         for (String var8 : var5) {
            int var9 = StringCompareUtil.getFuzzyDistance(var8, this.searchQuery, Locale.ENGLISH);
            if (var9 > 0) {
               var6.put(var8, var9);
            }
         }

         this.npcRoles = var6.keySet().stream().sorted().sorted(Comparator.comparingInt(var6::getInt).reversed()).limit(20L).collect(Collectors.toList());
      } else {
         var5.sort(String::compareTo);
         this.npcRoles = var5;
      }

      int var10 = 0;

      for (int var11 = this.npcRoles.size(); var10 < var11; var10++) {
         String var12 = this.npcRoles.get(var10);
         String var13 = "#NPCList[" + var10 + "]";
         var3.append("#NPCList", "Common/TextButton.ui");
         var3.set(var13 + " #Button.Text", var12);
         var4.addEventBinding(CustomUIEventBindingType.Activating, var13 + " #Button", new EventData().append("Type", "Select").append("NPCRole", var12), false);
      }

      if (!this.npcRoles.isEmpty() && this.selectedNpcRole != null) {
         if (this.npcRoles.contains(this.selectedNpcRole)) {
            this.selectNPCRole(var1, var2, this.selectedNpcRole, var3);
         } else {
            this.selectedNpcRole = null;
            this.clearPreview(var2);
            var3.set("#SelectedName.Text", Message.translation("server.customUI.entitySpawnPage.selectAnNpc"));
         }
      } else if (this.selectedNpcRole == null) {
         var3.set("#SelectedName.Text", Message.translation("server.customUI.entitySpawnPage.selectAnNpc"));
      }
   }

   class="kw">private void buildModelList(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nonnull UIEventBuilder var4) {
      var3.clear("#ModelList");
      Set var5 = new HashSet<>();

      for (Item var7 : Item.getAssetMap().getAssetMap().values()) {
         if (var7.getModel() != null) {
            var5.add(var7.getModel());
         }
      }

      for (BlockType var13 : BlockType.getAssetMap().getAssetMap().values()) {
         if (var13.getCustomModel() != null) {
            var5.add(var13.getCustomModel());
         }
      }

      Set var12 = new HashSet<>();

      for (Entry var8 : ModelAsset.getAssetMap().getAssetMap().entrySet()) {
         String var9 = var8.getValue().getModel();
         if (var9 != null && !var5.contains(var9) && !var9.startsWith("Items/Projectiles/")) {
            var12.add(var8.getKey());
         }
      }

      if (!this.searchQuery.isEmpty()) {
         Object2IntMap var15 = new Object2IntOpenHashMap(var12.size());

         for (String var19 : var12) {
            int var10 = StringCompareUtil.getFuzzyDistance(var19, this.searchQuery, Locale.ENGLISH);
            if (var10 > 0) {
               var15.put(var19, var10);
            }
         }

         this.modelIds = var15.keySet().stream().sorted().sorted(Comparator.comparingInt(var15::getInt).reversed()).limit(20L).collect(Collectors.toList());
      } else {
         this.modelIds = var12.stream().sorted().collect(Collectors.toList());
      }

      int var16 = 0;

      for (int var18 = this.modelIds.size(); var16 < var18; var16++) {
         String var20 = this.modelIds.get(var16);
         String var21 = "#ModelList[" + var16 + "]";
         var3.append("#ModelList", "Common/TextButton.ui");
         var3.set(var21 + " #Button.Text", var20);
         var4.addEventBinding(CustomUIEventBindingType.Activating, var21 + " #Button", new EventData().append("Type", "Select").append("ModelId", var20), false);
      }

      if (!this.modelIds.isEmpty() && this.selectedModelId != null) {
         if (this.modelIds.contains(this.selectedModelId)) {
            this.selectModel(var1, var2, this.selectedModelId, var3);
         } else {
            this.selectedModelId = null;
            this.clearPreview(var2);
            var3.set("#SelectedName.Text", Message.translation("server.customUI.entitySpawnPage.selectAModel"));
         }
      } else if (this.selectedModelId == null) {
         var3.set("#SelectedName.Text", Message.translation("server.customUI.entitySpawnPage.selectAModel"));
      }
   }

   class="kw">private void buildItemsContent(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3) {
      if (this.selectedItemId != null) {
         Item var4 = Item.getAssetMap().getAsset(this.selectedItemId);
         if (var4 != null) {
            var3.set("#SelectedName.Text", this.selectedItemId);
            var3.set("#ItemMaterialSlot.Slots", new ItemGridSlot[]{new ItemGridSlot(new ItemStack(this.selectedItemId, 1))});
            var3.set("#ClearMaterial.Visible", true);
            var3.set("#DropIndicator.Visible", false);
         }
      } else {
         var3.set("#SelectedName.Text", Message.translation("server.customUI.entitySpawnPage.selectAnItem"));
         var3.set("#ItemMaterialSlot.Slots", new ItemGridSlot[]{new ItemGridSlot()});
         var3.set("#ClearMaterial.Visible", false);
         var3.set("#DropIndicator.Visible", true);
      }
   }

   class="kw">private void selectItem(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3, @Nonnull UICommandBuilder var4) {
      Item var5 = Item.getAssetMap().getAsset(var3);
      if (var5 != null) {
         this.selectedItemId = var3;
         var4.set("#SelectedName.Text", var3);
         var4.set("#ItemMaterialSlot.Slots", new ItemGridSlot[]{new ItemGridSlot(new ItemStack(var3, 1))});
         var4.set("#ClearMaterial.Visible", true);
         var4.set("#DropIndicator.Visible", false);
         Model var6 = this.getItemModel(var5);
         if (var6 != null) {
            this.createOrUpdatePreview(var1, var2, var4, var6);
         } else if (var5.hasBlockType()) {
            this.createOrUpdateBlockPreview(var1, var2, var3);
         } else {
            this.createOrUpdateItemPreview(var1, var2, var3);
         }
      }
   }

   class="kw">private void spawnItem(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, int var3) {
      if (this.selectedItemId != null && this.position != null && this.rotation != null) {
         if (var3 >= 1 && var3 <= 100) {
            Item var4 = Item.getAssetMap().getAsset(this.selectedItemId);
            if (var4 != null) {
               this.clearPreview(var2);
               Rotation3f var5 = new Rotation3f(this.rotation);
               var5.setYaw(this.rotation.yaw() + this.currentRotationOffset);
               Model var6 = this.getItemModel(var4);
               if (var6 != null) {
                  String var7 = this.getItemModelId(var4);

                  for (int var8 = 0; var8 < var3; var8++) {
                     Holder var9 = var2.getRegistry().newHolder();
                     var9.addComponent(NetworkId.getComponentType(), new NetworkId(var2.getExternalData().takeNextNetworkId()));
                     var9.addComponent(TransformComponent.getComponentType(), new TransformComponent(this.position, var5));
                     var9.addComponent(ModelComponent.getComponentType(), new ModelComponent(var6));
                     var9.addComponent(PersistentModel.getComponentType(), new PersistentModel(new Model.ModelReference(var7, this.currentScale, null, true)));
                     ItemStack var10 = new ItemStack(this.selectedItemId, 1);
                     var10.setOverrideDroppedItemAnimation(true);
                     var9.addComponent(ItemComponent.getComponentType(), new ItemComponent(var10));
                     var9.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
                     var9.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
                     var9.addComponent(HeadRotation.getComponentType(), new HeadRotation(var5));
                     var9.addComponent(PropComponent.getComponentType(), PropComponent.get());
                     var9.ensureComponent(UUIDComponent.getComponentType());
                     var2.addEntity(var9, AddReason.SPAWN);
                  }
               } else if (var4.hasBlockType()) {
                  for (int var11 = 0; var11 < var3; var11++) {
                     Holder var13 = var2.getRegistry().newHolder();
                     var13.addComponent(BlockEntity.getComponentType(), new BlockEntity(this.selectedItemId));
                     var13.addComponent(TransformComponent.getComponentType(), new TransformComponent(this.position, var5));
                     var13.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(this.currentScale));
                     ItemStack var15 = new ItemStack(this.selectedItemId, 1);
                     var15.setOverrideDroppedItemAnimation(true);
                     var13.addComponent(ItemComponent.getComponentType(), new ItemComponent(var15));
                     var13.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
                     var13.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
                     var13.addComponent(PropComponent.getComponentType(), PropComponent.get());
                     var13.ensureComponent(UUIDComponent.getComponentType());
                     var2.addEntity(var13, AddReason.SPAWN);
                  }
               } else {
                  for (int var12 = 0; var12 < var3; var12++) {
                     Holder var14 = var2.getRegistry().newHolder();
                     var14.addComponent(NetworkId.getComponentType(), new NetworkId(var2.getExternalData().takeNextNetworkId()));
                     var14.addComponent(TransformComponent.getComponentType(), new TransformComponent(this.position, var5));
                     ItemStack var16 = new ItemStack(this.selectedItemId, 1);
                     var16.setOverrideDroppedItemAnimation(true);
                     var14.addComponent(ItemComponent.getComponentType(), new ItemComponent(var16));
                     var14.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(this.currentScale));
                     var14.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
                     var14.addComponent(PreventItemMerging.getComponentType(), PreventItemMerging.INSTANCE);
                     var14.addComponent(HeadRotation.getComponentType(), new HeadRotation(var5));
                     var14.addComponent(PropComponent.getComponentType(), PropComponent.get());
                     var2.addEntity(var14, AddReason.SPAWN);
                  }
               }

               var2.getComponent(var1, Player.getComponentType()).getPageManager().setPage(var1, var2, Page.None);
               this.playerRef
                  .sendMessage(Message.translation("server.customUI.entitySpawnPage.spawnedItem").param("quantity", var3).param("item", this.selectedItemId));
            }
         }
      }
   }

   @Nullable
   class="kw">private String getItemModelId(@Nonnull Item var1) {
      String var2 = var1.getModel();
      if (var2 == null && var1.hasBlockType()) {
         BlockType var3 = BlockType.getAssetMap().getAsset(var1.getId());
         if (var3 != null && var3.getCustomModel() != null) {
            var2 = var3.getCustomModel();
         }
      }

      class="kw">return var2;
   }

   @Nullable
   class="kw">private Model getItemModel(@Nonnull Item var1) {
      String var2 = this.getItemModelId(var1);
      if (var2 == null) {
         class="kw">return null;
      }

      ModelAsset var3 = ModelAsset.getAssetMap().getAsset(var2);
      class="kw">return var3 != null ? Model.createStaticScaledModel(var3, this.currentScale) : null;
   }

   class="kw">private void selectNPCRole(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3, @Nonnull UICommandBuilder var4) {
      if (this.selectedNpcRole != null && this.npcRoles.contains(this.selectedNpcRole)) {
         var4.set("#NPCList[" + this.npcRoles.indexOf(this.selectedNpcRole) + "] #Button.Style", BUTTON_LABEL_STYLE);
      }

      var4.set("#NPCList[" + this.npcRoles.indexOf(var3) + "] #Button.Style", BUTTON_LABEL_STYLE_SELECTED);
      var4.set("#SelectedName.Text", var3);
      this.selectedNpcRole = var3;
      this.createOrUpdatePreview(var1, var2, var4, this.getNPCModel());
   }

   class="kw">private void selectModel(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3, @Nonnull UICommandBuilder var4) {
      if (this.selectedModelId != null && this.modelIds.contains(this.selectedModelId)) {
         var4.set("#ModelList[" + this.modelIds.indexOf(this.selectedModelId) + "] #Button.Style", BUTTON_LABEL_STYLE);
      }

      var4.set("#ModelList[" + this.modelIds.indexOf(var3) + "] #Button.Style", BUTTON_LABEL_STYLE_SELECTED);
      var4.set("#SelectedName.Text", var3);
      this.selectedModelId = var3;
      ModelAsset var5 = ModelAsset.getAssetMap().getAsset(var3);
      if (var5 != null) {
         this.createOrUpdatePreview(var1, var2, var4, Model.createStaticScaledModel(var5, this.currentScale));
      }
   }

   class="kw">private void initPosition(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2) {
      TransformComponent var3 = var2.getComponent(var1, TransformComponent.getComponentType());
      assert var3 != null;
      HeadRotation var4 = var2.getComponent(var1, HeadRotation.getComponentType());
      assert var4 != null;
      Vector3d var5 = var3.getPosition();
      Rotation3f var6 = var4.getRotation();
      Vector3d var7 = Transform.getDirection(var6.pitch(), var6.yaw());
      Vector3d var8 = TargetUtil.getTargetLocation(var1, 4.0, var2);
      Vector3d var9;
      if (var8 != null) {
         var9 = var8;
      } else {
         Vector3d var10 = new Vector3d(var5).add(new Vector3d(var7).mul(4.0));
         World var11 = var2.getExternalData().getWorld();
         Vector3i var12 = TargetUtil.getTargetBlock(var11, (var0, var1x) -> var0 != 0, var10.x, var10.y + 0.5, var10.z, 0.0, -1.0, 0.0, 3.0);
         if (var12 != null) {
            var9 = new Vector3d(var12.x + 0.5, var12.y + 1, var12.z + 0.5);
         } else {
            var9 = var10;
         }
      }

      Vector3d var13 = new Vector3d(var5).sub(var9);
      var13.y = 0.0;
      Rotation3f var14 = Rotation3f.lookAt(var13);
      this.position = var9;
      this.rotation = var14;
   }

   class="kw">private void createOrUpdatePreview(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nullable Model var4) {
      if (var4 != null) {
         if (this.modelPreview != null && this.modelPreview.isValid()) {
            var2.putComponent(this.modelPreview, ModelComponent.getComponentType(), new ModelComponent(var4));
         } else {
            this.initPosition(var1, var2);
            Holder var5 = var2.getRegistry().newHolder();
            var5.addComponent(NetworkId.getComponentType(), new NetworkId(var2.getExternalData().takeNextNetworkId()));
            var5.addComponent(EntityStore.REGISTRY.getNonSerializedComponentType(), NonSerialized.get());
            Rotation3f var6 = new Rotation3f(this.rotation);
            var6.setYaw(this.rotation.yaw() + this.currentRotationOffset);
            var5.addComponent(TransformComponent.getComponentType(), new TransformComponent(this.position, var6));
            var5.addComponent(ModelComponent.getComponentType(), new ModelComponent(var4));
            var5.addComponent(HeadRotation.getComponentType(), new HeadRotation(var6));
            this.modelPreview = var2.addEntity(var5, AddReason.SPAWN);
            this.lastPreviewScale = this.currentScale;
         }
      }
   }

   class="kw">private void updatePreviewScale(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2) {
      if (this.modelPreview != null && this.modelPreview.isValid()) {
         EntityScaleComponent var3 = var2.getComponent(this.modelPreview, EntityScaleComponent.getComponentType());
         if (var3 != null) {
            var3.setScale(this.currentScale);
         } else if ("Model".equals(this.activeTab) && this.selectedModelId != null) {
            ModelAsset var4 = ModelAsset.getAssetMap().getAsset(this.selectedModelId);
            if (var4 != null) {
               var2.putComponent(
                  this.modelPreview, ModelComponent.getComponentType(), new ModelComponent(Model.createStaticScaledModel(var4, this.currentScale))
               );
            }
         } else if ("NPC".equals(this.activeTab)) {
            var2.putComponent(this.modelPreview, EntityScaleComponent.getComponentType(), new EntityScaleComponent(this.currentScale));
         }
      }
   }

   class="kw">private void createOrUpdateBlockPreview(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3) {
      this.clearPreview(var2);
      this.initPosition(var1, var2);
      Holder var4 = var2.getRegistry().newHolder();
      var4.addComponent(NetworkId.getComponentType(), new NetworkId(var2.getExternalData().takeNextNetworkId()));
      var4.addComponent(EntityStore.REGISTRY.getNonSerializedComponentType(), NonSerialized.get());
      Rotation3f var5 = new Rotation3f(this.rotation);
      var5.setYaw(this.rotation.yaw() + this.currentRotationOffset);
      var4.addComponent(BlockEntity.getComponentType(), new BlockEntity(var3));
      var4.addComponent(TransformComponent.getComponentType(), new TransformComponent(this.position, var5));
      var4.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(this.currentScale));
      this.modelPreview = var2.addEntity(var4, AddReason.SPAWN);
      this.lastPreviewScale = this.currentScale;
   }

   class="kw">private void createOrUpdateItemPreview(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3) {
      this.clearPreview(var2);
      this.initPosition(var1, var2);
      Holder var4 = var2.getRegistry().newHolder();
      var4.addComponent(NetworkId.getComponentType(), new NetworkId(var2.getExternalData().takeNextNetworkId()));
      var4.addComponent(EntityStore.REGISTRY.getNonSerializedComponentType(), NonSerialized.get());
      ItemStack var5 = new ItemStack(var3, 1);
      var5.setOverrideDroppedItemAnimation(true);
      var4.addComponent(ItemComponent.getComponentType(), new ItemComponent(var5));
      var4.addComponent(EntityScaleComponent.getComponentType(), new EntityScaleComponent(this.currentScale));
      Rotation3f var6 = new Rotation3f(this.rotation);
      var6.setYaw(this.rotation.yaw() + this.currentRotationOffset);
      var4.addComponent(PreventPickup.getComponentType(), PreventPickup.INSTANCE);
      var4.addComponent(TransformComponent.getComponentType(), new TransformComponent(this.position, var6));
      var4.addComponent(HeadRotation.getComponentType(), new HeadRotation(var6));
      this.modelPreview = var2.addEntity(var4, AddReason.SPAWN);
      this.lastPreviewScale = this.currentScale;
   }

   @Nullable
   class="kw">private Model getNPCModel() {
      NPCPlugin var1 = NPCPlugin.get();
      int var2 = var1.getIndex(this.selectedNpcRole);
      var1.forceValidation(var2);
      BuilderInfo var3 = var1.getRoleBuilderInfo(var2);
      if (var3 == null) {
         throw new IllegalStateException("Can't find a matching role builder");
      }

      if (!var1.testAndValidateRole(var3)) {
         throw new GeneralCommandException(Message.translation("server.commands.npc.spawn.validation_failed"));
      }

      Builder var4 = var1.tryGetCachedValidRole(var2);
      if (var4 == null) {
         throw new IllegalArgumentException("Can't find a matching role builder");
      }

      if (var4 class="kw">instanceof ISpawnableWithModel var5) {
         if (!var4.isSpawnable()) {
            throw new IllegalArgumentException("Abstract role templates cannot be spawned directly - a variant needs to be created!");
         } else {
            SpawningContext var6 = new SpawningContext();
            if (!var6.setSpawnable(var5)) {
               throw new GeneralCommandException(Message.translation("server.commands.npc.spawn.cantSetRolebuilder"));
            } else {
               class="kw">return var6.getModel();
            }
         }
      } else {
         throw new IllegalArgumentException("Role builder must support ISpawnableWithModel class="kw">interface");
      }
   }

   class="kw">public class="kw">static class EntitySpawnPageEventData {
      class="kw">static class="kw">final String KEY_NPC_ROLE = "NPCRole";
      class="kw">static class="kw">final String KEY_MODEL_ID = "ModelId";
      class="kw">static class="kw">final String KEY_ITEM_ID = "ItemId";
      class="kw">static class="kw">final String KEY_ITEM_STACK_ID = "ItemStackId";
      class="kw">static class="kw">final String KEY_TYPE = "Type";
      class="kw">static class="kw">final String KEY_TAB = "Tab";
      class="kw">static class="kw">final String KEY_SEARCH_QUERY = "@SearchQuery";
      class="kw">static class="kw">final String KEY_COUNT = "@Count";
      class="kw">static class="kw">final String KEY_ROTATION_OFFSET = "@RotationOffset";
      class="kw">static class="kw">final String KEY_SCALE = "@Scale";
      class="kw">static class="kw">final String KEY_FREEZE_ON_SPAWN = "@FreezeOnSpawn";
      class="kw">public class="kw">static class="kw">final BuilderCodec<EntitySpawnPage.EntitySpawnPageEventData> CODEC = BuilderCodec.builder(
            EntitySpawnPage.EntitySpawnPageEventData.class, EntitySpawnPage.EntitySpawnPageEventData::new
         )
         .append(new KeyedCodec<>("NPCRole", Codec.STRING), (var0, var1) -> var0.npcRole = var1, var0 -> var0.npcRole)
         .add()
         .append(new KeyedCodec<>("ModelId", Codec.STRING), (var0, var1) -> var0.modelId = var1, var0 -> var0.modelId)
         .add()
         .append(new KeyedCodec<>("ItemId", Codec.STRING), (var0, var1) -> var0.itemId = var1, var0 -> var0.itemId)
         .add()
         .append(new KeyedCodec<>("ItemStackId", Codec.STRING), (var0, var1) -> var0.itemStackId = var1, var0 -> var0.itemStackId)
         .add()
         .append(new KeyedCodec<>("Type", Codec.STRING), (var0, var1) -> var0.type = var1, var0 -> var0.type)
         .add()
         .append(new KeyedCodec<>("Tab", Codec.STRING), (var0, var1) -> var0.tab = var1, var0 -> var0.tab)
         .add()
         .append(new KeyedCodec<>("@SearchQuery", Codec.STRING), (var0, var1) -> var0.searchQuery = var1, var0 -> var0.searchQuery)
         .add()
         .append(new KeyedCodec<>("@Count", Codec.INTEGER), (var0, var1) -> var0.count = var1, var0 -> var0.count)
         .add()
         .append(new KeyedCodec<>("@RotationOffset", Codec.FLOAT), (var0, var1) -> var0.rotationOffset = var1, var0 -> var0.rotationOffset)
         .add()
         .append(new KeyedCodec<>("@Scale", Codec.FLOAT), (var0, var1) -> var0.scale = var1, var0 -> var0.scale)
         .add()
         .append(new KeyedCodec<>("@FreezeOnSpawn", Codec.BOOLEAN), (var0, var1) -> var0.freezeOnSpawn = var1, var0 -> var0.freezeOnSpawn)
         .add()
         .build();
      class="kw">private String npcRole;
      class="kw">private String modelId;
      class="kw">private String itemId;
      class="kw">private String itemStackId;
      class="kw">private String type;
      class="kw">private String tab;
      class="kw">private String searchQuery;
      class="kw">private int count;
      class="kw">private float rotationOffset;
      class="kw">private Float scale;
      class="kw">private boolean freezeOnSpawn;

      class="kw">public EntitySpawnPageEventData() {
      }
   }
}