AnimationSet class

Пакет: com.hypixel.hytale.server.core.asset.type.model.config

Файл: com/hypixel/hytale/server/core/asset/type/model/config/ModelAsset.java

Поля (5)

МодификаторыТипИмя
public static final BuilderCodec<ModelAsset.AnimationSet> CODEC
public static final Rangef DEFAULT_NEXT_ANIMATION_DELAY
protected ModelAsset.Animation[] animations
protected Rangef nextAnimationDelay
com.hypixel.hytale.protocol.AnimationSet var2

Методы (4)

МодификаторыВозвратСигнатура
public ModelAsset.Animation[] getAnimationspublic ModelAsset.Animation[] getAnimations()
public Rangef getNextAnimationDelaypublic Rangef getNextAnimationDelay()
public com.hypixel.hytale.protocol.AnimationSet toPacketpublic com.hypixel.hytale.protocol.AnimationSet toPacket(String var1)
public String toStringpublic String toString()

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.asset.type.model.config;

class="kw">import com.hypixel.hytale.assetstore.AssetExtraInfo;
class="kw">import com.hypixel.hytale.assetstore.AssetKeyValidator;
class="kw">import com.hypixel.hytale.assetstore.AssetRegistry;
class="kw">import com.hypixel.hytale.assetstore.AssetStore;
class="kw">import com.hypixel.hytale.assetstore.codec.AssetBuilderCodec;
class="kw">import com.hypixel.hytale.assetstore.codec.ContainedAssetCodec;
class="kw">import com.hypixel.hytale.assetstore.map.DefaultAssetMap;
class="kw">import com.hypixel.hytale.assetstore.map.JsonAssetWithMap;
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.codec.codecs.EnumCodec;
class="kw">import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.codecs.array.IntArrayCodec;
class="kw">import com.hypixel.hytale.codec.codecs.map.MapCodec;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIButton;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UICreateButtons;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIDefaultCollapsedState;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIDisplayMode;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIEditor;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIEditorPreview;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIEditorSectionStart;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UIRebuildCaches;
class="kw">import com.hypixel.hytale.codec.schema.metadata.ui.UISidebarButtons;
class="kw">import com.hypixel.hytale.codec.validation.ValidatorCache;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.codec.validation.validator.IntArrayValidator;
class="kw">import com.hypixel.hytale.common.map.IWeightedMap;
class="kw">import com.hypixel.hytale.common.map.WeightedMap;
class="kw">import com.hypixel.hytale.common.util.ArrayUtil;
class="kw">import com.hypixel.hytale.common.util.MapUtil;
class="kw">import com.hypixel.hytale.math.shape.Box;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector3fUtil;
class="kw">import com.hypixel.hytale.protocol.ColorLight;
class="kw">import com.hypixel.hytale.protocol.EntityPart;
class="kw">import com.hypixel.hytale.protocol.ModelTrail;
class="kw">import com.hypixel.hytale.protocol.Phobia;
class="kw">import com.hypixel.hytale.protocol.Rangef;
class="kw">import com.hypixel.hytale.server.core.asset.common.CommonAssetValidator;
class="kw">import com.hypixel.hytale.server.core.asset.type.item.config.AssetIconProperties;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.camera.CameraAxis;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.camera.CameraSettings;
class="kw">import com.hypixel.hytale.server.core.asset.type.soundevent.config.SoundEvent;
class="kw">import com.hypixel.hytale.server.core.asset.type.soundevent.validator.SoundEventValidators;
class="kw">import com.hypixel.hytale.server.core.asset.type.trail.config.Trail;
class="kw">import com.hypixel.hytale.server.core.codec.ProtocolCodecs;
class="kw">import com.hypixel.hytale.server.core.modules.physics.component.PhysicsValues;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.util.Arrays;
class="kw">import java.util.Collections;
class="kw">import java.util.HashMap;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3f;

