PlaceBlockProcedure class

Пакет: com.hypixel.hytale.builtin.randomtick.procedures

Файл: com/hypixel/hytale/builtin/randomtick/procedures/PlaceBlockProcedure.java

implements: RandomTickProcedure

Поля (35)

МодификаторыТипИмя
final BuilderCodec<PlaceBlockProcedure> CODEC
public static final BuilderCodec<PlaceBlockProcedure.PlacementRule> CODEC
public static final BuilderCodec<PlaceBlockProcedure.WeightedBlock> CODEC
private String block
private String block
private PlaceBlockProcedure.WeightedBlock[] blocks
private String state
private transient double totalWeight
BlockType var1
int var10
int var10
Ref var10
double var10
int var11
String var12
var12
PlaceBlockProcedure.PlacementRule var13
int var14
BlockType var15
int var16
Set var2
boolean var2
PlaceBlockProcedure.WeightedBlock var2
BlockTypeAssetMap var2
double var2
boolean var3
String var6
String var7
ChunkStore var7
Ref var8
int var9
BlockSection var9
BlockSection var9
var9
private double weight

Методы (36)

МодификаторыВозвратСигнатура
public PlacementRulepublic PlacementRule()
public WeightedBlockpublic WeightedBlock()
for for(PlaceBlockProcedure.PlacementRule var6 : var0.placements)
for for(PlaceBlockProcedure.PlacementRule var5 : this.placements)
for for(PlaceBlockProcedure.WeightedBlock var6 : this.blocks)
for for(PlaceBlockProcedure.WeightedBlock var7 : this.blocks)
for for(PlaceBlockProcedure.WeightedBlock var9 : this.blocks)
public String getBlockpublic String getBlock()
public String getBlockpublic String getBlock()
static int getBlockIdint getBlockId(Store<ChunkStore> var0, CommandBuffer<ChunkStore> var1, BlockSection var2, int var3, int var4, int var5, int var6, int var7, int var8)
public PlaceBlockProcedure.WeightedBlock[] getBlockspublic PlaceBlockProcedure.WeightedBlock[] getBlocks()
public String getStatepublic String getState()
public double getWeightpublic double getWeight()
if if(var0.placements != null)
if if(this.placements != null && this.placements.length != 0 && this.offset != null)
if if(var12 == null)
if if(var13 != null)
if if(var14 != Integer.MIN_VALUE)
if if(var15 != null)
if if(var9 != null)
if if(var10 != var14)
if if(var10 == null)
if if(var9 == null)
if if(var2 == var3)
if if(this.blocks != null && this.blocks.length > 0)
if if(var1 == Integer.MIN_VALUE)
if if(this.blocks != null && this.blocks.length > 0)
if if(var2 <= 0.0)
if if(var2 <= 0.0)
if if(var10 <= 0.0)
static boolean isEmptyboolean isEmpty(int var0)
private PlaceBlockProcedure.WeightedBlock pickWeightedprivate PlaceBlockProcedure.WeightedBlock pickWeighted(@Nonnull Random var1)
boolean placesBlockIdboolean placesBlockId(int var1)
int resolveBlockIdint resolveBlockId(@Nonnull Random var1)
public String toStringpublic String toString()
public String toStringpublic String toString()

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.randomtick.procedures;

class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
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.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector3iUtil;
class="kw">import com.hypixel.hytale.protocol.BlockMaterial;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktick.config.RandomTickProcedure;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockOperations;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import java.util.Arrays;
class="kw">import java.util.HashSet;
class="kw">import java.util.Random;
class="kw">import java.util.Set;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3i;

