summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ClientHandle.cpp2
-rw-r--r--src/Entities/Player.cpp3
-rw-r--r--src/Inventory.cpp25
-rw-r--r--src/Inventory.h3
-rw-r--r--src/Items/ItemEmptyMap.h16
-rw-r--r--src/Items/ItemHandler.cpp2
-rw-r--r--src/Items/ItemHandler.h8
-rw-r--r--src/Items/ItemMap.h43
-rw-r--r--src/Map.cpp63
-rw-r--r--src/Map.h13
-rw-r--r--src/World.cpp28
-rw-r--r--src/WorldStorage/MapSerializer.cpp11
-rw-r--r--src/WorldStorage/MapSerializer.h7
13 files changed, 195 insertions, 29 deletions
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index ff8775771..a2cbaefff 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -1199,8 +1199,6 @@ void cClientHandle::HandleSlotSelected(short a_SlotNum)
if (Map != NULL)
{
- Map->UpdateRadius(*m_Player, 128); // Temporary
-
// TODO 2014-02-14 xdot: Optimization - Do not send the whole map.
Map->SendTo(*this);
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 286d43cf6..fdf8d4303 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -254,6 +254,9 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
HandleFloater();
}
+ // Update items (e.g. Maps)
+ m_Inventory.UpdateItems();
+
// Send Player List (Once per m_LastPlayerListTime/1000 ms)
cTimer t1;
if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime())
diff --git a/src/Inventory.cpp b/src/Inventory.cpp
index 0e1cedc85..7f434adfd 100644
--- a/src/Inventory.cpp
+++ b/src/Inventory.cpp
@@ -515,6 +515,31 @@ bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size,
+void cInventory::UpdateItems(void)
+{
+ const cItem & Slot = GetEquippedItem();
+
+ if (Slot.IsEmpty())
+ {
+ return;
+ }
+
+ switch (Slot.m_ItemType)
+ {
+ case E_ITEM_MAP:
+ {
+ ItemHandler(Slot.m_ItemType)->OnUpdate(m_Owner.GetWorld(), &m_Owner, Slot);
+ break;
+ }
+
+ default: break;
+ }
+}
+
+
+
+
+
void cInventory::SaveToJson(Json::Value & a_Value)
{
// The JSON originally included the 4 crafting slots and the result, so we have to put empty items there, too:
diff --git a/src/Inventory.h b/src/Inventory.h
index 3c6a19de8..fd2089a13 100644
--- a/src/Inventory.h
+++ b/src/Inventory.h
@@ -150,6 +150,9 @@ public:
/// Sends the slot contents to the owner
void SendSlot(int a_SlotNum);
+ /// Update items (e.g. Maps)
+ void UpdateItems(void);
+
/// Converts an armor slot number into the ID for the EntityEquipment packet
static int ArmorSlotNumToEntityEquipmentID(short a_ArmorSlotNum);
diff --git a/src/Items/ItemEmptyMap.h b/src/Items/ItemEmptyMap.h
index 24d31151b..b06cf9d13 100644
--- a/src/Items/ItemEmptyMap.h
+++ b/src/Items/ItemEmptyMap.h
@@ -41,7 +41,21 @@ public:
int CenterX = round(a_Player->GetPosX() / (float) RegionWidth) * RegionWidth;
int CenterZ = round(a_Player->GetPosZ() / (float) RegionWidth) * RegionWidth;
- a_World->CreateMap(CenterX, CenterZ, DEFAULT_SCALE);
+ cMap * NewMap = a_World->CreateMap(CenterX, CenterZ, DEFAULT_SCALE);
+
+ // Remove empty map from inventory
+ if (!a_Player->GetInventory().RemoveOneEquippedItem())
+ {
+ ASSERT(!"Inventory mismatch");
+ return true;
+ }
+
+ if (NewMap == NULL)
+ {
+ return true;
+ }
+
+ a_Player->GetInventory().AddItem(cItem(E_ITEM_MAP, 1, NewMap->GetID()), true, true);
return true;
}
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 755766d64..cab8dec97 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -25,6 +25,7 @@
#include "ItemHoe.h"
#include "ItemLeaves.h"
#include "ItemLighter.h"
+#include "ItemMap.h"
#include "ItemMinecart.h"
#include "ItemNetherWart.h"
#include "ItemPickaxe.h"
@@ -107,6 +108,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType);
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
+ case E_ITEM_MAP: return new cItemMapHandler();
case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType);
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h
index 1a6bb044f..ef3f37a7a 100644
--- a/src/Items/ItemHandler.h
+++ b/src/Items/ItemHandler.h
@@ -32,6 +32,14 @@ public:
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
}
+
+ /// Called every tick while the item is on the player's inventory (Used by maps) - For now, called only for equipped items
+ virtual void OnUpdate(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item)
+ {
+ UNUSED(a_World);
+ UNUSED(a_Player);
+ UNUSED(a_Item);
+ }
/// Called while the player diggs a block using this item
virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace);
diff --git a/src/Items/ItemMap.h b/src/Items/ItemMap.h
new file mode 100644
index 000000000..c3e605547
--- /dev/null
+++ b/src/Items/ItemMap.h
@@ -0,0 +1,43 @@
+
+// ItemMap.h
+
+
+
+
+
+#pragma once
+
+#include "../Entities/Entity.h"
+#include "../Item.h"
+
+
+
+
+
+class cItemMapHandler :
+ public cItemHandler
+{
+ typedef cItemHandler super;
+
+ static const unsigned int DEFAULT_RADIUS = 128;
+
+public:
+ cItemMapHandler() :
+ super(E_ITEM_MAP)
+ {
+ }
+
+ virtual void OnUpdate(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item)
+ {
+ cMap * Map = a_World->GetMapData(a_Item.m_ItemDamage);
+
+ if (Map == NULL)
+ {
+ return;
+ }
+
+ // Map->AddTrackedPlayer(a_Player);
+
+ Map->UpdateRadius(*a_Player, DEFAULT_RADIUS);
+ }
+} ;
diff --git a/src/Map.cpp b/src/Map.cpp
index e0f991693..e85c23d3a 100644
--- a/src/Map.cpp
+++ b/src/Map.cpp
@@ -50,15 +50,25 @@ cMap::cMap(unsigned int a_ID, int a_CenterX, int a_CenterZ, cWorld * a_World, un
+template <typename T>
+T Clamp(T a_X, T a_Min, T a_Max)
+{
+ return std::min(std::max(a_X, a_Min), a_Max);
+}
+
+
+
+
+
void cMap::UpdateRadius(int a_PixelX, int a_PixelZ, unsigned int a_Radius)
{
int PixelRadius = a_Radius / GetPixelWidth();
- unsigned int StartX = std::max(a_PixelX - PixelRadius, 0);
- unsigned int StartZ = std::max(a_PixelZ - PixelRadius, 0);
+ unsigned int StartX = Clamp(a_PixelX - PixelRadius, 0, (int)m_Width);
+ unsigned int StartZ = Clamp(a_PixelZ - PixelRadius, 0, (int)m_Height);
- unsigned int EndX = std::min(a_PixelX + PixelRadius, (int)m_Width);
- unsigned int EndZ = std::min(a_PixelZ + PixelRadius, (int)m_Height);
+ unsigned int EndX = Clamp(a_PixelX + PixelRadius, 0, (int)m_Width);
+ unsigned int EndZ = Clamp(a_PixelZ + PixelRadius, 0, (int)m_Height);
for (unsigned int X = StartX; X < EndX; ++X)
{
@@ -93,11 +103,9 @@ void cMap::UpdateRadius(cPlayer & a_Player, unsigned int a_Radius)
-bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Y)
+bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z)
{
- ASSERT(m_World != NULL);
-
- unsigned int PixelWidth = GetPixelWidth();
+ /*unsigned int PixelWidth = GetPixelWidth();
int BlockX = m_CenterX + ((a_X - m_Width) * PixelWidth);
int BlockZ = m_CenterZ + ((a_Y - m_Height) * PixelWidth);
@@ -119,7 +127,7 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Y)
public:
cCalculatePixelCb(cMap * a_Map, int a_RelX, int a_RelZ)
- : m_Map(a_Map), m_RelX(a_RelX), m_RelZ(a_RelZ), m_PixelData(0) {}
+ : m_Map(a_Map), m_RelX(a_RelX), m_RelZ(a_RelZ), m_PixelData(4) {}
virtual bool Item(cChunk * a_Chunk) override
{
@@ -155,9 +163,9 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Y)
} CalculatePixelCb(this, RelX, RelZ);
ASSERT(m_World != NULL);
- m_World->DoWithChunk(ChunkX, ChunkZ, CalculatePixelCb);
+ m_World->DoWithChunk(ChunkX, ChunkZ, CalculatePixelCb);*/
- m_Data[a_Y + (a_X * m_Height)] = CalculatePixelCb.GetPixelData();
+ m_Data[a_Z + (a_X * m_Height)] = 4;
return true;
}
@@ -166,6 +174,39 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Y)
+void cMap::UpdateTrackedPlayers(void)
+{
+ cTrackedPlayerList NewList;
+
+ for (cTrackedPlayerList::iterator it = m_TrackedPlayers.begin(); it != m_TrackedPlayers.end(); ++it)
+ {
+ cPlayer * Player = *it;
+
+ UpdateRadius(*Player, DEFAULT_RADIUS);
+
+ if (true)
+ {
+ NewList.insert(Player);
+ }
+ }
+
+ std::swap(m_TrackedPlayers, NewList);
+}
+
+
+
+
+
+void cMap::AddTrackedPlayer(cPlayer * a_Player)
+{
+ ASSERT(a_Player != NULL);
+ m_TrackedPlayers.insert(a_Player);
+}
+
+
+
+
+
void cMap::EraseData(void)
{
m_Data.assign(m_Width * m_Height, 0);
diff --git a/src/Map.h b/src/Map.h
index 4134d53a1..805dfb845 100644
--- a/src/Map.h
+++ b/src/Map.h
@@ -38,6 +38,8 @@ public:
typedef std::vector<ColorID> cColorList;
+ static const unsigned int DEFAULT_RADIUS = 128;
+
public:
@@ -54,6 +56,10 @@ public:
void UpdateRadius(cPlayer & a_Player, unsigned int a_Radius);
+ void UpdateTrackedPlayers(void);
+
+ void AddTrackedPlayer(cPlayer * a_Player);
+
// tolua_begin
/** Erase pixel data */
@@ -93,7 +99,7 @@ public:
private:
/** Update the specified pixel. */
- bool UpdatePixel(unsigned int a_X, unsigned int a_Y);
+ bool UpdatePixel(unsigned int a_X, unsigned int a_Z);
unsigned int m_ID;
@@ -111,8 +117,9 @@ private:
cWorld * m_World;
- //typedef std::vector<cPlayer*> cPlayerList;
- //cPlayerList m_TrackedPlayers;
+ typedef std::set<cPlayer*> cTrackedPlayerList;
+
+ cTrackedPlayerList m_TrackedPlayers;
AString m_Name;
diff --git a/src/World.cpp b/src/World.cpp
index 2a3e53332..55c6fbb7a 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -1574,8 +1574,7 @@ cMap * cWorld::CreateMap(int a_CenterX, int a_CenterY, int a_Scale)
{
if (m_MapData.size() >= 65536)
{
- LOGD("cWorld::CreateMap - Too many maps in use");
-
+ LOGWARN("Could not craft map - Too many maps in use");
return NULL;
}
@@ -2992,9 +2991,12 @@ void cWorld::LoadMapData(void)
{
cIDCountSerializer IDSerializer(GetName());
- IDSerializer.Load();
+ if (!IDSerializer.Load())
+ {
+ return;
+ }
- unsigned int MapCount = IDSerializer.GetMapCount() + 1;
+ unsigned int MapCount = IDSerializer.GetMapCount();
m_MapData.clear();
@@ -3004,7 +3006,10 @@ void cWorld::LoadMapData(void)
cMapSerializer Serializer(GetName(), &Map);
- Serializer.Load();
+ if (!Serializer.Load())
+ {
+ LOGWARN("Could not load map #%i", Map.GetID());
+ }
m_MapData.push_back(Map);
}
@@ -3023,9 +3028,13 @@ void cWorld::SaveMapData(void)
cIDCountSerializer IDSerializer(GetName());
- IDSerializer.SetMapCount(m_MapData.size() - 1);
+ IDSerializer.SetMapCount(m_MapData.size());
- IDSerializer.Save();
+ if (!IDSerializer.Save())
+ {
+ LOGERROR("Could not save idcounts.dat");
+ return;
+ }
for (cMapList::iterator it = m_MapData.begin(); it != m_MapData.end(); ++it)
{
@@ -3033,7 +3042,10 @@ void cWorld::SaveMapData(void)
cMapSerializer Serializer(GetName(), &Map);
- Serializer.Save();
+ if (!Serializer.Save())
+ {
+ LOGWARN("Could not save map #%i", Map.GetID());
+ }
}
}
diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp
index 6dab19d4f..0bbe71a60 100644
--- a/src/WorldStorage/MapSerializer.cpp
+++ b/src/WorldStorage/MapSerializer.cpp
@@ -223,7 +223,11 @@ bool cIDCountSerializer::Load(void)
int CurrLine = NBT.FindChildByName(0, "map");
if (CurrLine >= 0)
{
- m_MapCount = (int)NBT.GetShort(CurrLine);
+ m_MapCount = (int)NBT.GetShort(CurrLine) + 1;
+ }
+ else
+ {
+ m_MapCount = 0;
}
return true;
@@ -237,7 +241,10 @@ bool cIDCountSerializer::Save(void)
{
cFastNBTWriter Writer;
- Writer.AddShort("map", m_MapCount);
+ if (m_MapCount > 0)
+ {
+ Writer.AddShort("map", m_MapCount - 1);
+ }
Writer.Finish();
diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h
index d9da107bc..296cc92c8 100644
--- a/src/WorldStorage/MapSerializer.h
+++ b/src/WorldStorage/MapSerializer.h
@@ -27,10 +27,10 @@ public:
cMapSerializer(const AString& a_WorldName, cMap * a_Map);
- /// Try to load the scoreboard
+ /** Try to load the scoreboard */
bool Load(void);
- /// Try to save the scoreboard
+ /** Try to save the scoreboard */
bool Save(void);
@@ -56,8 +56,10 @@ public:
cIDCountSerializer(const AString & a_WorldName);
+ /** Try to load the ID counts */
bool Load(void);
+ /** Try to save the ID counts */
bool Save(void);
inline unsigned int GetMapCount(void) const { return m_MapCount; }
@@ -70,6 +72,7 @@ private:
AString m_Path;
unsigned int m_MapCount;
+
};