class="kw">public class ModelAsset class="kw">implements JsonAssetWithMap<String, DefaultAssetMap<String, ModelAsset>> {
   class="kw">public class="kw">static class="kw">final BuilderCodec<ModelTrail> MODEL_TRAIL_CODEC = BuilderCodec.builder(ModelTrail.class, ModelTrail::new)
      .append(new KeyedCodec<>("TrailId", new ContainedAssetCodec<>(Trail.class, Trail.CODEC)), (var0, var1) -> var0.trailId = var1, var0 -> var0.trailId)
      .addValidator(Trail.VALIDATOR_CACHE.getValidator())
      .add()
      .addField(
         new KeyedCodec<>("TargetEntityPart", new EnumCodec<>(EntityPart.class)), (var0, var1) -> var0.targetEntityPart = var1, var0 -> var0.targetEntityPart
      )
      .addField(new KeyedCodec<>("TargetNodeName", Codec.STRING), (var0, var1) -> var0.targetNodeName = var1, var0 -> var0.targetNodeName)
      .addField(
         new KeyedCodec<>("PositionOffset", Vector3fUtil.CODEC),
         (var0, var1) -> var0.positionOffset = var1,
         var0 -> var0.positionOffset != null ? new Vector3f(var0.positionOffset.x(), var0.positionOffset.y(), var0.positionOffset.z()) : null
      )
      .addField(new KeyedCodec<>("RotationOffset", ProtocolCodecs.DIRECTION), (var0, var1) -> var0.rotationOffset = var1, var0 -> var0.rotationOffset)
      .addField(new KeyedCodec<>("FixedRotation", Codec.BOOLEAN), (var0, var1) -> var0.fixedRotation = var1, var0 -> var0.fixedRotation)
      .build();
   class="kw">public class="kw">static class="kw">final ArrayCodec<ModelTrail> MODEL_TRAIL_ARRAY_CODEC = new ArrayCodec<>(MODEL_TRAIL_CODEC, ModelTrail[]::new);
   class="kw">public class="kw">static class="kw">final AssetBuilderCodec<String, ModelAsset> CODEC = AssetBuilderCodec.<String, ModelAsset>builder(
         ModelAsset.class,
         ModelAsset::new,
         Codec.STRING,
         (var0, var1) -> var0.id = var1,
         var0 -> var0.id,
         (var0, var1) -> var0.extraData = var1,
         var0 -> var0.extraData
      )
      .metadata(new UIEditorPreview(UIEditorPreview.PreviewType.MODEL))
      .metadata(
         new UISidebarButtons(
            new UIButton("server.assetEditor.buttons.resetModel", "ResetModel"), new UIButton("server.assetEditor.buttons.useModel", "UseModel")
         )
      )
      .metadata(new UICreateButtons(new UIButton("server.assetEditor.buttons.createAndUseModel", "UseModel")))
      .<String>appendInherited(
         new KeyedCodec<>("Model", Codec.STRING), (var0, var1) -> var0.model = var1, var0 -> var0.model, (var0, var1) -> var0.model = var1.model
      )
      .addValidator(CommonAssetValidator.MODEL_CHARACTER)
      .add()
      .<String>appendInherited(
         new KeyedCodec<>("Texture", Codec.STRING), (var0, var1) -> var0.texture = var1, var0 -> var0.texture, (var0, var1) -> var0.texture = var1.texture
      )
      .addValidator(CommonAssetValidator.TEXTURE_CHARACTER)
      .add()
      .<String>appendInherited(
         new KeyedCodec<>("GradientSet", Codec.STRING),
         (var0, var1) -> var0.gradientSet = var1,
         var0 -> var0.gradientSet,
         (var0, var1) -> var0.gradientSet = var1.gradientSet
      )
      .metadata(new UIEditor(new UIEditor.Dropdown("GradientSets")))
      .add()
      .<String>appendInherited(
         new KeyedCodec<>("GradientId", Codec.STRING),
         (var0, var1) -> var0.gradientId = var1,
         var0 -> var0.gradientId,
         (var0, var1) -> var0.gradientId = var1.gradientId
      )
      .metadata(new UIEditor(new UIEditor.Dropdown("GradientIds")))
      .add()
      .<String>appendInherited(
         new KeyedCodec<>("Icon", Codec.STRING), (var0, var1) -> var0.icon = var1, var0 -> var0.icon, (var0, var1) -> var0.icon = var1.icon
      )
      .addValidator(CommonAssetValidator.ICON_MODEL)
      .metadata(new UIEditor(new UIEditor.Icon("Icons/ModelsGenerated/{assetId}.png", 128, 128)))
      .metadata(new UIRebuildCaches(UIRebuildCaches.ClientCache.ITEM_ICONS))
      .add()
      .<AssetIconProperties>appendInherited(
         new KeyedCodec<>("IconProperties", AssetIconProperties.CODEC),
         (var0, var1) -> var0.iconProperties = var1,
         var0 -> var0.iconProperties,
         (var0, var1) -> var0.iconProperties = var1.iconProperties
      )
      .metadata(UIDisplayMode.HIDDEN)
      .add()
      .appendInherited(
         new KeyedCodec<>("Light", ProtocolCodecs.COLOR_LIGHT), (var0, var1) -> var0.light = var1, var0 -> var0.light, (var0, var1) -> var0.light = var1.light
      )
      .add()
      .appendInherited(
         new KeyedCodec<>("PhysicsValues", PhysicsValues.CODEC),
         (var0, var1) -> var0.physicsValues = var1,
         var0 -> var0.physicsValues,
         (var0, var1) -> var0.physicsValues = var1.physicsValues
      )
      .add()
      .<Double>appendInherited(
         new KeyedCodec<>("MinScale", Codec.DOUBLE),
         (var0, var1) -> var0.minScale = var1.floatValue(),
         var0 -> (double)var0.minScale,
         (var0, var1) -> var0.minScale = var1.minScale
      )
      .metadata(new UIEditorSectionStart("Hitbox"))
      .add()
      .appendInherited(
         new KeyedCodec<>("MaxScale", Codec.DOUBLE),
         (var0, var1) -> var0.maxScale = var1.floatValue(),
         var0 -> (double)var0.maxScale,
         (var0, var1) -> var0.maxScale = var1.maxScale
      )
      .add()
      .appendInherited(
         new KeyedCodec<>("EyeHeight", Codec.DOUBLE),
         (var0, var1) -> var0.eyeHeight = var1.floatValue(),
         var0 -> (double)var0.eyeHeight,
         (var0, var1) -> var0.eyeHeight = var1.eyeHeight
      )
      .add()
      .<Box>appendInherited(
         new KeyedCodec<>("HitBox", Box.CODEC),
         (var0, var1) -> var0.boundingBox = var1,
         var0 -> var0.boundingBox,
         (var0, var1) -> var0.boundingBox = var1.boundingBox
      )
      .addValidator(Validators.nonNull())
      .add()
      .appendInherited(
         new KeyedCodec<>("DetailBoxes", new MapCodec<>(new ArrayCodec<>(DetailBox.CODEC, DetailBox[]::new), HashMap::new)),
         (var0, var1) -> var0.detailBoxes = var1,
         var0 -> var0.detailBoxes,
         (var0, var1) -> var0.detailBoxes = var1.detailBoxes
      )
      .add()
      .appendInherited(
         new KeyedCodec<>("CrouchOffset", Codec.DOUBLE),
         (var0, var1) -> var0.crouchOffset = var1.floatValue(),
         var0 -> (double)var0.crouchOffset,
         (var0, var1) -> var0.crouchOffset = var1.crouchOffset
      )
      .add()
      .appendInherited(
         new KeyedCodec<>("SittingOffset", Codec.DOUBLE),
         (var0, var1) -> var0.sittingOffset = var1.floatValue(),
         var0 -> (double)var0.sittingOffset,
         (var0, var1) -> var0.sittingOffset = var1.sittingOffset
      )
      .add()
      .<Double>appendInherited(
         new KeyedCodec<>("SleepingOffset", Codec.DOUBLE),
         (var0, var1) -> var0.sleepingOffset = var1.floatValue(),
         var0 -> (double)var0.sleepingOffset,
         (var0, var1) -> var0.sleepingOffset = var1.sleepingOffset
      )
      .metadata(new UIEditorSectionStart("Camera"))
      .add()
      .appendInherited(
         new KeyedCodec<>("Camera", CameraSettings.CODEC), (var0, var1) -> var0.camera = var1, var0 -> var0.camera, (var0, var1) -> var0.camera = var1.camera
      )
      .add()
      .<ModelAttachment[]>appendInherited(
         new KeyedCodec<>("DefaultAttachments", new ArrayCodec<>(ModelAttachment.CODEC, ModelAttachment[]::new)),
         (var0, var1) -> var0.defaultAttachments = var1,
         var0 -> var0.defaultAttachments,
         (var0, var1) -> var0.defaultAttachments = var1.defaultAttachments
      )
      .metadata(new UIEditorSectionStart("Attachments"))
      .metadata(UIDefaultCollapsedState.UNCOLLAPSED)
      .add()
      .<Map>appendInherited(
         new KeyedCodec<>("RandomAttachmentSets", new MapCodec<>(new MapCodec<>(ModelAttachment.CODEC, HashMap::new), HashMap::new)),
         (var0, var1) -> var0.randomAttachmentSets = var1,
         var0 -> var0.randomAttachmentSets,
         (var0, var1) -> var0.randomAttachmentSets = var1.randomAttachmentSets
      )
      .metadata(UIDefaultCollapsedState.UNCOLLAPSED)
      .add()
      .<Map>appendInherited(
         new KeyedCodec<>("AnimationSets", new MapCodec<>(ModelAsset.AnimationSet.CODEC, HashMap::new)),
         (var0, var1) -> var0.animationSetMap = MapUtil.combineUnmodifiable(var0.animationSetMap, var1),
         var0 -> var0.animationSetMap,
         (var0, var1) -> var0.animationSetMap = var1.animationSetMap
      )
      .metadata(new UIEditorSectionStart("Animations"))
      .metadata(UIDefaultCollapsedState.UNCOLLAPSED)
      .add()
      .<ModelParticle[]>appendInherited(
         new KeyedCodec<>("Particles", ModelParticle.ARRAY_CODEC),
         (var0, var1) -> var0.particles = var1,
         var0 -> var0.particles,
         (var0, var1) -> var0.particles = var1.particles
      )
      .metadata(new UIEditorSectionStart("Particles"))
      .metadata(UIDefaultCollapsedState.UNCOLLAPSED)
      .add()
      .<ModelTrail[]>appendInherited(
         new KeyedCodec<>("Trails", MODEL_TRAIL_ARRAY_CODEC),
         (var0, var1) -> var0.trails = var1,
         var0 -> var0.trails,
         (var0, var1) -> var0.trails = var1.trails
      )
      .metadata(new UIEditorSectionStart("Trails"))
      .metadata(UIDefaultCollapsedState.UNCOLLAPSED)
      .add()
      .<Phobia>appendInherited(
         new KeyedCodec<>("Phobia", new EnumCodec<>(Phobia.class)),
         (var0, var1) -> var0.phobia = var1,
         var0 -> var0.phobia,
         (var0, var1) -> var0.phobia = var1.phobia
      )
      .addValidator(Validators.nonNull())
      .documentation("Enum used to specify if the NPC is part of a phobia (e.g. spider for arachnophobia).")
      .add()
      .<String>appendInherited(
         new KeyedCodec<>("PhobiaModelAssetId", Codec.STRING),
         (var0, var1) -> var0.phobiaModelAssetId = var1,
         var0 -> var0.phobiaModelAssetId,
         (var0, var1) -> var0.phobiaModelAssetId = var1.phobiaModelAssetId
      )
      .documentation("The model to use if the player has the setting with the matching phobia toggled on.")
      .addValidatorLate(() -> ModelAsset.VALIDATOR_CACHE.getValidator().late())
      .add()
      .afterDecode(var0 -> {
         if (var0.randomAttachmentSets != null && !var0.randomAttachmentSets.isEmpty()) {
            Map var1 = new Object2ObjectOpenHashMap();

            for (Entry var3 : var0.randomAttachmentSets.entrySet()) {
               WeightedMap.Builder var4 = WeightedMap.builder(ArrayUtil.EMPTY_STRING_ARRAY);

               for (Entry var6 : var3.getValue().entrySet()) {
                  var4.put(var6.getKey(), var6.getValue().weight);
               }

               var1.put(var3.getKey(), var4.build());
            }

            var0.weightedRandomAttachmentSets = var1;
         }
      })
      .build();
   class="kw">public class="kw">static class="kw">final ModelAsset DEBUG = new ModelAsset() {
      {
         this.id = "Debug";
         this.model = "Blocks/_Debug/Model.blockymodel";
         this.texture = "Characters/_Debug/Texture.png";
         this.camera = new CameraSettings(null, CameraAxis.STATIC_HEAD, CameraAxis.STATIC_HEAD);
         this.boundingBox = new Box(new Vector3d(0.0, 0.0, 0.0), new Vector3d(1.0, 1.0, 1.0));
         this.minScale = 1.0F;
         this.maxScale = 1.0F;
      }
   };
   class="kw">public class="kw">static class="kw">final ValidatorCache<String> VALIDATOR_CACHE = new ValidatorCache<>(new AssetKeyValidator<>(ModelAsset::getAssetStore));
   class="kw">private class="kw">static AssetStore<String, ModelAsset, DefaultAssetMap<String, ModelAsset>> ASSET_STORE;
   class="kw">protected AssetExtraInfo.Data extraData;
   class="kw">protected String id;
   class="kw">protected String model;
   class="kw">protected String texture;
   class="kw">protected String gradientSet;
   class="kw">protected String gradientId;
   class="kw">protected float eyeHeight;
   class="kw">protected float crouchOffset;
   class="kw">protected float sittingOffset;
   class="kw">protected float sleepingOffset;
   class="kw">protected Map<String, ModelAsset.AnimationSet> animationSetMap = Collections.emptyMap();
   class="kw">protected CameraSettings camera;
   class="kw">protected Box boundingBox;
   class="kw">protected ColorLight light;
   class="kw">protected ModelParticle[] particles;
   class="kw">protected ModelTrail[] trails;
   class="kw">protected PhysicsValues physicsValues = new PhysicsValues(68.0, 0.5, false);
   class="kw">protected ModelAttachment[] defaultAttachments;
   class="kw">protected Map<String, Map<String, ModelAttachment>> randomAttachmentSets;
   class="kw">protected float minScale = 0.95F;
   class="kw">protected float maxScale = 1.05F;
   class="kw">protected String icon;
   class="kw">protected AssetIconProperties iconProperties;
   class="kw">protected Map<String, DetailBox[]> detailBoxes = Collections.emptyMap();
   class="kw">protected Map<String, IWeightedMap<String>> weightedRandomAttachmentSets;
   @Nonnull
   class="kw">protected Phobia phobia = Phobia.None;
   class="kw">protected String phobiaModelAssetId;

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

   class="kw">public class="kw">static AssetStore<String, ModelAsset, DefaultAssetMap<String, ModelAsset>> getAssetStore() {
      if (ASSET_STORE == null) {
         ASSET_STORE = AssetRegistry.getAssetStore(ModelAsset.class);
      }

      class="kw">return ASSET_STORE;
   }

   class="kw">public class="kw">static DefaultAssetMap<String, ModelAsset> getAssetMap() {
      class="kw">return (DefaultAssetMap<String, ModelAsset>)getAssetStore().getAssetMap();
   }

   class="kw">public String getId() {
      class="kw">return this.id;
   }

   class="kw">public String getModel() {
      class="kw">return this.model;
   }

   class="kw">public String getTexture() {
      class="kw">return this.texture;
   }

   class="kw">public String getGradientId() {
      class="kw">return this.gradientId;
   }

   class="kw">public String getGradientSet() {
      class="kw">return this.gradientSet;
   }

   class="kw">public float getEyeHeight() {
      class="kw">return this.eyeHeight;
   }

   class="kw">public float getCrouchOffset() {
      class="kw">return this.crouchOffset;
   }

   class="kw">public float getSittingOffset() {
      class="kw">return this.sittingOffset;
   }

   class="kw">public float getSleepingOffset() {
      class="kw">return this.sleepingOffset;
   }

