diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/VillagerData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/VillagerData.java
new file mode 100644
index 000000000..dc4e1fa9a
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/VillagerData.java
@@ -0,0 +1,112 @@
+/*
+ * Codename Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.game.datatypes.entities;
+
+import de.bixilon.minosoft.game.datatypes.MapSet;
+import de.bixilon.minosoft.game.datatypes.VersionValueMap;
+import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
+
+public class VillagerData {
+ final int type;
+ final int profession;
+ final int level;
+
+ public VillagerData(int type, int profession, int level) {
+ this.type = type;
+ this.profession = profession;
+ this.level = level;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public int getProfession() {
+ return profession;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public enum VillagerProfessions {
+ NONE(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 0)}),
+ ARMORER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 1)}),
+ BUTCHER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 4), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 2)}),
+ CARTOGRAPHER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 3)}),
+ CLERIC(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 4)}),
+ FARMER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 0), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 5)}),
+ FISHERMAN(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 6)}),
+ FLETCHER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 7)}),
+ LEATHER_WORKER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 8)}),
+ LIBRARIAN(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 1), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 9)}),
+ MASON(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 10)}),
+ NITWIT(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 5), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 11)}),
+ SHEPHERD(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 12)}),
+ TOOL_SMITH(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 13)}),
+ WEAPON_SMITH(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 14)}),
+ PRIEST(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 2), new MapSet<>(ProtocolVersion.VERSION_1_14_4, -1)}),
+ BLACKSMITH(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 3), new MapSet<>(ProtocolVersion.VERSION_1_14_4, -1)}),
+
+ HUSK(new MapSet[]{}); // used earlier (ZombieVillagerMeta)
+
+ final VersionValueMap valueMap;
+
+ VillagerProfessions(MapSet[] values) {
+ valueMap = new VersionValueMap<>(values, true);
+ }
+
+ public static VillagerProfessions byId(int id, ProtocolVersion version) {
+ for (VillagerProfessions profession : values()) {
+ if (profession.getId(version) == id) {
+ return profession;
+ }
+ }
+ return null;
+ }
+
+ public int getId(ProtocolVersion version) {
+ return valueMap.get(version);
+ }
+ }
+
+ public enum VillagerTypes {
+ DESSERT(0),
+ JUNGLE(1),
+ PLAINS(2),
+ SAVANNA(3),
+ SNOW(4),
+ SWAMP(5),
+ TAIGA(6);
+
+ final int id;
+
+ VillagerTypes(int id) {
+ this.id = id;
+ }
+
+ public static VillagerTypes byId(int id) {
+ for (VillagerTypes type : values()) {
+ if (type.getId() == id) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ public int getId() {
+ return id;
+ }
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java
index b16ffcc8c..a6d65e654 100644
--- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java
@@ -14,6 +14,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.*;
import de.bixilon.minosoft.game.datatypes.blocks.Blocks;
+import de.bixilon.minosoft.game.datatypes.entities.VillagerData;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
import de.bixilon.minosoft.util.BitByte;
@@ -109,6 +110,12 @@ public class EntityMetaData {
int blockId = buffer.readVarInt();
data = Blocks.getBlock(blockId, buffer.getVersion());
break;
+ case OPT_VAR_INT:
+ data = buffer.readVarInt() - 1;
+ break;
+ case VILLAGER_DATA:
+ data = new VillagerData(buffer.readVarInt(), buffer.readVarInt(), buffer.readVarInt());
+ break;
default:
throw new IllegalStateException("Unexpected value: " + type);
}
@@ -299,9 +306,9 @@ public class EntityMetaData {
OPT_BLOCK_ID(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_10, 12), new MapSet<>(ProtocolVersion.VERSION_1_13_2, 13)}),
NBT(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_12_2, 13), new MapSet<>(ProtocolVersion.VERSION_1_13_2, 14)}),
PARTICLE(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_13_2, 15)}),
- VILLAGER_DATA(-1),
- OPT_VAR_INT(-1),
- POSE(-1);
+ VILLAGER_DATA(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 16)}),
+ OPT_VAR_INT(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 17)}),
+ POSE(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 18)});
final VersionValueMap valueMap;
diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java
index 8b09e2d2c..7b3ca63d1 100644
--- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java
@@ -12,6 +12,7 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
+import de.bixilon.minosoft.game.datatypes.entities.VillagerData;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
import java.util.HashMap;
@@ -24,7 +25,7 @@ public class HuskMetaData extends ZombieMetaData {
@Override
- public VillagerMetaData.VillagerType getType() {
- return null; // ToDo: husk support
+ public VillagerData.VillagerProfessions getProfession() {
+ return VillagerData.VillagerProfessions.HUSK;
}
}
diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java
index 672e17349..ebab5197f 100644
--- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java
@@ -12,6 +12,7 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
+import de.bixilon.minosoft.game.datatypes.entities.VillagerData;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
import java.util.HashMap;
@@ -23,49 +24,20 @@ public class VillagerMetaData extends AgeableMetaData {
}
- public VillagerType getVillagerType() {
+ public VillagerData.VillagerProfessions getProfession() {
switch (version) {
case VERSION_1_7_10:
case VERSION_1_8:
- return VillagerType.byId((int) sets.get(16).getData());
+ return VillagerData.VillagerProfessions.byId((int) sets.get(16).getData(), version);
case VERSION_1_9_4:
- return VillagerType.byId((int) sets.get(12).getData());
+ return VillagerData.VillagerProfessions.byId((int) sets.get(12).getData(), version);
case VERSION_1_10:
case VERSION_1_11_2:
case VERSION_1_12_2:
case VERSION_1_13_2:
- return VillagerType.byId((int) sets.get(13).getData());
- }
- return VillagerType.FARMER;
- }
-
- public enum VillagerType {
- FARMER(0),
- LIBRARIAN(1),
- PRIEST(2),
- BLACKSMITH(3),
- BUTCHER(4),
- NITWIT(5);
-
-
- final int id;
-
- VillagerType(int id) {
- this.id = id;
- }
-
- public static VillagerType byId(int id) {
- for (VillagerType t : values()) {
- if (t.getId() == id) {
- return t;
- }
- }
- return null;
- }
-
- public int getId() {
- return id;
+ return VillagerData.VillagerProfessions.byId((int) sets.get(13).getData(), version);
}
+ return VillagerData.VillagerProfessions.FARMER;
}
diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java
index 7d9b2b55d..6dff5b192 100644
--- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java
@@ -12,6 +12,7 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
+import de.bixilon.minosoft.game.datatypes.entities.VillagerData;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
import java.util.HashMap;
@@ -39,17 +40,20 @@ public class ZombieMetaData extends MobMetaData {
return false;
}
- public VillagerMetaData.VillagerType getType() {
+ public VillagerData.VillagerProfessions getProfession() {
switch (version) {
case VERSION_1_7_10:
case VERSION_1_8:
- return VillagerMetaData.VillagerType.byId((byte) sets.get(13).getData() - 1);
- case VERSION_1_9_4:
- return VillagerMetaData.VillagerType.byId((int) sets.get(12).getData() - 1);
case VERSION_1_10:
- return VillagerMetaData.VillagerType.byId((int) sets.get(13).getData() - 1);
+ byte set = (byte) sets.get(13).getData();
+ if (version == ProtocolVersion.VERSION_1_10 && set == 6) {
+ return VillagerData.VillagerProfessions.HUSK;
+ }
+ return VillagerData.VillagerProfessions.byId(set - 1, version);
+ case VERSION_1_9_4:
+ return VillagerData.VillagerProfessions.byId((int) sets.get(12).getData() - 1, version);
}
- return null; // ToDo: Husk support
+ return VillagerData.VillagerProfessions.NONE;
}
public boolean isConverting() {
diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java
index f9a0c3a75..f82dcc5a0 100644
--- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java
@@ -12,6 +12,7 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
+import de.bixilon.minosoft.game.datatypes.entities.VillagerData;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
import java.util.HashMap;
@@ -23,15 +24,16 @@ public class ZombieVillagerMetaData extends ZombieMetaData {
}
@Override
- public VillagerMetaData.VillagerType getType() {
+ public VillagerData.VillagerProfessions getProfession() {
switch (version) {
case VERSION_1_11_2:
case VERSION_1_12_2:
- return VillagerMetaData.VillagerType.byId((int) sets.get(16).getData() + 1);
+ return VillagerData.VillagerProfessions.byId((int) sets.get(16).getData(), version);
case VERSION_1_13_2:
- return VillagerMetaData.VillagerType.byId((int) sets.get(17).getData() + 1);
+ return VillagerData.VillagerProfessions.byId((int) sets.get(17).getData(), version);
+ default:
+ return super.getProfession();
}
- return VillagerMetaData.VillagerType.FARMER;
}
@Override
@@ -42,8 +44,8 @@ public class ZombieVillagerMetaData extends ZombieMetaData {
return ((boolean) sets.get(15).getData());
case VERSION_1_13_2:
return ((boolean) sets.get(16).getData());
-
+ default:
+ return super.isConverting();
}
- return false;
}
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java
index 05620b307..0af0151d6 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java
@@ -62,7 +62,7 @@ public class PacketEntityTeleport implements ClientboundPacket {
@Override
public void log() {
- Log.protocol(String.format("Entity %d moved to %s (yaw=%s, pitch=%s", entityId, location.toString(), yaw, pitch));
+ Log.protocol(String.format("Entity %d moved to %s (yaw=%s, pitch=%s)", entityId, location.toString(), yaw, pitch));
}
public int getEntityId() {
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java
index 0101fcbc6..0b54a3e9d 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java
@@ -109,7 +109,7 @@ public class PacketMapData implements ClientboundPacket {
mapId = buffer.readVarInt();
scale = buffer.readByte();
boolean trackPosition = buffer.readBoolean();
- if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_12_2.getVersionNumber()) {
+ if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_14_4.getVersionNumber()) {
locked = buffer.readBoolean();
}
int pinCount = buffer.readVarInt();
diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java
index 8dfcff91e..c052728b4 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java
@@ -376,7 +376,8 @@ public class InByteBuffer {
break;
}
case VERSION_1_12_2:
- case VERSION_1_13_2: {
+ case VERSION_1_13_2:
+ case VERSION_1_14_4: {
byte index = readByte();
while (index != (byte) 0xFF) {
EntityMetaData.Types type = EntityMetaData.Types.byId(readVarInt(), version);