class="kw">public class PlaceBlockProcedure class="kw">implements RandomTickProcedure {
   class="kw">public class="kw">static class="kw">final BuilderCodec<PlaceBlockProcedure> CODEC = BuilderCodec.builder(PlaceBlockProcedure.class, PlaceBlockProcedure::new)
      .appendInherited(
         new KeyedCodec<>("Placements", new ArrayCodec<>(PlaceBlockProcedure.PlacementRule.CODEC, PlaceBlockProcedure.PlacementRule[]::new)),
         (var0, var1) -> var0.placements = var1,
         var0 -> var0.placements,
         (var0, var1) -> var0.placements = var1.placements
      )
      .documentation(
         "The blocks that can be placed at the configured Offset. Each rule may optionally be scoped to one of this block's visual States; a rule with no State applies to the block's class="kw">default (stateless) form. The first rule matching the block's current State is placed when the target cell is clear."
      )
      .addValidator(Validators.nonEmptyArray())
      .add()
      .<Vector3i>appendInherited(
         new KeyedCodec<>("Offset", Vector3iUtil.CODEC), (var0, var1) -> var0.offset = var1, var0 -> var0.offset, (var0, var1) -> var0.offset = var1.offset
      )
      .documentation(
         "The block offset (relative to the ticking block) at which to place the block. For example X=0, Y=1, Z=0 places the block one cell directly above."
      )
      .addValidator(Validators.nonNull())
      .add()
      .<Boolean>appendInherited(
         new KeyedCodec<>("RequireEmptyTarget", Codec.BOOLEAN),
         (var0, var1) -> var0.requireEmptyTarget = var1,
         var0 -> var0.requireEmptyTarget,
         (var0, var1) -> var0.requireEmptyTarget = var1.requireEmptyTarget
      )
      .documentation(
         "Whether the target cell must be empty (air) for the placement to occur. When true (the class="kw">default) an obstruction causes the procedure to silently do nothing and retry on a later tick."
      )
      .add()
      .validator((var0, var1) -> {
         if (var0.placements != null) {
            Set var2 = new HashSet<>();

            for (PlaceBlockProcedure.PlacementRule var6 : var0.placements) {
               String var7 = var6.state != null ? var6.state : "class="kw">default";
               if (!var2.add(var7)) {
                  var1.fail("Multiple Placements target the same State '" + var7 + "'; only the first would ever apply.");
               }
            }
         }
      })
      .build();
   class="kw">private PlaceBlockProcedure.PlacementRule[] placements;
   class="kw">private Vector3i offset;
   class="kw">private boolean requireEmptyTarget = true;

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

   @Override
   class="kw">public void onRandomTick(Store<ChunkStore> var1, CommandBuffer<ChunkStore> var2, BlockSection var3, int var4, int var5, int var6, int var7, BlockType var8) {
      if (this.placements != null && this.placements.length != 0 && this.offset != null) {
         int var9 = var4 + this.offset.x();
         int var10 = var5 + this.offset.y();
         int var11 = var6 + this.offset.z();
         String var12 = var8.getStateForBlock(var8.getId());
         if (var12 == null) {
            var12 = "class="kw">default";
         }

         PlaceBlockProcedure.PlacementRule var13 = this.findRule(var12);
         if (var13 != null) {
            int var14 = var13.resolveBlockId(ThreadLocalRandom.current());
            if (var14 != Integer.MIN_VALUE) {
               BlockType var15 = BlockType.getAssetMap().getAsset(var14);
               if (var15 != null) {
                  int var16 = getBlockId(var1, var2, var3, var4, var5, var6, var9, var10, var11);
                  if (!var13.placesBlockId(var16)) {
                     if (!this.requireEmptyTarget || isEmpty(var16)) {
                        var2.run(var6x -> {
                           ChunkStore var7 = var6x.getExternalData();
                           Ref var8 = var7.getChunkSectionReferenceAtBlock(var9, var10, var11);
                           if (var8 != null && var8.isValid()) {
                              BlockSection var9 = var6x.getComponent(var8, BlockSection.getComponentType());
                              if (var9 != null) {
                                 int var10 = var9.get(ChunkUtil.indexBlock(var9, var10, var11));
                                 if (var10 != var14) {
                                    if (!this.requireEmptyTarget || isEmpty(var10)) {
                                       BlockOperations.setBlock(var7, var8, var9, var10, var11, var14, var15, 0, 0, 0);
                                    }
                                 }
                              }
                           }
                        });
                     }
                  }
               }
            }
         }
      }
   }

