1
0

Map item handler; Fixed several bugs

This commit is contained in:
andrew 2014-02-17 16:27:12 +02:00
parent cf96e69716
commit 3b24bc870b
13 changed files with 195 additions and 29 deletions

View File

@ -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);
}

View File

@ -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())

View File

@ -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:

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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
View 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);
}
} ;

View File

@ -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);

View File

@ -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;

View File

@ -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());
}
}
}

View File

@ -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();

View File

@ -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;
};