summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Blocks/BlockEnchantmentTable.h37
-rw-r--r--src/Blocks/BlockHandler.cpp2
-rw-r--r--src/ClientHandle.cpp683
-rw-r--r--src/ClientHandle.h6
-rw-r--r--src/Enchantments.h7
-rw-r--r--src/FastRandom.cpp10
-rw-r--r--src/FastRandom.h3
-rw-r--r--src/Protocol/Protocol125.cpp18
-rw-r--r--src/Protocol/Protocol125.h1
-rw-r--r--src/Protocol/Protocol17x.cpp16
-rw-r--r--src/Protocol/Protocol17x.h1
-rw-r--r--src/UI/SlotArea.cpp118
-rw-r--r--src/UI/SlotArea.h28
-rw-r--r--src/UI/Window.cpp99
-rw-r--r--src/UI/Window.h32
15 files changed, 1055 insertions, 6 deletions
diff --git a/src/Blocks/BlockEnchantmentTable.h b/src/Blocks/BlockEnchantmentTable.h
new file mode 100644
index 000000000..81d2cb9a0
--- /dev/null
+++ b/src/Blocks/BlockEnchantmentTable.h
@@ -0,0 +1,37 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+#include "../UI/Window.h"
+#include "../Entities/Player.h"
+
+
+
+
+
+class cBlockEnchantmentTableHandler :
+ public cBlockHandler
+{
+public:
+ cBlockEnchantmentTableHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+
+ virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
+ {
+ cWindow * Window = new cEnchantingWindow(a_BlockX, a_BlockY, a_BlockZ);
+ a_Player->OpenWindow(Window);
+ }
+
+
+ virtual bool IsUseable(void) override
+ {
+ return true;
+ }
+};
+
+
+
+
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 4a29ff628..a764c6f44 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -25,6 +25,7 @@
#include "BlockDirt.h"
#include "BlockDoor.h"
#include "BlockDropSpenser.h"
+#include "BlockEnchantmentTable.h"
#include "BlockEnderchest.h"
#include "BlockEntity.h"
#include "BlockFarmland.h"
@@ -119,6 +120,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockDoubleSlabHandler (a_BlockType);
case E_BLOCK_DROPPER: return new cBlockDropSpenserHandler (a_BlockType);
case E_BLOCK_EMERALD_ORE: return new cBlockOreHandler (a_BlockType);
+ case E_BLOCK_ENCHANTMENT_TABLE: return new cBlockEnchantmentTableHandler(a_BlockType);
case E_BLOCK_ENDER_CHEST: return new cBlockEnderchestHandler (a_BlockType);
case E_BLOCK_FARMLAND: return new cBlockFarmlandHandler ( );
case E_BLOCK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 5876e55c7..90165b432 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -31,6 +31,8 @@
#include "CompositeChat.h"
#include "Items/ItemSword.h"
+#include "FastRandom.h"
+
/** Maximum number of explosions to send this tick, server will start dropping if exceeded */
@@ -2685,4 +2687,685 @@ void cClientHandle::SocketClosed(void)
+void cClientHandle::HandleEnchantItem(Byte & WindowID, Byte & Enchantment)
+{
+ cItem Item = m_Player->GetDraggingItem();
+ cEnchantingWindow * Window = (cEnchantingWindow*)m_Player->GetWindow();
+ int BaseEnchantmentLevel = Window->GetPropertyValue(Enchantment);
+
+ // Step 1 from Enchanting
+ int Enchantability = 1;
+
+ if (Item.m_ItemType == E_ITEM_WOODEN_SWORD || Item.m_ItemType == E_ITEM_WOODEN_PICKAXE || Item.m_ItemType == E_ITEM_WOODEN_SHOVEL || Item.m_ItemType == E_ITEM_WOODEN_AXE || Item.m_ItemType == E_ITEM_WOODEN_HOE)
+ {
+ Enchantability = 15;
+ }
+ else if (Item.m_ItemType == E_ITEM_LEATHER_CAP || Item.m_ItemType == E_ITEM_LEATHER_TUNIC || Item.m_ItemType == E_ITEM_LEATHER_PANTS || Item.m_ItemType == E_ITEM_LEATHER_BOOTS)
+ {
+ Enchantability = 15;
+ }
+ else if (Item.m_ItemType == E_ITEM_STONE_SWORD || Item.m_ItemType == E_ITEM_STONE_PICKAXE || Item.m_ItemType == E_ITEM_STONE_SHOVEL || Item.m_ItemType == E_ITEM_STONE_AXE || Item.m_ItemType == E_ITEM_STONE_HOE)
+ {
+ Enchantability = 5;
+ }
+ else if (Item.m_ItemType == E_ITEM_IRON_HELMET || Item.m_ItemType == E_ITEM_IRON_CHESTPLATE || Item.m_ItemType == E_ITEM_IRON_LEGGINGS || Item.m_ItemType == E_ITEM_IRON_BOOTS)
+ {
+ Enchantability = 9;
+ }
+ else if (Item.m_ItemType == E_ITEM_IRON_SWORD || Item.m_ItemType == E_ITEM_IRON_PICKAXE || Item.m_ItemType == E_ITEM_IRON_SHOVEL || Item.m_ItemType == E_ITEM_IRON_AXE || Item.m_ItemType == E_ITEM_IRON_HOE)
+ {
+ Enchantability = 14;
+ }
+ else if (Item.m_ItemType == E_ITEM_CHAIN_HELMET || Item.m_ItemType == E_ITEM_CHAIN_CHESTPLATE || Item.m_ItemType == E_ITEM_CHAIN_LEGGINGS || Item.m_ItemType == E_ITEM_CHAIN_BOOTS)
+ {
+ Enchantability = 12;
+ }
+ else if (Item.m_ItemType == E_ITEM_DIAMOND_HELMET || Item.m_ItemType == E_ITEM_DIAMOND_CHESTPLATE || Item.m_ItemType == E_ITEM_DIAMOND_LEGGINGS || Item.m_ItemType == E_ITEM_DIAMOND_BOOTS)
+ {
+ Enchantability = 10;
+ }
+ else if (Item.m_ItemType == E_ITEM_DIAMOND_SWORD || Item.m_ItemType == E_ITEM_DIAMOND_PICKAXE || Item.m_ItemType == E_ITEM_DIAMOND_SHOVEL || Item.m_ItemType == E_ITEM_DIAMOND_AXE || Item.m_ItemType == E_ITEM_DIAMOND_HOE)
+ {
+ Enchantability = 10;
+ }
+ else if (Item.m_ItemType == E_ITEM_GOLD_HELMET || Item.m_ItemType == E_ITEM_GOLD_CHESTPLATE || Item.m_ItemType == E_ITEM_GOLD_LEGGINGS || Item.m_ItemType == E_ITEM_GOLD_BOOTS)
+ {
+ Enchantability = 25;
+ }
+ else if (Item.m_ItemType == E_ITEM_GOLD_SWORD || Item.m_ItemType == E_ITEM_GOLD_PICKAXE || Item.m_ItemType == E_ITEM_GOLD_SHOVEL || Item.m_ItemType == E_ITEM_GOLD_AXE || Item.m_ItemType == E_ITEM_GOLD_HOE)
+ {
+ Enchantability = 22;
+ }
+
+ cFastRandom Random;
+ int ModifiedEnchantmentLevel = BaseEnchantmentLevel + Random.NextInt(Enchantability / 4) + Random.NextInt(Enchantability / 4) + 1;
+ float RandomBonus = 1.0F + (Random.NextFloat(1) + Random.NextFloat(1) - 1.0F) * 0.15F;
+
+ int FinalEnchantmentLevel = (int)(ModifiedEnchantmentLevel * RandomBonus + 0.5F);
+
+ // Step 2 and 3 from Enchanting
+ cEnchantmentsVector enchantments;
+
+ if (ItemCategory::IsSword(Item.m_ItemType))
+ {
+ // Sharpness
+ if (FinalEnchantmentLevel >= 34 && FinalEnchantmentLevel <= 54)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Sharpness=4"));
+ }
+ else if (FinalEnchantmentLevel >= 23 && FinalEnchantmentLevel <= 43)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Sharpness=3"));
+ }
+ else if (FinalEnchantmentLevel >= 12 && FinalEnchantmentLevel <= 32)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Sharpness=2"));
+ }
+ else if (FinalEnchantmentLevel >= 1 && FinalEnchantmentLevel <= 21)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Sharpness=1"));
+ }
+
+ // Smite
+ if (FinalEnchantmentLevel >= 29 && FinalEnchantmentLevel <= 49)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Smite=4"));
+ }
+ else if (FinalEnchantmentLevel >= 21 && FinalEnchantmentLevel <= 41)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Smite=3"));
+ }
+ else if (FinalEnchantmentLevel >= 13 && FinalEnchantmentLevel <= 33)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Smite=2"));
+ }
+ else if (FinalEnchantmentLevel >= 5 && FinalEnchantmentLevel <= 25)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Smite=1"));
+ }
+
+ // Bane of Arthropods
+ if (FinalEnchantmentLevel >= 29 && FinalEnchantmentLevel <= 49)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("BaneOfArthropods=4"));
+ }
+ else if (FinalEnchantmentLevel >= 21 && FinalEnchantmentLevel <= 41)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("BaneOfArthropods=3"));
+ }
+ else if (FinalEnchantmentLevel >= 13 && FinalEnchantmentLevel <= 33)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("BaneOfArthropods=2"));
+ }
+ else if (FinalEnchantmentLevel >= 5 && FinalEnchantmentLevel <= 25)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("BaneOfArthropods=1"));
+ }
+
+ // Knockback
+ if (FinalEnchantmentLevel >= 25 && FinalEnchantmentLevel <= 75)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Knockback=2"));
+ }
+ else if (FinalEnchantmentLevel >= 5 && FinalEnchantmentLevel <= 55)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Knockback=1"));
+ }
+
+ // Fire Aspect
+ if (FinalEnchantmentLevel >= 30 && FinalEnchantmentLevel <= 80)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("FireAspect=2"));
+ }
+ else if (FinalEnchantmentLevel >= 10 && FinalEnchantmentLevel <= 60)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("FireAspect=1"));
+ }
+
+ // Looting
+ if (FinalEnchantmentLevel >= 33 && FinalEnchantmentLevel <= 83)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Looting=3"));
+ }
+ else if (FinalEnchantmentLevel >= 24 && FinalEnchantmentLevel <= 74)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Looting=2"));
+ }
+ else if (FinalEnchantmentLevel >= 15 && FinalEnchantmentLevel <= 65)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Looting=1"));
+ }
+ }
+
+ else if (ItemCategory::IsTool(Item.m_ItemType))
+ {
+ // Efficiency
+ if (FinalEnchantmentLevel >= 31 && FinalEnchantmentLevel <= 81)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Efficiency=4"));
+ }
+ else if (FinalEnchantmentLevel >= 21 && FinalEnchantmentLevel <= 71)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Efficiency=3"));
+ }
+ else if (FinalEnchantmentLevel >= 11 && FinalEnchantmentLevel <= 61)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Efficiency=2"));
+ }
+ else if (FinalEnchantmentLevel >= 1 && FinalEnchantmentLevel <= 51)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Efficiency=1"));
+ }
+
+ // Silk Touch
+ if (FinalEnchantmentLevel >= 15 && FinalEnchantmentLevel <= 65)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("SilkTouch=1"));
+ }
+
+ // Fortune
+ if (FinalEnchantmentLevel >= 33 && FinalEnchantmentLevel <= 83)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Fortune=3"));
+ }
+ else if (FinalEnchantmentLevel >= 24 && FinalEnchantmentLevel <= 74)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Fortune=2"));
+ }
+ else if (FinalEnchantmentLevel >= 15 && FinalEnchantmentLevel <= 65)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Fortune=1"));
+ }
+ }
+
+ else if (ItemCategory::IsArmor(Item.m_ItemType))
+ {
+ // Protection
+ if (FinalEnchantmentLevel >= 34 && FinalEnchantmentLevel <= 54)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Protection=4"));
+ }
+ else if (FinalEnchantmentLevel >= 23 && FinalEnchantmentLevel <= 43)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Protection=3"));
+ }
+ else if (FinalEnchantmentLevel >= 12 && FinalEnchantmentLevel <= 32)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Protection=2"));
+ }
+ else if (FinalEnchantmentLevel >= 1 && FinalEnchantmentLevel <= 21)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Protection=1"));
+ }
+
+ // Fire Protection
+ if (FinalEnchantmentLevel >= 34 && FinalEnchantmentLevel <= 46)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FireProtection=4"));
+ }
+ else if (FinalEnchantmentLevel >= 26 && FinalEnchantmentLevel <= 38)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FireProtection=3"));
+ }
+ else if (FinalEnchantmentLevel >= 18 && FinalEnchantmentLevel <= 30)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FireProtection=2"));
+ }
+ else if (FinalEnchantmentLevel >= 10 && FinalEnchantmentLevel <= 22)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FireProtection=1"));
+ }
+
+ // Blast Protection
+ if (FinalEnchantmentLevel >= 29 && FinalEnchantmentLevel <= 41)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("BlastProtection=4"));
+ }
+ else if (FinalEnchantmentLevel >= 21 && FinalEnchantmentLevel <= 33)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("BlastProtection=3"));
+ }
+ else if (FinalEnchantmentLevel >= 13 && FinalEnchantmentLevel <= 25)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("BlastProtection=2"));
+ }
+ else if (FinalEnchantmentLevel >= 5 && FinalEnchantmentLevel <= 17)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("BlastProtection=1"));
+ }
+
+ // Projectile Protection
+ if (FinalEnchantmentLevel >= 21 && FinalEnchantmentLevel <= 36)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("ProjectileProtection=4"));
+ }
+ else if (FinalEnchantmentLevel >= 15 && FinalEnchantmentLevel <= 30)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("ProjectileProtection=3"));
+ }
+ else if (FinalEnchantmentLevel >= 9 && FinalEnchantmentLevel <= 24)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("ProjectileProtection=2"));
+ }
+ else if (FinalEnchantmentLevel >= 3 && FinalEnchantmentLevel <= 18)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("ProjectileProtection=1"));
+ }
+
+ // Thorns
+ if (FinalEnchantmentLevel >= 50 && FinalEnchantmentLevel <= 100)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("Thorns=3"));
+ }
+ else if (FinalEnchantmentLevel >= 30 && FinalEnchantmentLevel <= 80)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("Thorns=2"));
+ }
+ else if (FinalEnchantmentLevel >= 10 && FinalEnchantmentLevel <= 60)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("Thorns=1"));
+ }
+
+
+ if (ItemCategory::IsHelmet(Item.m_ItemType))
+ {
+ // Respiration
+ if (FinalEnchantmentLevel >= 30 && FinalEnchantmentLevel <= 60)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Respiration=3"));
+ }
+ else if (FinalEnchantmentLevel >= 20 && FinalEnchantmentLevel <= 50)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Respiration=2"));
+ }
+ else if (FinalEnchantmentLevel >= 10 && FinalEnchantmentLevel <= 40)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Respiration=1"));
+ }
+
+ // Aqua Affinity
+ if (FinalEnchantmentLevel >= 1 && FinalEnchantmentLevel <= 41)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("AquaAffinity=1"));
+ }
+ }
+
+ else if (ItemCategory::IsBoots(Item.m_ItemType))
+ {
+ // Feather Fall
+ if (FinalEnchantmentLevel >= 23 && FinalEnchantmentLevel <= 33)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FeatherFalling=4"));
+ }
+ else if (FinalEnchantmentLevel >= 17 && FinalEnchantmentLevel <= 27)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FeatherFalling=3"));
+ }
+ else if (FinalEnchantmentLevel >= 11 && FinalEnchantmentLevel <= 21)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FeatherFalling=2"));
+ }
+ else if (FinalEnchantmentLevel >= 5 && FinalEnchantmentLevel <= 15)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("FeatherFalling=1"));
+ }
+ }
+ }
+
+ else if (Item.m_ItemType == E_ITEM_BOW)
+ {
+ // Power
+ if (FinalEnchantmentLevel >= 31 && FinalEnchantmentLevel <= 46)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Power=4"));
+ }
+ else if (FinalEnchantmentLevel >= 21 && FinalEnchantmentLevel <= 36)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Power=3"));
+ }
+ else if (FinalEnchantmentLevel >= 11 && FinalEnchantmentLevel <= 26)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Power=2"));
+ }
+ else if (FinalEnchantmentLevel >= 1 && FinalEnchantmentLevel <= 16)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 10, cEnchantments("Power=1"));
+ }
+
+ // Punch
+ if (FinalEnchantmentLevel >= 32 && FinalEnchantmentLevel <= 57)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Punch=2"));
+ }
+ else if (FinalEnchantmentLevel >= 12 && FinalEnchantmentLevel <= 37)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Punch=1"));
+ }
+
+ // Flame and Infinity
+ if (FinalEnchantmentLevel >= 20 && FinalEnchantmentLevel <= 50)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 2, cEnchantments("Flame=1"));
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("Infinity=1"));
+ }
+ }
+
+ else if (Item.m_ItemType == E_ITEM_FISHING_ROD)
+ {
+ // Luck of the Sea and Lure
+ if (FinalEnchantmentLevel >= 33 && FinalEnchantmentLevel <= 83)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("LuckOfTheSea=3"));
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("Lure=3"));
+ }
+ else if (FinalEnchantmentLevel >= 24 && FinalEnchantmentLevel <= 74)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("LuckOfTheSea=2"));
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("Lure=2"));
+ }
+ else if (FinalEnchantmentLevel >= 15 && FinalEnchantmentLevel <= 65)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("LuckOfTheSea=1"));
+ enchantments = AddEnchantmentWeight(enchantments, 1, cEnchantments("Lure=1"));
+ }
+ }
+
+ // Unbreaking
+ if (FinalEnchantmentLevel >= 21 && FinalEnchantmentLevel <= 71)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Unbreaking=3"));
+ }
+ else if (FinalEnchantmentLevel >= 13 && FinalEnchantmentLevel <= 63)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Unbreaking=2"));
+ }
+ else if (FinalEnchantmentLevel >= 5 && FinalEnchantmentLevel <= 55)
+ {
+ enchantments = AddEnchantmentWeight(enchantments, 5, cEnchantments("Unbreaking=1"));
+ }
+
+ int RandomEnchantment1 = floor(Random.NextFloat(1) * enchantments.size());
+ cEnchantments Enchantment1 = enchantments[RandomEnchantment1];
+ Item.m_Enchantments.AddFromString(Enchantment1.ToString());
+ enchantments.erase(std::remove(enchantments.begin(), enchantments.end(), Enchantment1), enchantments.end());
+
+ // TODO: Don't add every time so much enchantments
+
+ // Checking for conflicting enchantments
+ enchantments = CheckEnchantmentConflicts(enchantments, Enchantment1);
+
+ int RandomEnchantment2 = floor(Random.NextFloat(1) * enchantments.size());
+ cEnchantments Enchantment2 = enchantments[RandomEnchantment2];
+ Item.m_Enchantments.AddFromString(Enchantment2.ToString());
+ enchantments.erase(std::remove(enchantments.begin(), enchantments.end(), Enchantment2), enchantments.end());
+
+ // Checking for conflicting enchantments
+ enchantments = CheckEnchantmentConflicts(enchantments, Enchantment2);
+
+ int RandomEnchantment3 = floor(Random.NextFloat(1) * enchantments.size());
+ cEnchantments Enchantment3 = enchantments[RandomEnchantment3];
+ Item.m_Enchantments.AddFromString(Enchantment3.ToString());
+ enchantments.erase(std::remove(enchantments.begin(), enchantments.end(), Enchantment3), enchantments.end());
+
+ m_Player->GetWindow()->SetSlot(*m_Player, 0, Item);
+}
+
+
+
+
+
+cEnchantmentsVector cClientHandle::AddEnchantmentWeight(cEnchantmentsVector a_Map, int a_Weight, cEnchantments a_Enchantment)
+{
+ for (int i = 0; i < a_Weight; i++)
+ {
+ a_Map.push_back(a_Enchantment);
+ }
+
+ return a_Map;
+}
+
+
+
+
+
+cEnchantmentsVector cClientHandle::CheckEnchantmentConflicts(cEnchantmentsVector a_Map, cEnchantments a_FirstEnchantment)
+{
+ int FirstEnchantmentID = std::stoi(StringSplit(a_FirstEnchantment.ToString(), "=")[0]);
+
+ if (FirstEnchantmentID == cEnchantments::enchProtection)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchFireProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchBlastProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchProjectileProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+ else if (FirstEnchantmentID == cEnchantments::enchFireProtection)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchBlastProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchProjectileProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+ else if (FirstEnchantmentID == cEnchantments::enchBlastProtection)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchFireProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchProjectileProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+ else if (FirstEnchantmentID == cEnchantments::enchProjectileProtection)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchFireProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchBlastProtection)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+
+ else if (FirstEnchantmentID == cEnchantments::enchSharpness)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchSmite)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchBaneOfArthropods)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+ else if (FirstEnchantmentID == cEnchantments::enchSmite)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchSharpness)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchBaneOfArthropods)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+ else if (FirstEnchantmentID == cEnchantments::enchBaneOfArthropods)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchSharpness)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchSmite)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+ else if (FirstEnchantmentID == cEnchantments::enchSilkTouch)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchFortune)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+ else if (FirstEnchantmentID == cEnchantments::enchFortune)
+ {
+ for (cEnchantments enchantment : a_Map)
+ {
+ int EnchantmentID = std::stoi(StringSplit(enchantment.ToString(), "=")[0]);
+
+ if (EnchantmentID == cEnchantments::enchSilkTouch)
+ {
+ a_Map.erase(std::remove(a_Map.begin(), a_Map.end(), enchantment), a_Map.end());
+ break;
+ }
+ }
+ }
+
+ return a_Map;
+}
+
+
+
+
+
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 0c367ec7d..4c88d79e2 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -18,6 +18,7 @@
#include "ByteBuffer.h"
#include "Scoreboard.h"
#include "Map.h"
+#include "Enchantments.h"
@@ -230,6 +231,11 @@ public:
/** Called when the player moves into a different world; queues sreaming the new chunks */
void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket);
+ /** Called when the player will enchant a Item */
+ void HandleEnchantItem(Byte & WindowID, Byte & Enchantment);
+ cEnchantmentsVector AddEnchantmentWeight(cEnchantmentsVector a_Map, int a_Weight, cEnchantments a_Enchantment);
+ cEnchantmentsVector CheckEnchantmentConflicts(cEnchantmentsVector a_Map, cEnchantments a_FirstEnchantment);
+
private:
/** Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) */
diff --git a/src/Enchantments.h b/src/Enchantments.h
index f77b535d8..70d6b6613 100644
--- a/src/Enchantments.h
+++ b/src/Enchantments.h
@@ -28,6 +28,9 @@ mapping each enchantment's id onto its level. ID may be either a number or the e
Level value of 0 means no such enchantment, and it will not be stored in the m_Enchantments.
Serialization will never put zero-level enchantments into the stringspec and will always use numeric IDs.
*/
+
+typedef std::vector<cEnchantments> cEnchantmentsVector;
+
// tolua_begin
class cEnchantments
{
@@ -61,7 +64,7 @@ public:
enchLuckOfTheSea = 61,
enchLure = 62,
} ;
-
+
/// Creates an empty enchantments container
cEnchantments(void);
@@ -102,7 +105,7 @@ public:
/// Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments)
friend void EnchantmentSerializer::ParseFromNBT(cEnchantments& a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx);
-
+
protected:
/// Maps enchantment ID -> enchantment level
typedef std::map<int, int> cMap;
diff --git a/src/FastRandom.cpp b/src/FastRandom.cpp
index e6634bb0d..c45261947 100644
--- a/src/FastRandom.cpp
+++ b/src/FastRandom.cpp
@@ -172,3 +172,13 @@ float cFastRandom::NextFloat(float a_Range, int a_Salt)
+
+int cFastRandom::GenerateRandomInteger(int a_Begin, int a_End)
+{
+ cFastRandom Random;
+ return Random.NextInt(a_End - a_Begin + 1) + a_Begin;
+}
+
+
+
+
diff --git a/src/FastRandom.h b/src/FastRandom.h
index bf70822cf..567198a31 100644
--- a/src/FastRandom.h
+++ b/src/FastRandom.h
@@ -43,6 +43,9 @@ public:
/// Returns a random float in the range [0 .. a_Range]; a_Range must be less than 1M; a_Salt is additional source of randomness
float NextFloat(float a_Range, int a_Salt);
+
+ /** Returns a random int in the range [a_Begin .. a_End] */
+ int GenerateRandomInteger(int a_Begin, int a_End);
protected:
int m_Seed;
diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp
index bf946ef19..26f109918 100644
--- a/src/Protocol/Protocol125.cpp
+++ b/src/Protocol/Protocol125.cpp
@@ -96,6 +96,7 @@ enum
PACKET_INVENTORY_WHOLE = 0x68,
PACKET_WINDOW_PROPERTY = 0x69,
PACKET_CREATIVE_INVENTORY_ACTION = 0x6B,
+ PACKET_ENCHANT_ITEM = 0x6C,
PACKET_UPDATE_SIGN = 0x82,
PACKET_ITEM_DATA = 0x83,
PACKET_PLAYER_LIST_ITEM = 0xC9,
@@ -1236,6 +1237,7 @@ int cProtocol125::ParsePacket(unsigned char a_PacketType)
case PACKET_SLOT_SELECTED: return ParseSlotSelected();
case PACKET_UPDATE_SIGN: return ParseUpdateSign();
case PACKET_USE_ENTITY: return ParseUseEntity();
+ case PACKET_ENCHANT_ITEM: return ParseEnchantItem();
case PACKET_WINDOW_CLICK: return ParseWindowClick();
case PACKET_WINDOW_CLOSE: return ParseWindowClose();
}
@@ -1597,6 +1599,22 @@ int cProtocol125::ParseUseEntity(void)
+int cProtocol125::ParseEnchantItem(void)
+{
+ HANDLE_PACKET_READ(ReadByte, Byte, WindowID);
+ HANDLE_PACKET_READ(ReadByte, Byte, Enchantment);
+
+ LOGWARN("Older Protocol: Enchantment Packet received!");
+
+ m_Client->HandleEnchantItem(WindowID, Enchantment);
+
+ return PARSE_OK;
+}
+
+
+
+
+
int cProtocol125::ParseWindowClick(void)
{
HANDLE_PACKET_READ(ReadChar, char, WindowID);
diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h
index 08d3ebbe9..753458ebc 100644
--- a/src/Protocol/Protocol125.h
+++ b/src/Protocol/Protocol125.h
@@ -155,6 +155,7 @@ protected:
virtual int ParseSlotSelected (void);
virtual int ParseUpdateSign (void);
virtual int ParseUseEntity (void);
+ virtual int ParseEnchantItem (void);
virtual int ParseWindowClick (void);
virtual int ParseWindowClose (void);
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index a4319df37..785dbf935 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -1431,6 +1431,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return true;
case 0x0f: // Confirm transaction - not used in MCS
case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;
+ case 0x11: HandlePacketEnchantItem (a_ByteBuffer); return true;
case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return true;
case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return true;
case 0x14: HandlePacketTabComplete (a_ByteBuffer); return true;
@@ -1912,6 +1913,21 @@ void cProtocol172::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer)
+void cProtocol172::HandlePacketEnchantItem(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, WindowID);
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Enchantment);
+
+ LOGWARN("Protocol 1.7: Enchantment Packet received!");
+
+ m_Client->HandleEnchantItem(WindowID, Enchantment);
+
+}
+
+
+
+
+
void cProtocol172::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID);
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 91186b270..a1ad1f049 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -279,6 +279,7 @@ protected:
void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer);
void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer);
void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer);
+ void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 88977e005..d43b91700 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -13,6 +13,8 @@
#include "Window.h"
#include "../CraftingRecipes.h"
#include "../Root.h"
+#include "../FastRandom.h"
+#include "../BlockArea.h"
@@ -593,6 +595,122 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cSlotAreaEnchanting:
+
+cSlotAreaEnchanting::cSlotAreaEnchanting(int a_NumSlots, cWindow & a_ParentWindow) :
+cSlotAreaTemporary(a_NumSlots, a_ParentWindow)
+{
+}
+
+
+
+
+
+void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem)
+{
+ // Check if Slot is in the Enchantment Table
+ if (a_SlotNum == 0)
+ {
+ if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
+ {
+ ShiftClickedResult(a_Player);
+ }
+ else
+ {
+ ClickedResult(a_Player);
+ }
+ return;
+ }
+ super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem);
+}
+
+
+
+
+
+void cSlotAreaEnchanting::OnPlayerRemoved(cPlayer & a_Player)
+{
+ // Toss the item in the enchanting slot
+ TossItems(a_Player, 0, 0);
+ // Player not found - that is acceptable
+}
+
+
+
+
+
+void cSlotAreaEnchanting::ClickedResult(cPlayer & a_Player)
+{
+ if (a_Player.GetDraggingItem().IsEmpty())
+ {
+ m_ParentWindow.SetProperty(0, 0, a_Player);
+ m_ParentWindow.SetProperty(1, 0, a_Player);
+ m_ParentWindow.SetProperty(2, 0, a_Player);
+ }
+ else if (a_Player.GetDraggingItem().IsEnchantable)
+ {
+ int PosX = 0;
+ int PosY = 0;
+ int PosZ = 0;
+ cEnchantingWindow * Window = (cEnchantingWindow*)&m_ParentWindow;
+ Window->GetBlockPos(PosX, PosY, PosZ);
+
+ cBlockArea Area;
+ Area.Read(a_Player.GetWorld(), PosX - 2, PosX + 2, PosY, PosY + 1, PosZ - 2, PosZ + 2);
+
+ for (int x = 0; x < 6; x++)
+ {
+ for (int y = 0; y < 3; y++)
+ {
+ for (int z = 0; z < 6; z++)
+ {
+ if ((((x == 0) || (x == 5)) || ((z == 0) || (z == 5))) && ((y == 0) || y == 1))
+ {
+ LOG("%i", Area.GetRelBlockType(x, y, z));
+
+ if (Area.GetRelBlockType(x, y, z) == E_BLOCK_BOOKCASE)
+ {
+ LOG("BookShelf");
+ }
+ }
+ }
+ }
+ }
+
+ int bookshelves = 15; // TODO: Check Bookshelves
+
+ cFastRandom Random;
+ int base = (Random.GenerateRandomInteger(1, 8) + floor(bookshelves / 2) + Random.GenerateRandomInteger(0, bookshelves));
+ int topSlot = std::max(base / 3, 1);
+ int middleSlot = (base * 2) / 3 + 1;
+ int bottomSlot = std::max(base, bookshelves * 2);
+
+ m_ParentWindow.SetProperty(0, topSlot, a_Player);
+ m_ParentWindow.SetProperty(1, middleSlot, a_Player);
+ m_ParentWindow.SetProperty(2, bottomSlot, a_Player);
+ }
+ else
+ {
+ m_ParentWindow.SetProperty(0, 0, a_Player);
+ m_ParentWindow.SetProperty(1, 0, a_Player);
+ m_ParentWindow.SetProperty(2, 0, a_Player);
+ }
+}
+
+
+
+
+
+void cSlotAreaEnchanting::ShiftClickedResult(cPlayer & a_Player)
+{
+ LOGWARN("Shift Click!");
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cSlotAreaEnderChest:
cSlotAreaEnderChest::cSlotAreaEnderChest(cEnderChestEntity * a_EnderChest, cWindow & a_ParentWindow) :
diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h
index 25b367cff..82360ffbe 100644
--- a/src/UI/SlotArea.h
+++ b/src/UI/SlotArea.h
@@ -252,6 +252,34 @@ protected:
+class cSlotAreaEnchanting :
+ public cSlotAreaTemporary
+{
+ typedef cSlotAreaTemporary super;
+
+public:
+ /// a_GridSize is allowed to be only 2 or 3
+ cSlotAreaEnchanting(int a_NumSlots, cWindow & a_ParentWindow);
+
+ // cSlotAreaTemporary overrides:
+ virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
+ virtual void OnPlayerRemoved(cPlayer & a_Player) override;
+
+ // Distributing items into this area is completely disabled
+ virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override {}
+
+protected:
+ /// Handles a click in the result slot. Crafts using the current recipe, if possible
+ void ClickedResult(cPlayer & a_Player);
+
+ /// Handles a shift-click in the result slot. Crafts using the current recipe until it changes or no more space for result.
+ void ShiftClickedResult(cPlayer & a_Player);
+};
+
+
+
+
+
class cSlotAreaChest :
public cSlotArea
{
diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp
index aae7b99a3..c514e76e7 100644
--- a/src/UI/Window.cpp
+++ b/src/UI/Window.cpp
@@ -805,6 +805,105 @@ cCraftingWindow::cCraftingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cEnchantingWindow:
+
+cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
+ cWindow(wtEnchantment, "Enchant"),
+ m_BlockX(a_BlockX),
+ m_BlockY(a_BlockY),
+ m_BlockZ(a_BlockZ)
+{
+ m_SlotAreas.push_back(new cSlotAreaEnchanting(1, *this));
+ m_SlotAreas.push_back(new cSlotAreaInventory(*this));
+ m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
+}
+
+
+
+
+
+void cEnchantingWindow::SetProperty(int a_Property, int a_Value)
+{
+ if (a_Property == 0)
+ {
+ m_PropertyValue0 = a_Value;
+ }
+ else if (a_Property == 1)
+ {
+ m_PropertyValue1 = a_Value;
+ }
+ else if (a_Property == 2)
+ {
+ m_PropertyValue2 = a_Value;
+ }
+
+ cCSLock Lock(m_CS);
+ for (cPlayerList::iterator itr = m_OpenedBy.begin(), end = m_OpenedBy.end(); itr != end; ++itr)
+ {
+ (*itr)->GetClientHandle()->SendWindowProperty(*this, a_Property, a_Value);
+ } // for itr - m_OpenedBy[]
+}
+
+
+
+
+
+void cEnchantingWindow::SetProperty(int a_Property, int a_Value, cPlayer & a_Player)
+{
+ if (a_Property == 0)
+ {
+ m_PropertyValue0 = a_Value;
+ }
+ else if (a_Property == 1)
+ {
+ m_PropertyValue1 = a_Value;
+ }
+ else if (a_Property == 2)
+ {
+ m_PropertyValue2 = a_Value;
+ }
+
+ a_Player.GetClientHandle()->SendWindowProperty(*this, a_Property, a_Value);
+}
+
+
+
+
+
+int cEnchantingWindow::GetPropertyValue(int a_Property)
+{
+ if (a_Property == 0)
+ {
+ return m_PropertyValue0;
+ }
+ else if (a_Property == 1)
+ {
+ return m_PropertyValue1;
+ }
+ else if (a_Property == 2)
+ {
+ return m_PropertyValue2;
+ }
+
+ return -1;
+}
+
+
+
+
+
+void cEnchantingWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
+{
+ a_PosX = m_BlockX;
+ a_PosY = m_BlockY;
+ a_PosZ = m_BlockZ;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cChestWindow:
cChestWindow::cChestWindow(cChestEntity * a_Chest) :
diff --git a/src/UI/Window.h b/src/UI/Window.h
index 030182888..52ab6c3ae 100644
--- a/src/UI/Window.h
+++ b/src/UI/Window.h
@@ -136,11 +136,11 @@ public:
void SetWindowTitle(const AString & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; }
/// Sends the UpdateWindowProperty (0x69) packet to all clients of the window
- void SetProperty(int a_Property, int a_Value);
+ virtual void SetProperty(int a_Property, int a_Value);
/// Sends the UpdateWindowPropert(0x69) packet to the specified player
- void SetProperty(int a_Property, int a_Value, cPlayer & a_Player);
-
+ virtual void SetProperty(int a_Property, int a_Value, cPlayer & a_Player);
+
// tolua_end
void OwnerDestroyed(void);
@@ -165,7 +165,7 @@ public:
/// Used by cSlotAreas to send individual slots to clients, a_RelativeSlotNum is the slot number relative to a_SlotArea
void SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum);
-
+
protected:
cSlotAreas m_SlotAreas;
@@ -231,6 +231,30 @@ public:
+class cEnchantingWindow :
+ public cWindow
+{
+ typedef cWindow super;
+public:
+ cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void SetProperty(int a_Property, int a_Value, cPlayer & a_Player) override;
+ virtual void SetProperty(int a_Property, int a_Value) override;
+
+ /** Return the Value of a Property */
+ int GetPropertyValue(int a_Property);
+
+ /** Set the Position Values to the Position of the Enchantment Table */
+ void GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ);
+
+protected:
+ int m_PropertyValue0, m_PropertyValue1, m_PropertyValue2;
+ int m_BlockX, m_BlockY, m_BlockZ;
+};
+
+
+
+
+
class cFurnaceWindow :
public cWindow
{