   class="kw">public Map<String, ModelAsset.AnimationSet> getAnimationSetMap() {
      class="kw">return this.animationSetMap;
   }

   class="kw">public CameraSettings getCamera() {
      class="kw">return this.camera;
   }

   @Nonnull
   class="kw">public Box getBoundingBox() {
      class="kw">return this.boundingBox;
   }

   class="kw">public ColorLight getLight() {
      class="kw">return this.light;
   }

   class="kw">public ModelParticle[] getParticles() {
      class="kw">return this.particles;
   }

   class="kw">public ModelTrail[] getTrails() {
      class="kw">return this.trails;
   }

   class="kw">public PhysicsValues getPhysicsValues() {
      class="kw">return this.physicsValues;
   }

   class="kw">public ModelAttachment[] getDefaultAttachments() {
      class="kw">return this.defaultAttachments;
   }

   class="kw">public Map<String, Map<String, ModelAttachment>> getRandomAttachmentSets() {
      class="kw">return this.randomAttachmentSets;
   }

   class="kw">public float getMinScale() {
      class="kw">return this.minScale;
   }

   class="kw">public float getMaxScale() {
      class="kw">return this.maxScale;
   }

   class="kw">public AssetIconProperties getIconProperties() {
      class="kw">return this.iconProperties;
   }

