EntitySpawnPage class

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

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

extends: InteractiveCustomUIPage<EntitySpawnPage.EntitySpawnPageEventData>

Поля (132)

МодификаторыТипИмя
public static final BuilderCodec<EntitySpawnPage.EntitySpawnPageEventData> CODEC
final String COMMON_TEXT_BUTTON_DOCUMENT
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
break
break
break
break
break
break
break
break
break
break
break
break
break
break
break
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
NPCPlugin var1
int var10
int var10
ItemStack var10
Vector3d var10
World var11
Item var12
String var12
Set var12
Vector3i var12
ModelAsset var13
String var13
Holder var13
Vector3d var13
float var14
Holder var14
Rotation3f var14
UICommandBuilder var15
Object2IntMap var15
ItemStack var15
float var16
int var16
ItemStack var16
UICommandBuilder var17
UICommandBuilder var18
UICommandBuilder var19
int var2
String var2
var2
String var2
int var2
TransformComponent var20
String var20
UICommandBuilder var21
String var21
UIEventBuilder var22
long var23
HeadRotation var24
TransformComponent var25
UICommandBuilder var3
BlockType var3
ModelAsset var3
TransformComponent var3
EntityScaleComponent var3
BuilderInfo var3
UICommandBuilder var4
UICommandBuilder var4
UICommandBuilder var4
Rotation3f var4
ModelAsset var4
Item var4
Item var4
HeadRotation var4
ModelAsset var4
Holder var4
Holder var4
Builder var4
UIEventBuilder var5
Model var5
List var5
Set var5
Item var5
Rotation3f var5
ModelAsset var5
Vector3d var5
Holder var5
Rotation3f var5
ItemStack var5
UICommandBuilder var6
Pair var6
Rotation3f var6
Object2IntMap var6
Model var6
Model var6
Rotation3f var6
Rotation3f var6
Rotation3f var6
SpawningContext var6
Model var7
NPCEntity var7
String var7
Vector3d var7
UICommandBuilder var8
Holder var8
Vector3d var8
HeadRotation var9
int var9
String var9
Holder var9
Vector3d var9
var9
var9
var9

Методы (83)

МодификаторыВозвратСигнатура
public EntitySpawnPageEventDatapublic EntitySpawnPageEventData()
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Can't find a matching role builder")
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Abstract role templates cannot be spawned directly - a variant needs to be created!")
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Role builder must support ISpawnableWithModel interface")
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Can't find a matching role builder")
private void buildItemsContentvoid buildItemsContent(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3)
private void buildListvoid buildList(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nonnull UIEventBuilder var4)
private void buildModelListvoid buildModelList(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nonnull UIEventBuilder var4)
private void buildNPCListvoid buildNPCList(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nonnull UIEventBuilder var4)
private void clearPreviewvoid clearPreview(@Nonnull Store<EntityStore> var1)
private void clearSelectedItemvoid clearSelectedItem(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2)
private void createOrUpdateBlockPreviewvoid createOrUpdateBlockPreview(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3)
private void createOrUpdateItemPreviewvoid createOrUpdateItemPreview(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3)
private void createOrUpdatePreviewvoid createOrUpdatePreview(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull UICommandBuilder var3, @Nullable Model var4)
for for(int var5 = 0; var5 < var3; var5++)
for for(int var7 = 0; var7 < var3; var7++)
for for(String var8 : var5)
for for(String var19 : var12)
for for(int var8 = 0; var8 < var3; var8++)
for for(int var11 = 0; var11 < var3; var11++)
for for(int var12 = 0; var12 < var3; var12++)
abstract for for(int var11 = this.npcRoles.size()
abstract for for(int var18 = this.modelIds.size()
public void handleDataEventvoid handleDataEvent(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3)
private void handleSelectvoid handleSelect(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3)
private void handleSetItemMaterialvoid handleSetItemMaterial(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3)
private void handleSpawnvoid handleSpawn(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull EntitySpawnPage.EntitySpawnPageEventData var3)
if if(var3.searchQuery != null)
if if(var16 != var3.rotationOffset)
if if(var9 != null)
if if(var24 != null)
if if(var3.scale != null && var3.scale >= 0.1F)
if if(var14 != this.currentScale)
if if(var3.scale != null && var3.scale >= 0.1F)
if if(var13 != null)
if if(var12 != null)
if if(var7 != null)
if if(var3.npcRole != null)
if if(var3.itemId != null)
if if(var3.modelId != null)
if if(var3.itemStackId != null)
if if(this.selectedNpcRole != null && this.position != null && this.rotation != null)
if if(var3 >= 1 && var3 <= 100)
if if(var6 != null)
if if(this.freezeOnSpawn)
if if(var7 != null)
if if(this.selectedModelId != null && this.position != null && this.rotation != null)
if if(var3 >= 1 && var3 <= 100)
if if(var4 != null)
if if(var9 > 0)
if if(var10 > 0)
if if(this.selectedItemId != null)
if if(var4 != null)
if if(var5 != null)
if if(var6 != null)
if if(this.selectedItemId != null && this.position != null && this.rotation != null)
if if(var3 >= 1 && var3 <= 100)
if if(var4 != null)
if if(var6 != null)
if if(var2 == null)
if if(var5 != null)
if if(var8 != null)
if if(var12 != null)
if if(var4 != null)
if if(var3 != null)
if if(var4 != null)
if if(var3 == null)
if if(var4 == null)
if if(var4 instanceof ISpawnableWithModel var5)
private void initPositionvoid initPosition(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2)
private void selectItemvoid selectItem(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3, @Nonnull UICommandBuilder var4)
private void selectModelvoid selectModel(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3, @Nonnull UICommandBuilder var4)
private void selectNPCRolevoid selectNPCRole(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull String var3, @Nonnull UICommandBuilder var4)
private void spawnItemvoid spawnItem(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, int var3)
private void spawnModelvoid spawnModel(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, int var3)
private void spawnNPCvoid spawnNPC(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, int var3)
abstract super super(var1, CustomPageLifetime.CanDismiss, EntitySpawnPage.EntitySpawnPageEventData.CODEC)
switch switch(var3.type)
switch switch(this.activeTab)
switch switch(this.activeTab)
switch switch(this.activeTab)
private void updatePreviewScalevoid updatePreviewScale(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2)
private void updateTabVisibilityvoid updateTabVisibility(@Nonnull UICommandBuilder var1)

Исходный код

Показать/скрыть
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() {
      }
   }
}