Skip to content

Commit cbc99e5

Browse files
authored
Merge pull request CloudburstMC#1085 from PowerNukkit/v1.4/cauldron/fixes
Fix Incorrect dye names and block colors. Improves color mixing
2 parents bb574ba + 32b960e commit cbc99e5

File tree

4 files changed

+173
-56
lines changed

4 files changed

+173
-56
lines changed

src/main/java/cn/nukkit/block/BlockCauldron.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ public boolean onActivate(@Nonnull Item item, Player player) {
149149
cauldronLava.setFillLevel(3);
150150
this.level.setBlock(this, cauldronLava, true, true);
151151
cauldron.clearCustomColor();
152+
cauldron.setType(BlockEntityCauldron.PotionType.LAVA);
152153
this.getLevel().addSound(this.add(0.5, 1, 0.5), Sound.BUCKET_EMPTY_LAVA);
153154
} else {
154155
clearWithFizz(cauldron);
@@ -168,15 +169,15 @@ public boolean onActivate(@Nonnull Item item, Player player) {
168169
player.getInventory().setItemInHand(item);
169170
}
170171

171-
BlockColor color = new ItemDye(item.getDamage()).getDyeColor().getColor();
172+
BlockColor color = new ItemDye(item.getDamage()).getDyeColor().getLeatherColor();
172173
if (!cauldron.isCustomColor()) {
173174
cauldron.setCustomColor(color);
174175
} else {
175176
BlockColor current = cauldron.getCustomColor();
176177
BlockColor mixed = new BlockColor(
177-
current.getRed() + (color.getRed() - current.getRed()) / 2,
178-
current.getGreen() + (color.getGreen() - current.getGreen()) / 2,
179-
current.getBlue() + (color.getBlue() - current.getBlue()) / 2
178+
(int)Math.round(Math.sqrt(color.getRed() * current.getRed()) * 0.965),
179+
(int)Math.round(Math.sqrt(color.getGreen() * current.getGreen()) * 0.965),
180+
(int)Math.round(Math.sqrt(color.getBlue() * current.getBlue()) * 0.965)
180181
);
181182
cauldron.setCustomColor(mixed);
182183
}
@@ -279,7 +280,7 @@ public boolean onActivate(@Nonnull Item item, Player player) {
279280

280281
setFillLevel(getFillLevel() - 1);
281282
if (isEmpty()) {
282-
cauldron.setPotionId(0xffff);//reset potion
283+
cauldron.setPotionId(-1);//reset potion
283284
cauldron.clearCustomColor();
284285
}
285286
this.level.setBlock(this, this, true);
@@ -402,7 +403,7 @@ private void consumePotion(Item item, Player player) {
402403

403404
public void clearWithFizz(BlockEntityCauldron cauldron) {
404405
this.setFillLevel(0);//empty
405-
cauldron.setPotionId(0xffff);//reset potion
406+
cauldron.setPotionId(-1);//reset potion
406407
cauldron.setSplashPotion(false);
407408
cauldron.clearCustomColor();
408409
this.level.setBlock(this, new BlockCauldron(0), true);
@@ -415,7 +416,7 @@ public void clearWithFizz(BlockEntityCauldron cauldron) {
415416
@Override
416417
public boolean place(@Nonnull Item item, @Nonnull Block block, @Nonnull Block target, @Nonnull BlockFace face, double fx, double fy, double fz, Player player) {
417418
CompoundTag nbt = new CompoundTag()
418-
.putShort("PotionId", 0xffff)
419+
.putShort("PotionId", -1)
419420
.putByte("SplashPotion", 0);
420421

421422
if (item.hasCustomBlockData()) {

src/main/java/cn/nukkit/blockentity/BlockEntityCauldron.java

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,49 @@
11
package cn.nukkit.blockentity;
22

33
import cn.nukkit.Player;
4+
import cn.nukkit.Server;
5+
import cn.nukkit.api.DeprecationDetails;
6+
import cn.nukkit.api.PowerNukkitDifference;
7+
import cn.nukkit.api.PowerNukkitOnly;
8+
import cn.nukkit.api.Since;
49
import cn.nukkit.block.Block;
5-
import cn.nukkit.level.GlobalBlockPalette;
10+
import cn.nukkit.block.BlockCauldron;
11+
import cn.nukkit.level.Location;
612
import cn.nukkit.level.format.FullChunk;
13+
import cn.nukkit.math.Vector3;
714
import cn.nukkit.nbt.tag.CompoundTag;
8-
import cn.nukkit.network.protocol.UpdateBlockPacket;
15+
import cn.nukkit.nbt.tag.ListTag;
916
import cn.nukkit.utils.BlockColor;
17+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
18+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
19+
import lombok.RequiredArgsConstructor;
20+
21+
import javax.annotation.Nonnull;
1022

1123
/**
1224
* @author CreeperFace (Nukkit Project)
1325
*/
1426
public class BlockEntityCauldron extends BlockEntitySpawnable {
15-
16-
public static final int POTION_TYPE_EMPTY = 0xFFFF;
27+
28+
@PowerNukkitDifference(since = "1.4.0.0-PN", info = "Using -1 instead of the overflown 0xFFFF")
29+
@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
30+
reason = "Magic value", replaceWith = "PotionType")
31+
public static final int POTION_TYPE_EMPTY = -1;
32+
33+
@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
34+
reason = "Magic value", replaceWith = "PotionType")
1735
public static final int POTION_TYPE_NORMAL = 0;
36+
37+
@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
38+
reason = "Magic value", replaceWith = "PotionType")
1839
public static final int POTION_TYPE_SPLASH = 1;
40+
41+
@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
42+
reason = "Magic value", replaceWith = "PotionType")
1943
public static final int POTION_TYPE_LINGERING = 2;
44+
45+
@Deprecated @DeprecationDetails(by = "PowerNukkit", since = "1.4.0.0-PN",
46+
reason = "Magic value", replaceWith = "PotionType")
2047
public static final int POTION_TYPE_LAVA = 0xF19B;
2148

2249
public BlockEntityCauldron(FullChunk chunk, CompoundTag nbt) {
@@ -55,15 +82,27 @@ public void setPotionId(int potionId) {
5582
}
5683

5784
public boolean hasPotion() {
58-
return getPotionId() != 0xffff;
85+
return (getPotionId() & 0xffff) != 0xffff;
5986
}
6087

6188
public void setPotionType(int potionType) {
62-
this.namedTag.putShort("PotionType", potionType & 0xFFFF);
89+
this.namedTag.putShort("PotionType", (short)(potionType & 0xFFFF));
6390
}
6491

6592
public int getPotionType() {
66-
return this.namedTag.getShort("PotionType") & 0xFFFF;
93+
return (short)(this.namedTag.getShort("PotionType") & 0xFFFF);
94+
}
95+
96+
@PowerNukkitOnly
97+
@Since("1.4.0.0-PN")
98+
public PotionType getType() {
99+
return PotionType.getByTypeData(getPotionType());
100+
}
101+
102+
@PowerNukkitOnly
103+
@Since("1.4.0.0-PN")
104+
public void setType(PotionType type) {
105+
setPotionType(type.potionTypeData);
67106
}
68107

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

106145
namedTag.putInt("CustomColor", color);
107-
108-
Block block = getBlock();
109-
Player[] viewers = this.level.getChunkPlayers(getChunkX(), getChunkZ()).values().toArray(Player.EMPTY_ARRAY);
110-
UpdateBlockPacket air = new UpdateBlockPacket();
111-
air.blockRuntimeId = GlobalBlockPalette.getOrCreateRuntimeId(0, 0);
112-
air.flags = UpdateBlockPacket.FLAG_ALL_PRIORITY;
113-
air.x = (int) x;
114-
air.y = (int) y;
115-
air.z = (int) z;
116-
UpdateBlockPacket self = (UpdateBlockPacket) air.clone();
117-
self.blockRuntimeId = GlobalBlockPalette.getOrCreateRuntimeId(block.getId(), block.getDamage());
118-
for (Player viewer : viewers) {
119-
viewer.dataPacket(air);
120-
viewer.dataPacket(self);
121-
}
122-
146+
123147
spawnToAll();
124148
}
125149

@@ -128,6 +152,24 @@ public void clearCustomColor() {
128152
spawnToAll();
129153
}
130154

155+
@Override
156+
public void spawnToAll() {
157+
BlockCauldron block = (BlockCauldron) getBlock();
158+
Player[] viewers = this.level.getChunkPlayers(getChunkX(), getChunkZ()).values().toArray(Player.EMPTY_ARRAY);
159+
this.level.sendBlocks(viewers, new Vector3[]{block});
160+
super.spawnToAll();
161+
Location location = getLocation();
162+
Server.getInstance().getScheduler().scheduleTask(null, ()-> {
163+
if (isValid()) {
164+
BlockEntity cauldron = this.level.getBlockEntity(location);
165+
if (cauldron == BlockEntityCauldron.this) {
166+
this.level.sendBlocks(viewers, new Vector3[]{location});
167+
super.spawnToAll();
168+
}
169+
}
170+
});
171+
}
172+
131173
@Override
132174
public boolean isBlockEntityValid() {
133175
int id = getBlock().getId();
@@ -141,11 +183,41 @@ public CompoundTag getSpawnCompound() {
141183
.putInt("x", (int) this.x)
142184
.putInt("y", (int) this.y)
143185
.putInt("z", (int) this.z)
144-
.putShort("PotionId", namedTag.getShort("PotionId"))
145-
.putByte("PotionType", namedTag.getShort("PotionType"));
186+
.putBoolean("isMovable", isMovable())
187+
.putList(new ListTag<>("Items"))
188+
.putShort("PotionId", (short) namedTag.getShort("PotionId"))
189+
.putShort("PotionType", (short) namedTag.getShort("PotionType"));
146190
if (namedTag.contains("CustomColor")) {
147-
compoundTag.putInt("CustomColor", namedTag.getInt("CustomColor"));
191+
compoundTag.putInt("CustomColor", namedTag.getInt("CustomColor") << 8 >> 8);
148192
}
149193
return compoundTag;
150194
}
195+
196+
@PowerNukkitOnly
197+
@Since("1.4.0.0-PN")
198+
@RequiredArgsConstructor
199+
public enum PotionType {
200+
EMPTY(POTION_TYPE_EMPTY),
201+
NORMAL(POTION_TYPE_NORMAL),
202+
SPLASH(POTION_TYPE_SPLASH),
203+
LINGERING(POTION_TYPE_LINGERING),
204+
LAVA(POTION_TYPE_LAVA),
205+
UNKNOWN(-2);
206+
private final int potionTypeData;
207+
private static final Int2ObjectMap<PotionType> BY_DATA;
208+
static {
209+
PotionType[] types = values();
210+
BY_DATA = new Int2ObjectOpenHashMap<>(types.length);
211+
for (PotionType type : types) {
212+
BY_DATA.put(type.potionTypeData, type);
213+
}
214+
}
215+
216+
@PowerNukkitOnly
217+
@Since("1.4.0.0-PN")
218+
@Nonnull
219+
public static PotionType getByTypeData(int typeData) {
220+
return BY_DATA.getOrDefault(typeData, PotionType.UNKNOWN);
221+
}
222+
}
151223
}

src/main/java/cn/nukkit/item/ItemDye.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public ItemDye(DyeColor dyeColor, int amount) {
6262
}
6363

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

6767
if (this.meta == DyeColor.BROWN.getDyeData()) {
6868
this.block = Block.get(BlockID.COCOA_BLOCK);

src/main/java/cn/nukkit/utils/DyeColor.java

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,95 @@
11
package cn.nukkit.utils;
22

3+
import cn.nukkit.api.PowerNukkitDifference;
4+
import cn.nukkit.api.PowerNukkitOnly;
5+
import cn.nukkit.api.Since;
6+
import cn.nukkit.math.MathHelper;
7+
8+
import java.util.Arrays;
9+
310
public enum DyeColor {
411

512

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

2330

2431
private int dyeColorMeta;
32+
private int itemDyeMeta;
2533
private int woolColorMeta;
2634
private String colorName;
2735
private String dyeName;
2836
private BlockColor blockColor;
37+
private BlockColor leatherColor;
2938

3039

3140
private final static DyeColor[] BY_WOOL_DATA;
3241
private final static DyeColor[] BY_DYE_DATA;
3342

34-
DyeColor(int dyeColorMeta, int woolColorMeta, String colorName, BlockColor blockColor) {
35-
this(dyeColorMeta, woolColorMeta, colorName, colorName + " Dye", blockColor);
43+
DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, BlockColor blockColor) {
44+
this(dyeColorMeta, woolColorMeta, itemDyeMeta, colorName, blockColor, blockColor);
45+
}
46+
47+
DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, BlockColor blockColor, BlockColor leatherColor) {
48+
this(dyeColorMeta, woolColorMeta, itemDyeMeta, colorName, colorName + " Dye", blockColor, leatherColor);
49+
}
50+
51+
DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, String dyeName, BlockColor blockColor) {
52+
this(dyeColorMeta, woolColorMeta, itemDyeMeta, colorName, blockColor, blockColor);
3653
}
3754

38-
DyeColor(int dyeColorMeta, int woolColorMeta, String colorName, String dyeName, BlockColor blockColor) {
55+
DyeColor(int dyeColorMeta, int woolColorMeta, int itemDyeMeta, String colorName, String dyeName, BlockColor blockColor, BlockColor leatherColor) {
3956
this.dyeColorMeta = dyeColorMeta;
4057
this.woolColorMeta = woolColorMeta;
58+
this.itemDyeMeta = itemDyeMeta;
4159
this.colorName = colorName;
4260
this.blockColor = blockColor;
4361
this.dyeName = dyeName;
62+
this.leatherColor = leatherColor;
4463
}
4564

4665
public BlockColor getColor() {
4766
return this.blockColor;
4867
}
4968

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

77+
/**
78+
* The {@code minecraft:dye} meta that actually represents the item dye for that color.
79+
* Uses black_dye instead of ink_sac, white_dye instead of bone_meal, and so on.
80+
*/
81+
@PowerNukkitOnly
82+
@Since("1.4.0.0-PN")
83+
public int getItemDyeMeta() {
84+
return itemDyeMeta;
85+
}
86+
87+
@PowerNukkitOnly
88+
@Since("1.4.0.0-PN")
89+
public BlockColor getLeatherColor() {
90+
return leatherColor;
91+
}
92+
5493
public int getWoolData() {
5594
return this.woolColorMeta;
5695
}
@@ -64,17 +103,22 @@ public String getDyeName() {
64103
}
65104

66105
static {
67-
BY_DYE_DATA = values();
68106
BY_WOOL_DATA = values();
107+
BY_DYE_DATA = new DyeColor[Arrays.stream(BY_WOOL_DATA).mapToInt(DyeColor::getItemDyeMeta).max().orElse(0) + 1];
108+
109+
for (DyeColor dyeColor : BY_WOOL_DATA) {
110+
BY_DYE_DATA[dyeColor.dyeColorMeta] = dyeColor;
111+
BY_DYE_DATA[dyeColor.itemDyeMeta] = dyeColor;
112+
}
69113

70114
for (DyeColor color : values()) {
71115
BY_WOOL_DATA[color.woolColorMeta & 0x0f] = color;
72-
BY_DYE_DATA[color.dyeColorMeta & 0x0f] = color;
73116
}
74117
}
75118

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

80124
public static DyeColor getByWoolData(int woolColorMeta) {

0 commit comments

Comments
 (0)