   class="kw">public String getIcon() {
      class="kw">return this.icon;
   }

   class="kw">public float generateRandomScale() {
      class="kw">return MathUtil.randomFloat(this.minScale, this.maxScale);
   }

   class="kw">public float generateDeterministicScale(long var1) {
      class="kw">return MathUtil.seededLerp(this.minScale, this.maxScale, var1);
   }

   @Nullable
   class="kw">public Map<String, String> generateRandomAttachmentIds() {
      if (this.weightedRandomAttachmentSets == null) {
         class="kw">return null;
      }

      ThreadLocalRandom var1 = ThreadLocalRandom.current();
      Map var2 = new Object2ObjectOpenHashMap();

      for (Entry var4 : this.weightedRandomAttachmentSets.entrySet()) {
         String var5 = var4.getKey();
         String var6 = var4.getValue().get(var1);
         if (var6 != null) {
            var2.put(var5, var6);
         }
      }

      class="kw">return var2;
   }

   class="kw">public ModelAttachment[] getAttachments(@Nullable Map<String, String> var1) {
      if (var1 != null && !var1.isEmpty() && this.randomAttachmentSets != null) {
         List var2 = new ObjectArrayList((this.defaultAttachments == null ? 0 : this.defaultAttachments.length) + var1.size());
         if (this.defaultAttachments != null) {
            Collections.addAll(var2, this.defaultAttachments);
         }

         for (Entry var4 : var1.entrySet()) {
            Map var5 = this.randomAttachmentSets.get(var4.getKey());
            if (var5 != null) {
               ModelAttachment var6 = var5.get(var4.getValue());
               if (var6 != null && var6.getModel() != null && var6.getTexture() != null) {
                  var2.add(var6);
               }
            }
         }

         class="kw">return var2.toArray(ModelAttachment[]::new);
      } else {
         class="kw">return this.defaultAttachments;
      }
   }