   class="kw">private class="kw">static boolean isEmpty(int var0) {
      BlockType var1 = BlockType.getAssetMap().getAsset(var0);
      class="kw">return var1 != null && var1.getMaterial() == BlockMaterial.Empty;
   }

   @Nullable
   class="kw">private PlaceBlockProcedure.PlacementRule findRule(String var1) {
      for (PlaceBlockProcedure.PlacementRule var5 : this.placements) {
         String var6 = var5.state != null ? var5.state : "class="kw">default";
         if (var6.equals(var1)) {
            class="kw">return var5;
         }
      }

      class="kw">return null;
   }

   class="kw">private class="kw">static int getBlockId(
      Store<ChunkStore> var0, CommandBuffer<ChunkStore> var1, BlockSection var2, int var3, int var4, int var5, int var6, int var7, int var8
   ) {
      BlockSection var9 = var2;
      if (!ChunkUtil.isSameChunkSection(var3, var4, var5, var6, var7, var8)) {
         Ref var10 = var0.getExternalData().getChunkSectionReferenceAtBlock(var6, var7, var8);
         if (var10 == null) {
            class="kw">return 0;
         }

         var9 = var1.getComponent(var10, BlockSection.getComponentType());
         if (var9 == null) {
            class="kw">return 0;
         }
      }

      class="kw">return var9.get(ChunkUtil.indexBlock(var6, var7, var8));
   }

   @Override
   class="kw">public String toString() {
      class="kw">return "PlaceBlockProcedure{placements="
         + Arrays.toString(this.placements)
         + ", offset="
         + this.offset
         + ", requireEmptyTarget="
         + this.requireEmptyTarget
         + "}";
   }

   class="kw">public class="kw">static class PlacementRule {
      class="kw">public class="kw">static class="kw">final BuilderCodec<PlaceBlockProcedure.PlacementRule> CODEC = BuilderCodec.builder(
            PlaceBlockProcedure.PlacementRule.class, PlaceBlockProcedure.PlacementRule::new
         )
         .appendInherited(
            new KeyedCodec<>("State", Codec.STRING), (var0, var1) -> var0.state = var1, var0 -> var0.state, (var0, var1) -> var0.state = var1.state
         )
         .documentation(
            "Optional. The ticking block's own state (as defined under State.Definitions) that this rule applies to. If omitted, the rule applies to the block's class="kw">default (stateless) form."
         )
         .add()
         .<String>appendInherited(
            new KeyedCodec<>("Block", Codec.STRING), (var0, var1) -> var0.block = var1, var0 -> var0.block, (var0, var1) -> var0.block = var1.block
         )
         .documentation(
            "The single block id to place at the configured offset when this rule's State is matched. Use this for a fixed block; for a randomised choice use Blocks instead. Exactly one of Block or Blocks must be set."
         )
         .addValidatorLate(() -> BlockType.VALIDATOR_CACHE.getValidator().late())
         .add()
         .<PlaceBlockProcedure.WeightedBlock[]>appendInherited(
            new KeyedCodec<>("Blocks", new ArrayCodec<>(PlaceBlockProcedure.WeightedBlock.CODEC, PlaceBlockProcedure.WeightedBlock[]::new)),
            (var0, var1) -> var0.blocks = var1,
            var0 -> var0.blocks,
            (var0, var1) -> var0.blocks = var1.blocks
         )
         .documentation(
            "A weighted list of candidate blocks to choose from when this rule's State is matched. Each placement randomly selects one entry, with higher Weight values chosen proportionally more often. Exactly one of Block or Blocks must be set."
         )
         .add()
         .validator((var0, var1) -> {
            boolean var2 = var0.block != null;
            boolean var3 = var0.blocks != null && var0.blocks.length > 0;
            if (var2 == var3) {
               var1.fail("A PlacementRule must specify exactly one of 'Block' (a single block) or 'Blocks' (a weighted list).");
            }
         })
         .build();
      class="kw">private String state;
      class="kw">private String block;
      class="kw">private PlaceBlockProcedure.WeightedBlock[] blocks;
      class="kw">private class="kw">transient double totalWeight;

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

