Skip to content

Commit

Permalink
Merge pull request CloudburstMC#1085 from PowerNukkit/v1.4/cauldron/f…
Browse files Browse the repository at this point in the history
…ixes

Fix Incorrect dye names and block colors. Improves color mixing
  • Loading branch information
joserobjr authored May 26, 2021
2 parents bb574ba + 32b960e commit cbc99e5
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 56 deletions.
15 changes: 8 additions & 7 deletions src/main/java/cn/nukkit/block/BlockCauldron.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public boolean onActivate(@Nonnull Item item, Player player) {
cauldronLava.setFillLevel(3);
this.level.setBlock(this, cauldronLava, true, true);
cauldron.clearCustomColor();
cauldron.setType(BlockEntityCauldron.PotionType.LAVA);
this.getLevel().addSound(this.add(0.5, 1, 0.5), Sound.BUCKET_EMPTY_LAVA);
} else {
clearWithFizz(cauldron);
Expand All @@ -168,15 +169,15 @@ public boolean onActivate(@Nonnull Item item, Player player) {
player.getInventory().setItemInHand(item);
}

BlockColor color = new ItemDye(item.getDamage()).getDyeColor().getColor();
BlockColor color = new ItemDye(item.getDamage()).getDyeColor().getLeatherColor();
if (!cauldron.isCustomColor()) {
cauldron.setCustomColor(color);
} else {
BlockColor current = cauldron.getCustomColor();
BlockColor mixed = new BlockColor(
current.getRed() + (color.getRed() - current.getRed()) / 2,
current.getGreen() + (color.getGreen() - current.getGreen()) / 2,
current.getBlue() + (color.getBlue() - current.getBlue()) / 2
(int)Math.round(Math.sqrt(color.getRed() * current.getRed()) * 0.965),
(int)Math.round(Math.sqrt(color.getGreen() * current.getGreen()) * 0.965),
(int)Math.round(Math.sqrt(color.getBlue() * current.getBlue()) * 0.965)
);
cauldron.setCustomColor(mixed);
}
Expand Down Expand Up @@ -279,7 +280,7 @@ public boolean onActivate(@Nonnull Item item, Player player) {

setFillLevel(getFillLevel() - 1);
if (isEmpty()) {
cauldron.setPotionId(0xffff);//reset potion
cauldron.setPotionId(-1);//reset potion
cauldron.clearCustomColor();
}
this.level.setBlock(this, this, true);
Expand Down Expand Up @@ -402,7 +403,7 @@ private void consumePotion(Item item, Player player) {

public void clearWithFizz(BlockEntityCauldron cauldron) {
this.setFillLevel(0);//empty
cauldron.setPotionId(0xffff);//reset potion
cauldron.setPotionId(-1);//reset potion
cauldron.setSplashPotion(false);
cauldron.clearCustomColor();
this.level.setBlock(this, new BlockCauldron(0), true);
Expand All @@ -415,7 +416,7 @@ public void clearWithFizz(BlockEntityCauldron cauldron) {
@Override
public boolean place(@Nonnull Item item, @Nonnull Block block, @Nonnull Block target, @Nonnull BlockFace face, double fx, double fy, double fz, Player player) {
CompoundTag nbt = new CompoundTag()
.putShort("PotionId", 0xffff)
.putShort("PotionId", -1)
.putByte("SplashPotion", 0);

if (item.hasCustomBlockData()) {
Expand Down
124 changes: 98 additions & 26 deletions src/main/java/cn/nukkit/blockentity/BlockEntityCauldron.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,49 @@
package cn.nukkit.blockentity;

import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.api.DeprecationDetails;
import cn.nukkit.api.PowerNukkitDifference;
import cn.nukkit.api.PowerNukkitOnly;
import cn.nukkit.api.Since;
import cn.nukkit.block.Block;
import cn.nukkit.level.GlobalBlockPalette;
import cn.nukkit.block.BlockCauldron;
import cn.nukkit.level.Location;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.UpdateBlockPacket;
import cn.nukkit.nbt.tag.ListTag;
import cn.nukkit.utils.BlockColor;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.RequiredArgsConstructor;

import javax.annotation.Nonnull;

/**
* @author CreeperFace (Nukkit Project)
*/
public class BlockEntityCauldron extends BlockEntitySpawnable {

public static final int POTION_TYPE_EMPTY = 0xFFFF;

@PowerNukkitDifference(since = "1.4.0.0-PN", info = "Using -1 instead of the overflown 0xFFFF")
@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
reason = "Magic value", replaceWith = "PotionType")
public static final int POTION_TYPE_EMPTY = -1;

@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
reason = "Magic value", replaceWith = "PotionType")
public static final int POTION_TYPE_NORMAL = 0;

@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
reason = "Magic value", replaceWith = "PotionType")
public static final int POTION_TYPE_SPLASH = 1;

@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
reason = "Magic value", replaceWith = "PotionType")
public static final int POTION_TYPE_LINGERING = 2;

@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
reason = "Magic value", replaceWith = "PotionType")
public static final int POTION_TYPE_LAVA = 0xF19B;

public BlockEntityCauldron(FullChunk chunk, CompoundTag nbt) {
Expand Down Expand Up @@ -55,15 +82,27 @@ public void setPotionId(int potionId) {
}

public boolean hasPotion() {
return getPotionId() != 0xffff;
return (getPotionId() & 0xffff) != 0xffff;
}

public void setPotionType(int potionType) {
this.namedTag.putShort("PotionType", potionType & 0xFFFF);
this.namedTag.putShort("PotionType", (short)(potionType & 0xFFFF));
}

public int getPotionType() {
return this.namedTag.getShort("PotionType") & 0xFFFF;
return (short)(this.namedTag.getShort("PotionType") & 0xFFFF);
}

@PowerNukkitOnly
@Since("1.4.0.0-PN")
public PotionType getType() {
return PotionType.getByTypeData(getPotionType());
}

@PowerNukkitOnly
@Since("1.4.0.0-PN")
public void setType(PotionType type) {
setPotionType(type.potionTypeData);
}

public boolean isSplashPotion() {
Expand Down Expand Up @@ -104,22 +143,7 @@ public void setCustomColor(int r, int g, int b) {
int color = (r << 16 | g << 8 | b) & 0xffffff;

namedTag.putInt("CustomColor", color);

Block block = getBlock();
Player[] viewers = this.level.getChunkPlayers(getChunkX(), getChunkZ()).values().toArray(Player.EMPTY_ARRAY);
UpdateBlockPacket air = new UpdateBlockPacket();
air.blockRuntimeId = GlobalBlockPalette.getOrCreateRuntimeId(0, 0);
air.flags = UpdateBlockPacket.FLAG_ALL_PRIORITY;
air.x = (int) x;
air.y = (int) y;
air.z = (int) z;
UpdateBlockPacket self = (UpdateBlockPacket) air.clone();
self.blockRuntimeId = GlobalBlockPalette.getOrCreateRuntimeId(block.getId(), block.getDamage());
for (Player viewer : viewers) {
viewer.dataPacket(air);
viewer.dataPacket(self);
}


spawnToAll();
}

Expand All @@ -128,6 +152,24 @@ public void clearCustomColor() {
spawnToAll();
}

@Override
public void spawnToAll() {
BlockCauldron block = (BlockCauldron) getBlock();
Player[] viewers = this.level.getChunkPlayers(getChunkX(), getChunkZ()).values().toArray(Player.EMPTY_ARRAY);
this.level.sendBlocks(viewers, new Vector3[]{block});
super.spawnToAll();
Location location = getLocation();
Server.getInstance().getScheduler().scheduleTask(null, ()-> {
if (isValid()) {
BlockEntity cauldron = this.level.getBlockEntity(location);
if (cauldron == BlockEntityCauldron.this) {
this.level.sendBlocks(viewers, new Vector3[]{location});
super.spawnToAll();
}
}
});
}

@Override
public boolean isBlockEntityValid() {
int id = getBlock().getId();
Expand All @@ -141,11 +183,41 @@ public CompoundTag getSpawnCompound() {
.putInt("x", (int) this.x)
.putInt("y", (int) this.y)
.putInt("z", (int) this.z)
.putShort("PotionId", namedTag.getShort("PotionId"))
.putByte("PotionType", namedTag.getShort("PotionType"));
.putBoolean("isMovable", isMovable())
.putList(new ListTag<>("Items"))
.putShort("PotionId", (short) namedTag.getShort("PotionId"))
.putShort("PotionType", (short) namedTag.getShort("PotionType"));
if (namedTag.contains("CustomColor")) {
compoundTag.putInt("CustomColor", namedTag.getInt("CustomColor"));
compoundTag.putInt("CustomColor", namedTag.getInt("CustomColor") << 8 >> 8);
}
return compoundTag;
}

@PowerNukkitOnly
@Since("1.4.0.0-PN")
@RequiredArgsConstructor
public enum PotionType {
EMPTY(POTION_TYPE_EMPTY),
NORMAL(POTION_TYPE_NORMAL),
SPLASH(POTION_TYPE_SPLASH),
LINGERING(POTION_TYPE_LINGERING),
LAVA(POTION_TYPE_LAVA),
UNKNOWN(-2);
private final int potionTypeData;
private static final Int2ObjectMap<PotionType> BY_DATA;
static {
PotionType[] types = values();
BY_DATA = new Int2ObjectOpenHashMap<>(types.length);
for (PotionType type : types) {
BY_DATA.put(type.potionTypeData, type);
}
}

@PowerNukkitOnly
@Since("1.4.0.0-PN")
@Nonnull
public static PotionType getByTypeData(int typeData) {
return BY_DATA.getOrDefault(typeData, PotionType.UNKNOWN);
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/cn/nukkit/item/ItemDye.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public ItemDye(DyeColor dyeColor, int amount) {
}

public ItemDye(Integer meta, int amount) {
super(DYE, meta, amount, meta < 15? DyeColor.getByDyeData(meta).getDyeName() : DyeColor.getByDyeData(meta).getName() + " Dye");
super(DYE, meta, amount, meta <= 15? DyeColor.getByDyeData(meta).getDyeName() : DyeColor.getByDyeData(meta).getName() + " Dye");

if (this.meta == DyeColor.BROWN.getDyeData()) {
this.block = Block.get(BlockID.COCOA_BLOCK);
Expand Down
88 changes: 66 additions & 22 deletions src/main/java/cn/nukkit/utils/DyeColor.java
Original file line number Diff line number Diff line change
@@ -1,56 +1,95 @@
package cn.nukkit.utils;

import cn.nukkit.api.PowerNukkitDifference;
import cn.nukkit.api.PowerNukkitOnly;
import cn.nukkit.api.Since;
import cn.nukkit.math.MathHelper;

import java.util.Arrays;

public enum DyeColor {


BLACK(0, 15, "Black", "Ink Sack", BlockColor.BLACK_BLOCK_COLOR),
RED(1, 14, "Red", "Rose Red", BlockColor.RED_BLOCK_COLOR),
GREEN(2, 13, "Green", "Cactus Green", BlockColor.GREEN_BLOCK_COLOR),
BROWN(3, 12, "Brown", "Cocoa Beans", BlockColor.BROWN_BLOCK_COLOR),
BLUE(4, 11, "Blue", "Lapis Lazuli", BlockColor.BLUE_BLOCK_COLOR),
PURPLE(5, 10, "Purple", BlockColor.PURPLE_BLOCK_COLOR),
CYAN(6, 9, "Cyan", BlockColor.CYAN_BLOCK_COLOR),
LIGHT_GRAY(7, 8, "Light Gray", BlockColor.LIGHT_GRAY_BLOCK_COLOR),
GRAY(8, 7, "Gray", BlockColor.GRAY_BLOCK_COLOR),
PINK(9, 6, "Pink", BlockColor.PINK_BLOCK_COLOR),
LIME(10, 5, "Lime", BlockColor.LIME_BLOCK_COLOR),
YELLOW(11, 4, "Yellow", "Dandelion Yellow", BlockColor.YELLOW_BLOCK_COLOR),
LIGHT_BLUE(12, 3, "Light Blue", BlockColor.LIGHT_BLUE_BLOCK_COLOR),
MAGENTA(13, 2, "Magenta", BlockColor.MAGENTA_BLOCK_COLOR),
ORANGE(14, 1, "Orange", BlockColor.ORANGE_BLOCK_COLOR),
WHITE(15, 0, "White", "Bone Meal", BlockColor.WHITE_BLOCK_COLOR);
BLACK(0, 15, 16, "Black", "Ink Sack", BlockColor.BLACK_BLOCK_COLOR, new BlockColor(0x1D1D21)),
RED(1, 14, 1, "Red", "Rose Red", BlockColor.RED_BLOCK_COLOR, new BlockColor(0xB02E26)),
GREEN(2, 13, 2, "Green", "Cactus Green", BlockColor.GREEN_BLOCK_COLOR, new BlockColor(0x5E7C16)),
BROWN(3, 12, 17, "Brown", "Cocoa Beans", BlockColor.BROWN_BLOCK_COLOR, new BlockColor(0x835432)),
BLUE(4, 11, 18, "Blue", "Lapis Lazuli", BlockColor.BLUE_BLOCK_COLOR, new BlockColor(0x3C44AA)),
PURPLE(5, 10, 5, "Purple", BlockColor.PURPLE_BLOCK_COLOR, new BlockColor(0x8932B8)),
CYAN(6, 9, 6, "Cyan", BlockColor.CYAN_BLOCK_COLOR, new BlockColor(0x169C9C)),
LIGHT_GRAY(7, 8, 7, "Light Gray", BlockColor.LIGHT_GRAY_BLOCK_COLOR, new BlockColor(0x9D9D97)),
GRAY(8, 7, 8, "Gray", BlockColor.GRAY_BLOCK_COLOR, new BlockColor(0x474F52)),
PINK(9, 6, 9, "Pink", BlockColor.PINK_BLOCK_COLOR, new BlockColor(0xF38BAA)),
LIME(10, 5, 10, "Lime", BlockColor.LIME_BLOCK_COLOR, new BlockColor(0x80C71F)),
YELLOW(11, 4, 11, "Yellow", "Dandelion Yellow", BlockColor.YELLOW_BLOCK_COLOR, new BlockColor(0xFED83D)),
LIGHT_BLUE(12, 3, 12, "Light Blue", BlockColor.LIGHT_BLUE_BLOCK_COLOR, new BlockColor(0x3AB3DA)),
MAGENTA(13, 2, 13, "Magenta", BlockColor.MAGENTA_BLOCK_COLOR, new BlockColor(0xC74EBD)),
ORANGE(14, 1, 14, "Orange", BlockColor.ORANGE_BLOCK_COLOR, new BlockColor(0xFF9801)),
WHITE(15, 0, 19, "White", "Bone Meal", BlockColor.WHITE_BLOCK_COLOR, new BlockColor(0xF0F0F0));


private int dyeColorMeta;
private int itemDyeMeta;
private int woolColorMeta;
private String colorName;
private String dyeName;
private BlockColor blockColor;
private BlockColor leatherColor;


private final static DyeColor[] BY_WOOL_DATA;
private final static DyeColor[] BY_DYE_DATA;

DyeColor(int dyeColorMeta, int woolColorMeta, String colorName, BlockColor blockColor) {
this(dyeColorMeta, woolColorMeta, colorName, colorName + " Dye", blockColor);
DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, BlockColor blockColor) {
this(dyeColorMeta, woolColorMeta, itemDyeMeta, colorName, blockColor, blockColor);
}

DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, BlockColor blockColor, BlockColor leatherColor) {
this(dyeColorMeta, woolColorMeta, itemDyeMeta, colorName, colorName + " Dye", blockColor, leatherColor);
}

DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, String dyeName, BlockColor blockColor) {
this(dyeColorMeta, woolColorMeta, itemDyeMeta, colorName, blockColor, blockColor);
}

DyeColor(int dyeColorMeta, int woolColorMeta, String colorName, String dyeName, BlockColor blockColor) {
DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, String dyeName, BlockColor blockColor, BlockColor leatherColor) {
this.dyeColorMeta = dyeColorMeta;
this.woolColorMeta = woolColorMeta;
this.itemDyeMeta = itemDyeMeta;
this.colorName = colorName;
this.blockColor = blockColor;
this.dyeName = dyeName;
this.leatherColor = leatherColor;
}

public BlockColor getColor() {
return this.blockColor;
}

/**
* The {@code minecraft:dye} meta from `0-15` that represents the source of a dye. Includes
* ink_sac, bone_meal, cocoa_beans, and lapis_lazuli.
*/
public int getDyeData() {
return this.dyeColorMeta;
}

/**
* The {@code minecraft:dye} meta that actually represents the item dye for that color.
* Uses black_dye instead of ink_sac, white_dye instead of bone_meal, and so on.
*/
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public int getItemDyeMeta() {
return itemDyeMeta;
}

@PowerNukkitOnly
@Since("1.4.0.0-PN")
public BlockColor getLeatherColor() {
return leatherColor;
}

public int getWoolData() {
return this.woolColorMeta;
}
Expand All @@ -64,17 +103,22 @@ public String getDyeName() {
}

static {
BY_DYE_DATA = values();
BY_WOOL_DATA = values();
BY_DYE_DATA = new DyeColor[Arrays.stream(BY_WOOL_DATA).mapToInt(DyeColor::getItemDyeMeta).max().orElse(0) + 1];

for (DyeColor dyeColor : BY_WOOL_DATA) {
BY_DYE_DATA[dyeColor.dyeColorMeta] = dyeColor;
BY_DYE_DATA[dyeColor.itemDyeMeta] = dyeColor;
}

for (DyeColor color : values()) {
BY_WOOL_DATA[color.woolColorMeta & 0x0f] = color;
BY_DYE_DATA[color.dyeColorMeta & 0x0f] = color;
}
}

@PowerNukkitDifference(since = "1.4.0.0-PN", info = "When overflowed, instead of wrapping, the meta will be clamped, accepts the new dye metas")
public static DyeColor getByDyeData(int dyeColorMeta) {
return BY_DYE_DATA[dyeColorMeta & 0x0f];
return BY_DYE_DATA[MathHelper.clamp(dyeColorMeta, 0, BY_DYE_DATA.length - 1)];
}

public static DyeColor getByWoolData(int woolColorMeta) {
Expand Down

0 comments on commit cbc99e5

Please sign in to comment.