   class="kw">public Map<String, DetailBox[]> getDetailBoxes() {
      class="kw">return this.detailBoxes;
   }

   class="kw">public Phobia getPhobia() {
      class="kw">return this.phobia;
   }

   class="kw">public String getPhobiaModelAssetId() {
      class="kw">return this.phobiaModelAssetId;
   }

   @Override
   class="kw">public String toString() {
      class="kw">return "ModelAsset{id='"
         + this.id
         + "', model='"
         + this.model
         + "', texture='"
         + this.texture
         + "', gradientSet='"
         + this.gradientSet
         + "', gradientId='"
         + this.gradientId
         + "', eyeHeight="
         + this.eyeHeight
         + ", crouchOffset="
         + this.crouchOffset
         + ", sittingOffset="
         + this.sittingOffset
         + ", sleepingOffset="
         + this.sleepingOffset
         + ", animationSetMap="
         + this.animationSetMap
         + ", camera="
         + this.camera
         + ", boundingBox="
         + this.boundingBox
         + ", light="
         + this.light
         + ", particles="
         + Arrays.toString(this.particles)
         + ", trails="
         + Arrays.toString(this.trails)
         + ", physicsValues="
         + this.physicsValues
         + ", defaultAttachments="
         + Arrays.toString(this.defaultAttachments)
         + ", randomAttachmentSets="
         + this.randomAttachmentSets
         + ", minScale="
         + this.minScale
         + ", maxScale="
         + this.maxScale
         + ", icon='"
         + this.icon
         + "', iconProperties="
         + this.iconProperties
         + ", detailBoxes="
         + this.detailBoxes
         + ", weightedRandomAttachmentSets="
         + this.weightedRandomAttachmentSets
         + ", phobia="
         + this.phobia
         + ", phobiaModelAssetId='"
         + this.phobiaModelAssetId
         + "'}";
   }

