Advertisement
jayhillx

redpanda

Feb 9th, 2024
763
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 21.66 KB | None | 0 0
  1. package com.mysticsbiomes.common.animal;
  2.  
  3. import com.mysticsbiomes.init.MysticBlocks;
  4. import com.mysticsbiomes.init.MysticEntities;
  5. import net.minecraft.advancements.CriteriaTriggers;
  6. import net.minecraft.core.BlockPos;
  7. import net.minecraft.nbt.CompoundTag;
  8. import net.minecraft.nbt.NbtUtils;
  9. import net.minecraft.network.syncher.EntityDataAccessor;
  10. import net.minecraft.network.syncher.EntityDataSerializers;
  11. import net.minecraft.network.syncher.SynchedEntityData;
  12. import net.minecraft.server.level.ServerLevel;
  13. import net.minecraft.server.level.ServerPlayer;
  14. import net.minecraft.stats.Stats;
  15. import net.minecraft.util.ByIdMap;
  16. import net.minecraft.util.RandomSource;
  17. import net.minecraft.util.StringRepresentable;
  18. import net.minecraft.world.DifficultyInstance;
  19. import net.minecraft.world.InteractionHand;
  20. import net.minecraft.world.damagesource.DamageSource;
  21. import net.minecraft.world.entity.*;
  22. import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
  23. import net.minecraft.world.entity.ai.attributes.Attributes;
  24. import net.minecraft.world.entity.ai.control.LookControl;
  25. import net.minecraft.world.entity.ai.control.MoveControl;
  26. import net.minecraft.world.entity.ai.goal.*;
  27. import net.minecraft.world.entity.ai.targeting.TargetingConditions;
  28. import net.minecraft.world.entity.animal.*;
  29. import net.minecraft.world.entity.item.ItemEntity;
  30. import net.minecraft.world.entity.player.Player;
  31. import net.minecraft.world.item.ItemStack;
  32. import net.minecraft.world.item.Items;
  33. import net.minecraft.world.item.crafting.Ingredient;
  34. import net.minecraft.world.level.GameRules;
  35. import net.minecraft.world.level.Level;
  36. import net.minecraft.world.level.ServerLevelAccessor;
  37. import net.minecraft.world.level.block.Blocks;
  38. import net.minecraft.world.level.block.state.BlockState;
  39. import net.minecraftforge.common.MinecraftForge;
  40. import net.minecraftforge.event.entity.living.BabyEntitySpawnEvent;
  41.  
  42. import javax.annotation.Nullable;
  43. import java.util.EnumSet;
  44. import java.util.Optional;
  45. import java.util.UUID;
  46.  
  47. public class RedPanda extends Animal {
  48.     private static final EntityDataAccessor<Byte> DATA_TRAIT_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.BYTE);
  49.     private static final EntityDataAccessor<Byte> DATA_HIDDEN_TRAIT_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.BYTE);
  50.     private static final EntityDataAccessor<Byte> DATA_QUIRK_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.BYTE);
  51.     private static final EntityDataAccessor<Byte> DATA_FLAGS_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.BYTE);
  52.     private static final EntityDataAccessor<Optional<UUID>> DATA_TRUSTED_ID = SynchedEntityData.defineId(RedPanda.class, EntityDataSerializers.OPTIONAL_UUID);
  53.     public final AnimationState idleAnimationState = new AnimationState();
  54.     public final AnimationState sleepingAnimationState = new AnimationState();
  55.  
  56.     public RedPanda(EntityType<? extends RedPanda> type, Level level) {
  57.         super(type, level);
  58.         this.moveControl = new RedPandaMoveControl();
  59.         this.lookControl = new RedPandaLookControl();
  60.         //this.setCanPickUpLoot(!this.isBaby());
  61.     }
  62.  
  63.     protected void defineSynchedData() {
  64.         super.defineSynchedData();
  65.         this.entityData.define(DATA_TRAIT_ID, (byte)0);
  66.         this.entityData.define(DATA_HIDDEN_TRAIT_ID, (byte)0);
  67.         this.entityData.define(DATA_QUIRK_ID, (byte)0);
  68.         this.entityData.define(DATA_FLAGS_ID, (byte)0);
  69.         this.entityData.define(DATA_TRUSTED_ID, Optional.empty());
  70.     }
  71.  
  72.     protected void registerGoals() {
  73.         this.goalSelector.addGoal(0, new PanicGoal(this, 2.0));
  74.         this.goalSelector.addGoal(1, new RedPandaBreedGoal(1.0));
  75.         this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2F, true));
  76.         this.goalSelector.addGoal(3, new TemptGoal(this, 1.0, Ingredient.of(Blocks.BAMBOO.asItem()), false));
  77.         this.goalSelector.addGoal(4, new AvoidEntityGoal<>(this, Player.class, 6.0F, 1.6, 2.5, (entity) -> {
  78.             boolean flag = EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) && !this.trusts(entity.getUUID()) && entity.isSprinting();
  79.             this.setSprinting(flag);
  80.             return flag;
  81.         }));
  82.         this.goalSelector.addGoal(5, new SleepGoal());
  83.         this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
  84.         this.goalSelector.addGoal(7, new RandomLookAroundGoal(this));
  85.         this.goalSelector.addGoal(8, new FollowParentGoal(this, 1.25));
  86.         this.goalSelector.addGoal(9, new WaterAvoidingRandomStrollGoal(this, 1.0));
  87.     }
  88.  
  89.     public static AttributeSupplier.Builder createAttributes() {
  90.         return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 0.125F).add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.FOLLOW_RANGE, 32.0D).add(Attributes.ATTACK_DAMAGE, 8.0D);
  91.     }
  92.  
  93.     public SpawnGroupData finalizeSpawn(ServerLevelAccessor accessor, DifficultyInstance instance, MobSpawnType type, @Nullable SpawnGroupData data, @Nullable CompoundTag tag) {
  94.         return super.finalizeSpawn(accessor, instance, type, data, tag);
  95.     }
  96.  
  97.     @Nullable
  98.     public RedPanda getBreedOffspring(ServerLevel level, AgeableMob mob) {
  99.         RedPanda redPanda = MysticEntities.RED_PANDA.get().create(level);
  100.         if (redPanda != null) {
  101.             redPanda.setTrait(this.random.nextBoolean() ? this.getVariant() : ((RedPanda)mob).getVariant());
  102.         }
  103.         return redPanda;
  104.     }
  105.  
  106.     protected void onOffspringSpawnedFromEgg(Player player, Mob mob) {
  107.         ((RedPanda)mob).addTrustedPlayer(player.getUUID());
  108.     }
  109.  
  110.     protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) {
  111.         return this.isBaby() ? dimensions.height * 0.85F : 0.4F;
  112.     }
  113.  
  114.     ///////////////////////////////////////////////////////////////////////////
  115.  
  116.     @Override
  117.     public void addAdditionalSaveData(CompoundTag tag) {
  118.         super.addAdditionalSaveData(tag);
  119.         tag.putString("Trait", this.getTrait().getSerializedName());
  120.         tag.putString("HiddenTrait", this.getHiddenTrait().getSerializedName());
  121.         tag.putString("Quirk", this.getQuirk().getSerializedName());
  122.         tag.putBoolean("Sleeping", this.isSleeping());
  123.  
  124.         if (this.getTrustedPlayer() != null) {
  125.             tag.put("Trusted", NbtUtils.createUUID(this.getTrustedPlayer()));
  126.         }
  127.     }
  128.  
  129.     @Override
  130.     public void readAdditionalSaveData(CompoundTag tag) {
  131.         super.readAdditionalSaveData(tag);
  132.         this.setTrait(Trait.byName(tag.getString("Trait")));
  133.         this.setHiddenTrait(Trait.byName(tag.getString("HiddenTrait")));
  134.         this.setQuirk(Quirk.byName(tag.getString("Quirk")));
  135.         this.setSleeping(tag.getBoolean("Sleeping"));
  136.  
  137.         if (tag.contains("Trusted")) {
  138.             this.addTrustedPlayer(NbtUtils.loadUUID(tag.get("Trusted")));
  139.         }
  140.     }
  141.  
  142.     // TRAITS
  143.  
  144.     public Trait getTrait() {
  145.         return Trait.byId(this.entityData.get(DATA_TRAIT_ID));
  146.     }
  147.  
  148.     public void setTrait(Trait trait) {
  149.         this.entityData.set(DATA_TRAIT_ID, (byte)trait.getId());
  150.     }
  151.  
  152.     public Trait getHiddenTrait() {
  153.         return Trait.byId(this.entityData.get(DATA_HIDDEN_TRAIT_ID));
  154.     }
  155.  
  156.     public void setHiddenTrait(Trait trait) {
  157.         this.entityData.set(DATA_HIDDEN_TRAIT_ID, (byte)trait.getId());
  158.     }
  159.  
  160.     public Trait getVariant() {
  161.         return Trait.getTraitFromGenes(this.getTrait(), this.getHiddenTrait());
  162.     }
  163.  
  164.     public boolean isClumsy() {
  165.         return this.getTrait() == Trait.CLUMSY;
  166.     }
  167.  
  168.     public boolean isGloomy() {
  169.         return this.getTrait() == Trait.GLOOMY;
  170.     }
  171.  
  172.     public boolean isWeak() {
  173.         return this.getTrait() == Trait.WEAK;
  174.     }
  175.  
  176.     public boolean isPlayful() {
  177.         return this.getTrait() == Trait.PLAYFUL;
  178.     }
  179.  
  180.     public boolean isCherry() {
  181.         return this.getTrait() == Trait.CHERRY;
  182.     }
  183.  
  184.     // QUIRKS
  185.  
  186.     public Quirk getQuirk() {
  187.         return Quirk.byId(this.entityData.get(DATA_QUIRK_ID));
  188.     }
  189.  
  190.     public void setQuirk(Quirk trait) {
  191.         this.entityData.set(DATA_QUIRK_ID, (byte)trait.getId());
  192.     }
  193.  
  194.     public boolean lovesSnow() {
  195.         return this.getQuirk() == Quirk.LOVES_SNOW;
  196.     }
  197.  
  198.     public boolean isLoyal() {
  199.         return this.getQuirk() == Quirk.LOYAL;
  200.     }
  201.  
  202.     public boolean isMischievous() {
  203.         return this.getQuirk() == Quirk.MISCHIEVOUS;
  204.     }
  205.  
  206.     public boolean isCurious() {
  207.         return this.getQuirk() == Quirk.CURIOUS;
  208.     }
  209.  
  210.     public boolean isClingy() {
  211.         return this.getQuirk() == Quirk.CLINGY;
  212.     }
  213.  
  214.     ///////////////////////////////////////////////////////////////////////////
  215.  
  216.     public boolean isSleeping() {
  217.         return this.getFlag(2);
  218.     }
  219.  
  220.     public void setSleeping(boolean sleeping) {
  221.         this.setFlag(2, sleeping);
  222.     }
  223.  
  224.     public void wakeUp() {
  225.         this.setSleeping(false);
  226.     }
  227.  
  228.     public boolean isStanding() {
  229.         return this.getFlag(8);
  230.     }
  231.  
  232.     public void setStanding(boolean sleeping) {
  233.         this.setFlag(8, sleeping);
  234.     }
  235.  
  236.     private boolean getFlag(int value) {
  237.         return (this.entityData.get(DATA_FLAGS_ID) & value) != 0;
  238.     }
  239.  
  240.     private void setFlag(int value, boolean b) {
  241.         if (b) {
  242.             this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) | value));
  243.         } else {
  244.             this.entityData.set(DATA_FLAGS_ID, (byte)(this.entityData.get(DATA_FLAGS_ID) & ~value));
  245.         }
  246.     }
  247.  
  248.     ///////////////////////////////////////////////////////////////////////////
  249.  
  250.     private UUID getTrustedPlayer() {
  251.         return this.entityData.get(DATA_TRUSTED_ID).orElse(null);
  252.     }
  253.  
  254.     private void addTrustedPlayer(UUID uuid) {
  255.         this.entityData.set(DATA_TRUSTED_ID, Optional.ofNullable(uuid));
  256.     }
  257.  
  258.     private boolean trusts(UUID uuid) {
  259.         return this.getTrustedPlayer() == uuid;
  260.     }
  261.  
  262.     ///////////////////////////////////////////////////////////////////////////
  263.  
  264.     @Override
  265.     public void tick() {
  266.         super.tick();
  267.         if (this.isEffectiveAi()) {
  268.             boolean flag = this.isInWater();
  269.  
  270.             if (flag && this.isSleeping()) {
  271.                 this.setSleeping(false);
  272.             }
  273.         }
  274.  
  275.         this.setStanding(this.walkAnimation.isMoving() && this.isHoldingItem());
  276.  
  277.         if (this.level().isClientSide()) {
  278.             if (this.isSleeping()) {
  279.                 this.sleepingAnimationState.start(this.tickCount);
  280.             } else {
  281.                 this.idleAnimationState.animateWhen(!this.walkAnimation.isMoving(), this.tickCount);
  282.             }
  283.         }
  284.     }
  285.  
  286.     @Override
  287.     public void aiStep() {
  288.         if (this.isSleeping() || this.isImmobile()) {
  289.             this.jumping = false;
  290.             this.xxa = 0.0F;
  291.             this.zza = 0.0F;
  292.         }
  293.  
  294.         super.aiStep();
  295.     }
  296.  
  297.     ///////////////////////////////////////////////////////////////////////////
  298.  
  299.     public boolean isFood(ItemStack stack) {
  300.         return stack.is(Items.BAMBOO);
  301.     }
  302.  
  303.     public boolean hurt(DamageSource source, float amount) {
  304.         if (this.isInvulnerableTo(source)) {
  305.             return false;
  306.         } else {
  307.             if (!this.level().isClientSide) {
  308.                 this.wakeUp();
  309.             }
  310.             return super.hurt(source, amount);
  311.         }
  312.     }
  313.  
  314.     protected void dropEquipment() {
  315.         super.dropEquipment();
  316.         ItemStack stack = this.getItemBySlot(EquipmentSlot.MAINHAND);
  317.         if (!stack.isEmpty()) {
  318.             this.spawnAtLocation(stack);
  319.             this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
  320.         }
  321.     }
  322.  
  323.     ///////////////////////////////////////////////////////////////////////////
  324.  
  325.     @Override
  326.     protected void pickUpItem(ItemEntity entity) {
  327.         super.pickUpItem(entity);
  328.     }
  329.  
  330.     /**
  331.      * @return weather they are holding an item; used for if they should stand up or not when holding something.
  332.      */
  333.     public boolean isHoldingItem() {
  334.         return !this.getHeldItem().isEmpty();
  335.     }
  336.  
  337.     public ItemStack getHeldItem() {
  338.         return this.getItemInHand(InteractionHand.MAIN_HAND);
  339.     }
  340.  
  341.     ///////////////////////////////////////////////////////////////////////////
  342.  
  343.     // GENERAL
  344.  
  345.     abstract class RedPandaBehaviorGoal extends Goal {
  346.         private final TargetingConditions NEARBY_TARGET_CONDITIONS = TargetingConditions.forCombat().range(12.0).ignoreLineOfSight();
  347.  
  348.         protected boolean alertable() {
  349.             return !RedPanda.this.level().getNearbyEntities(LivingEntity.class, this.NEARBY_TARGET_CONDITIONS, RedPanda.this, RedPanda.this.getBoundingBox().inflate(12.0, 6.0, 12.0)).isEmpty();
  350.         }
  351.     }
  352.  
  353.     class SleepGoal extends Goal {
  354.  
  355.         public boolean canUse() {
  356.             return RedPanda.this.level().isNight();
  357.         }
  358.  
  359.         public boolean canContinueToUse() {
  360.             return !RedPanda.this.isInWater();
  361.         }
  362.  
  363.         public void start() {
  364.             RedPanda.this.setSleeping(true);
  365.         }
  366.  
  367.         public void stop() {
  368.             RedPanda.this.wakeUp();
  369.         }
  370.     }
  371.  
  372.     // TRAITS
  373.  
  374.     /**
  375.      * Clumsy red pandas will trip over randomly while walking.
  376.      */
  377.     class TripGoal extends Goal {
  378.         int randomChance = RedPanda.this.random.nextInt(300);
  379.  
  380.         TripGoal() {
  381.             this.setFlags(EnumSet.of(Flag.MOVE));
  382.         }
  383.  
  384.         public boolean canUse() {
  385.             return RedPanda.this.isClumsy();
  386.         }
  387.     }
  388.  
  389.     /**
  390.      * Gloomy red pandas will cry randomly, when it's raining, or when they're a baby away from their parent.
  391.      */
  392.     class CryGoal extends Goal {
  393.         int ticksSpentCrying;
  394.         int cooldownUntilCanCry;
  395.  
  396.         public boolean canUse() {
  397.             return RedPanda.this.isGloomy();
  398.         }
  399.     }
  400.  
  401.     /**
  402.      * Weak red pandas sneeze randomly.
  403.      */
  404.     class SneezeGoal extends Goal {
  405.  
  406.         public boolean canUse() {
  407.             return RedPanda.this.isWeak();
  408.         }
  409.     }
  410.  
  411.     // QUIRKS
  412.  
  413.     class ReturnItemGoal extends Goal {
  414.  
  415.         public boolean canUse() {
  416.             return RedPanda.this.isLoyal();
  417.         }
  418.     }
  419.  
  420.     class StealItemGoal extends Goal {
  421.  
  422.         public boolean canUse() {
  423.             return RedPanda.this.isMischievous();
  424.         }
  425.     }
  426.  
  427.     class SniffGoal extends Goal {
  428.  
  429.         public boolean canUse() {
  430.             return RedPanda.this.isCurious();
  431.         }
  432.     }
  433.  
  434.     ///////////////////////////////////////////////////////////////////////////
  435.  
  436.     class RedPandaBreedGoal extends BreedGoal {
  437.  
  438.         public RedPandaBreedGoal(double speed) {
  439.             super(RedPanda.this, speed);
  440.         }
  441.  
  442.         public boolean canUse() {
  443.             return super.canUse() && this.canFindBamboo();
  444.         }
  445.  
  446.         @Override
  447.         protected void breed() {
  448.             ServerLevel level = (ServerLevel)this.level;
  449.             RedPanda redPanda = (RedPanda)this.animal.getBreedOffspring(level, this.partner);
  450.             BabyEntitySpawnEvent event = new BabyEntitySpawnEvent(this.animal, this.partner, redPanda);
  451.             redPanda = (RedPanda)event.getChild();
  452.             boolean cancelled = MinecraftForge.EVENT_BUS.post(event);
  453.             if (cancelled) {
  454.                 this.animal.setAge(6000);
  455.                 this.partner.setAge(6000);
  456.                 this.animal.resetLove();
  457.                 this.partner.resetLove();
  458.             } else {
  459.                 if (redPanda != null) {
  460.                     ServerPlayer causePlayer = this.animal.getLoveCause();
  461.                     ServerPlayer causePlayer2 = this.partner.getLoveCause();
  462.                     ServerPlayer player = causePlayer;
  463.                     if (causePlayer != null) {
  464.                         redPanda.addTrustedPlayer(causePlayer.getUUID());
  465.                     } else {
  466.                         player = causePlayer2;
  467.                     }
  468.  
  469.                     if (causePlayer2 != null && causePlayer != causePlayer2) {
  470.                         redPanda.addTrustedPlayer(causePlayer2.getUUID());
  471.                     }
  472.  
  473.                     if (player != null) {
  474.                         player.awardStat(Stats.ANIMALS_BRED);
  475.                         CriteriaTriggers.BRED_ANIMALS.trigger(player, this.animal, this.partner, redPanda);
  476.                     }
  477.  
  478.                     this.animal.setAge(6000);
  479.                     this.partner.setAge(6000);
  480.                     this.animal.resetLove();
  481.                     this.partner.resetLove();
  482.                     redPanda.setAge(-24000);
  483.                     redPanda.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F);
  484.                     level.addFreshEntityWithPassengers(redPanda);
  485.                     this.level.broadcastEntityEvent(this.animal, (byte)18);
  486.                     if (this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
  487.                         this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), this.animal.getRandom().nextInt(7) + 1));
  488.                     }
  489.                 }
  490.             }
  491.         }
  492.  
  493.         private boolean canFindBamboo() {
  494.             BlockPos pos = RedPanda.this.blockPosition();
  495.             BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
  496.  
  497.             for (int i = 0; i < 3; ++i) {
  498.                 for (int j = 0; j < 8; ++j) {
  499.                     for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) {
  500.                         for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) {
  501.                             mutablePos.setWithOffset(pos, k, i, l);
  502.                             BlockState mutableState = this.level.getBlockState(mutablePos);
  503.                             if (mutableState.is(Blocks.BAMBOO) || mutableState.is(MysticBlocks.SPRING_BAMBOO.get())) {
  504.                                 return true;
  505.                             }
  506.                         }
  507.                     }
  508.                 }
  509.             }
  510.             return false;
  511.         }
  512.     }
  513.  
  514.     class RedPandaMoveControl extends MoveControl {
  515.  
  516.         public RedPandaMoveControl() {
  517.             super(RedPanda.this);
  518.         }
  519.  
  520.         public void tick() {
  521.             if (!RedPanda.this.isSleeping()) {
  522.                 super.tick();
  523.             }
  524.         }
  525.     }
  526.  
  527.     class RedPandaLookControl extends LookControl {
  528.  
  529.         public RedPandaLookControl() {
  530.             super(RedPanda.this);
  531.         }
  532.  
  533.         public void tick() {
  534.             if (!RedPanda.this.isSleeping()) {
  535.                 super.tick();
  536.             }
  537.         }
  538.     }
  539.  
  540.     ///////////////////////////////////////////////////////////////////////////
  541.  
  542.     /**
  543.      * Main personality trait that defines most of a red pandas actions & behaviors.
  544.      */
  545.     public enum Trait implements StringRepresentable {
  546.         NORMAL(0, "normal", false),
  547.         CLUMSY(1, "clumsy", false),
  548.         GLOOMY(2, "gloomy", false),
  549.         WEAK(3, "weak", true),
  550.         LAZY(4, "lazy", false),
  551.         PLAYFUL(5, "playful", false),
  552.         CHERRY(6, "cherry", true);
  553.  
  554.         private final int id;
  555.         private final String name;
  556.         private final boolean recessive;
  557.  
  558.         Trait(int id, String name, boolean recessive) {
  559.             this.id = id;
  560.             this.name = name;
  561.             this.recessive = recessive;
  562.         }
  563.  
  564.         public String getSerializedName() {
  565.             return this.name;
  566.         }
  567.  
  568.         public int getId() {
  569.             return this.id;
  570.         }
  571.  
  572.         public boolean isRecessive() {
  573.             return this.recessive;
  574.         }
  575.  
  576.         public static Trait byName(String name) {
  577.             return StringRepresentable.fromEnum(Trait::values).byName(name, NORMAL);
  578.         }
  579.  
  580.         public static Trait byId(int id) {
  581.             return ByIdMap.continuous(Trait::getId, values(), ByIdMap.OutOfBoundsStrategy.ZERO).apply(id);
  582.         }
  583.  
  584.         public static Trait getTraitFromGenes(Trait trait1, Trait trait2) {
  585.             if (trait1.isRecessive()) {
  586.                 return trait1 == trait2 ? trait1 : NORMAL;
  587.             } else {
  588.                 return trait1;
  589.             }
  590.         }
  591.  
  592.         public static Trait getRandom(RandomSource source) {
  593.             int i = source.nextInt(16);
  594.             if (i == 0) {
  595.                 return CLUMSY;
  596.             } else if (i == 1) {
  597.                 return GLOOMY;
  598.             } else if (i == 2) {
  599.                 return WEAK;
  600.             } else if (i == 4) {
  601.                 return LAZY;
  602.             } else if (i < 9) {
  603.                 return PLAYFUL;
  604.             } else {
  605.                 return i < 11 ? CHERRY : NORMAL;
  606.             }
  607.         }
  608.     }
  609.  
  610.     /**
  611.      * Little additions to go with traits; making each red panda more distinct and unique.
  612.      */
  613.     public enum Quirk implements StringRepresentable {
  614.         NONE(0, "none"),
  615.         LOVES_SNOW(1, "loves_snow"),
  616.         LOYAL(2, "loyal"),
  617.         MISCHIEVOUS(3, "mischievous"),
  618.         CURIOUS(4, "curious"),
  619.         CLINGY(5, "clingy");
  620.  
  621.         private final int id;
  622.         private final String name;
  623.  
  624.         Quirk(int id, String name) {
  625.             this.id = id;
  626.             this.name = name;
  627.         }
  628.  
  629.         public String getSerializedName() {
  630.             return this.name;
  631.         }
  632.  
  633.         public int getId() {
  634.             return this.id;
  635.         }
  636.  
  637.         public static Quirk byName(String name) {
  638.             return StringRepresentable.fromEnum(Quirk::values).byName(name, NONE);
  639.         }
  640.  
  641.         public static Quirk byId(int id) {
  642.             return ByIdMap.continuous(Quirk::getId, values(), ByIdMap.OutOfBoundsStrategy.ZERO).apply(id);
  643.         }
  644.     }
  645.  
  646. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement