Map item handler; Fixed several bugs
This commit is contained in:
parent
cf96e69716
commit
3b24bc870b
@ -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);
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
43
src/Items/ItemMap.h
Normal file
43
src/Items/ItemMap.h
Normal file
@ -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);
|
||||
}
|
||||
} ;
|
63
src/Map.cpp
63
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);
|
||||
|
13
src/Map.h
13
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;
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user