   class="kw">public class="kw">static class Animation {
      class="kw">public class="kw">static class="kw">final BuilderCodec<ModelAsset.Animation> CODEC = BuilderCodec.builder(ModelAsset.Animation.class, ModelAsset.Animation::new)
         .append(new KeyedCodec<>("Animation", Codec.STRING), (var0, var1) -> var0.animation = var1, var0 -> var0.animation)
         .addValidator(Validators.nonNull())
         .addValidator(CommonAssetValidator.ANIMATION_CHARACTER)
         .add()
         .<Double>append(new KeyedCodec<>("Speed", Codec.DOUBLE), (var0, var1) -> var0.speed = var1.floatValue(), var0 -> (double)var0.speed)
         .addValidator(Validators.greaterThan(0.0))
         .add()
         .<Double>append(
            new KeyedCodec<>("BlendingDuration", Codec.DOUBLE),
            (var0, var1) -> var0.blendingDuration = var1.floatValue(),
            var0 -> (double)var0.blendingDuration
         )
         .addValidator(Validators.min(0.0))
         .add()
         .addField(new KeyedCodec<>("Looping", Codec.BOOLEAN), (var0, var1) -> var0.looping = var1, var0 -> var0.looping)
         .addField(new KeyedCodec<>("Weight", Codec.DOUBLE), (var0, var1) -> var0.weight = var1.floatValue(), var0 -> (double)var0.weight)
         .<int[]>append(new KeyedCodec<>("FootstepIntervals", Codec.INT_ARRAY), (var0, var1) -> var0.footstepIntervals = var1, var0 -> var0.footstepIntervals)
         .documentation(
            "The intervals (in percentage of the animation duration) at which footsteps are supposed to occur. Only relevant for movement animations (used for timing footstep sound effects)."
         )
         .addValidator(Validators.nonNull())
         .addValidator(new IntArrayValidator(Validators.range(0, 100)))
         .add()
         .<String>append(new KeyedCodec<>("SoundEventId", Codec.STRING), (var0, var1) -> var0.soundEventId = var1, var0 -> var0.soundEventId)
         .addValidator(SoundEvent.VALIDATOR_CACHE.getValidator())
         .addValidator(SoundEventValidators.MONO)
         .add()
         .<Integer>append(new KeyedCodec<>("PassiveLoopCount", Codec.INTEGER), (var0, var1) -> var0.passiveLoopCount = var1, var0 -> var0.passiveLoopCount)
         .addValidator(Validators.greaterThan(0))
         .add()
         .afterDecode(ModelAsset.Animation::processConfig)
         .build();
      class="kw">protected String animation;
      class="kw">protected float speed = 1.0F;
      class="kw">protected float blendingDuration = 0.2F;
      class="kw">protected boolean looping = true;
      class="kw">protected float weight = 1.0F;
      class="kw">protected int[] footstepIntervals = IntArrayCodec.EMPTY_INT_ARRAY;
      class="kw">protected String soundEventId;
      class="kw">protected class="kw">transient int soundEventIndex;
      class="kw">protected int passiveLoopCount = 1;

      class="kw">public Animation(String var1, String var2, float var3, float var4, boolean var5, float var6, int[] var7, String var8) {
         this.animation = var2;
         this.speed = var3;
         this.blendingDuration = var4;
         this.looping = var5;
         this.weight = var6;
         this.footstepIntervals = var7;
         this.soundEventId = var8;
      }

      class="kw">protected Animation() {
      }

      class="kw">public String getAnimation() {
         class="kw">return this.animation;
      }

      class="kw">public float getSpeed() {
         class="kw">return this.speed;
      }