      class="kw">public String getState() {
         class="kw">return this.state;
      }

      class="kw">public String getBlock() {
         class="kw">return this.block;
      }

      class="kw">public PlaceBlockProcedure.WeightedBlock[] getBlocks() {
         class="kw">return this.blocks;
      }

      int resolveBlockId(@Nonnull Random var1) {
         if (this.blocks != null && this.blocks.length > 0) {
            PlaceBlockProcedure.WeightedBlock var2 = this.pickWeighted(var1);
            class="kw">return var2 != null ? BlockType.getAssetMap().getIndex(var2.block) : Integer.MIN_VALUE;
         } else {
            class="kw">return this.block != null ? BlockType.getAssetMap().getIndex(this.block) : Integer.MIN_VALUE;
         }
      }

      boolean placesBlockId(int var1) {
         if (var1 == Integer.MIN_VALUE) {
            class="kw">return false;
         }

         BlockTypeAssetMap var2 = BlockType.getAssetMap();
         if (this.blocks != null && this.blocks.length > 0) {
            for (PlaceBlockProcedure.WeightedBlock var6 : this.blocks) {
               if (var2.getIndex(var6.block) == var1) {
                  class="kw">return true;
               }
            }

            class="kw">return false;
         } else {
            class="kw">return this.block != null && var2.getIndex(this.block) == var1;
         }
      }

      @Nullable
      class="kw">private PlaceBlockProcedure.WeightedBlock pickWeighted(@Nonnull Random var1) {
         double var2 = this.totalWeight;
         if (var2 <= 0.0) {
            for (PlaceBlockProcedure.WeightedBlock var7 : this.blocks) {
               var2 += var7.weight;
            }

            this.totalWeight = var2;
         }

         if (var2 <= 0.0) {
            class="kw">return null;
         }

         double var10 = var1.nextDouble() * var2;

         for (PlaceBlockProcedure.WeightedBlock var9 : this.blocks) {
            var10 -= var9.weight;
            if (var10 <= 0.0) {
               class="kw">return var9;
            }
         }

         class="kw">return this.blocks[this.blocks.length - 1];
      }

      @Override
      class="kw">public String toString() {
         class="kw">return "PlacementRule{state='" + this.state + "', block='" + this.block + "', blocks=" + Arrays.toString(this.blocks) + "}";
      }
   }

   class="kw">public class="kw">static class WeightedBlock {
      class="kw">public class="kw">static class="kw">final BuilderCodec<PlaceBlockProcedure.WeightedBlock> CODEC = BuilderCodec.builder(
            PlaceBlockProcedure.WeightedBlock.class, PlaceBlockProcedure.WeightedBlock::new
         )
         .appendInherited(
            new KeyedCodec<>("Block", Codec.STRING), (var0, var1) -> var0.block = var1, var0 -> var0.block, (var0, var1) -> var0.block = var1.block
         )
         .documentation("The block id that may be placed when this option is selected.")
         .addValidatorLate(() -> BlockType.VALIDATOR_CACHE.getValidator().late())
         .addValidator(Validators.nonNull())
         .add()
         .<Double>appendInherited(
            new KeyedCodec<>("Weight", Codec.DOUBLE), (var0, var1) -> var0.weight = var1, var0 -> var0.weight, (var0, var1) -> var0.weight = var1.weight
         )
         .documentation(
            "Optional. The relative selection weight for this block (class="kw">default 1.0). A block with weight 2.0 is twice as likely to be chosen as one with weight 1.0."
         )
         .addValidator(Validators.greaterThan(0.0))
         .add()
         .build();
      class="kw">private String block;
      class="kw">private double weight = 1.0;

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

      class="kw">public String getBlock() {
         class="kw">return this.block;
      }

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

      @Override
      class="kw">public String toString() {
         class="kw">return "WeightedBlock{block='" + this.block + "', weight=" + this.weight + "}";
      }
   }
}