      class="kw">public float getBlendingDuration() {
         class="kw">return this.blendingDuration;
      }

      class="kw">public boolean isLooping() {
         class="kw">return this.looping;
      }

      class="kw">public double getWeight() {
         class="kw">return this.weight;
      }

      class="kw">public String getSoundEventId() {
         class="kw">return this.soundEventId;
      }

      class="kw">public int getSoundEventIndex() {
         class="kw">return this.soundEventIndex;
      }

      @Nonnull
      class="kw">public com.hypixel.hytale.protocol.Animation toPacket() {
         com.hypixel.hytale.protocol.Animation var1 = new com.hypixel.hytale.protocol.Animation();
         var1.name = this.animation;
         var1.speed = this.speed;
         var1.blendingDuration = this.blendingDuration;
         var1.looping = this.looping;
         var1.weight = this.weight;
         var1.footstepIntervals = this.footstepIntervals;
         var1.soundEventIndex = this.soundEventIndex;
         var1.passiveLoopCount = this.passiveLoopCount;
         class="kw">return var1;
      }

      class="kw">protected void processConfig() {
         if (this.soundEventId != null) {
            this.soundEventIndex = SoundEvent.getAssetMap().getIndex(this.soundEventId);
         }
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return "Animation{animation='"
            + this.animation
            + "', speed="
            + this.speed
            + ", blendingDuration="
            + this.blendingDuration
            + ", looping="
            + this.looping
            + ", weight="
            + this.weight
            + ", footstepIntervals="
            + Arrays.toString(this.footstepIntervals)
            + ", soundEventId='"
            + this.soundEventId
            + "', soundEventIndex="
            + this.soundEventIndex
            + ", passiveLoopCount="
            + this.passiveLoopCount
            + "}";
      }
   }

   class="kw">public class="kw">static class AnimationSet {
      class="kw">public class="kw">static class="kw">final BuilderCodec<ModelAsset.AnimationSet> CODEC = BuilderCodec.builder(ModelAsset.AnimationSet.class, ModelAsset.AnimationSet::new)
         .append(
            new KeyedCodec<>("Animations", new ArrayCodec<>(ModelAsset.Animation.CODEC, ModelAsset.Animation[]::new)),
            (var0, var1) -> var0.animations = var1,
            var0 -> var0.animations
         )
         .addValidator(Validators.nonEmptyArray())
         .add()
         .addField(
            new KeyedCodec<>("NextAnimationDelay", ProtocolCodecs.RANGEF), (var0, var1) -> var0.nextAnimationDelay = var1, var0 -> var0.nextAnimationDelay
         )
         .build();
      class="kw">public class="kw">static class="kw">final Rangef DEFAULT_NEXT_ANIMATION_DELAY = new Rangef(2.0F, 10.0F);
      class="kw">protected ModelAsset.Animation[] animations;
      class="kw">protected Rangef nextAnimationDelay = DEFAULT_NEXT_ANIMATION_DELAY;

      class="kw">public AnimationSet(ModelAsset.Animation[] var1, Rangef var2) {
         this.animations = var1;
         this.nextAnimationDelay = var2;
      }

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

      class="kw">public ModelAsset.Animation[] getAnimations() {
         class="kw">return this.animations;
      }

      class="kw">public Rangef getNextAnimationDelay() {
         class="kw">return this.nextAnimationDelay;
      }

      @Nonnull
      class="kw">public com.hypixel.hytale.protocol.AnimationSet toPacket(String var1) {
         com.hypixel.hytale.protocol.AnimationSet var2 = new com.hypixel.hytale.protocol.AnimationSet();
         var2.id = var1;
         var2.animations = ArrayUtil.copyAndMutate(this.animations, ModelAsset.Animation::toPacket, com.hypixel.hytale.protocol.Animation[]::new);
         var2.nextAnimationDelay = this.nextAnimationDelay;
         class="kw">return var2;
      }

      @Nonnull
      @Override
      class="kw">public String toString() {
         class="kw">return "AnimationSet{animations=" + Arrays.toString(this.animations) + ", nextAnimationDelay=" + this.nextAnimationDelay + "}";
      }
   }
}