mirror of
https://github.com/edubart/otclient.git
synced 2025-10-16 12:34:55 +02:00
Browse field, locked & paginated container support
This commit is contained in:
@@ -389,6 +389,7 @@ namespace Otc
|
||||
GameHideNpcNames = 55,
|
||||
GameSpritesAlphaChannel = 56,
|
||||
GamePremiumExpiration = 57,
|
||||
GameBrowseField = 58,
|
||||
|
||||
LastGameFeature = 101
|
||||
};
|
||||
|
@@ -57,9 +57,22 @@ void Container::onClose()
|
||||
|
||||
void Container::onAddItem(const ItemPtr& item, int slot)
|
||||
{
|
||||
m_items.push_front(item);
|
||||
slot -= m_firstIndex;
|
||||
|
||||
m_size++;
|
||||
// indicates that there is a new item on next page
|
||||
if(m_hasPages && slot > m_capacity) {
|
||||
callLuaField("onSizeChange", m_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if(slot == 0)
|
||||
m_items.push_front(item);
|
||||
else
|
||||
m_items.push_back(item);
|
||||
updateItemsPositions();
|
||||
|
||||
callLuaField("onSizeChange", m_size);
|
||||
callLuaField("onAddItem", slot, item);
|
||||
}
|
||||
|
||||
@@ -80,6 +93,7 @@ void Container::onAddItems(const std::vector<ItemPtr>& items)
|
||||
|
||||
void Container::onUpdateItem(int slot, const ItemPtr& item)
|
||||
{
|
||||
slot -= m_firstIndex;
|
||||
if(slot < 0 || slot >= (int)m_items.size()) {
|
||||
g_logger.traceError("slot not found");
|
||||
return;
|
||||
@@ -92,8 +106,15 @@ void Container::onUpdateItem(int slot, const ItemPtr& item)
|
||||
callLuaField("onUpdateItem", slot, item, oldItem);
|
||||
}
|
||||
|
||||
void Container::onRemoveItem(int slot)
|
||||
void Container::onRemoveItem(int slot, const ItemPtr& lastItem)
|
||||
{
|
||||
slot -= m_firstIndex;
|
||||
if(m_hasPages && slot >= (int)m_items.size()) {
|
||||
m_size--;
|
||||
callLuaField("onSizeChange", m_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if(slot < 0 || slot >= (int)m_items.size()) {
|
||||
g_logger.traceError("slot not found");
|
||||
return;
|
||||
@@ -102,8 +123,16 @@ void Container::onRemoveItem(int slot)
|
||||
ItemPtr item = m_items[slot];
|
||||
m_items.erase(m_items.begin() + slot);
|
||||
|
||||
|
||||
if(lastItem) {
|
||||
onAddItem(lastItem, m_firstIndex + m_capacity - 1);
|
||||
m_size--;
|
||||
}
|
||||
m_size--;
|
||||
|
||||
updateItemsPositions();
|
||||
|
||||
callLuaField("onSizeChange", m_size);
|
||||
callLuaField("onRemoveItem", slot, item);
|
||||
}
|
||||
|
||||
|
@@ -57,7 +57,7 @@ protected:
|
||||
void onAddItem(const ItemPtr& item, int slot);
|
||||
void onAddItems(const std::vector<ItemPtr>& items);
|
||||
void onUpdateItem(int slot, const ItemPtr& item);
|
||||
void onRemoveItem(int slot);
|
||||
void onRemoveItem(int slot, const ItemPtr& lastItem);
|
||||
|
||||
friend class Game;
|
||||
|
||||
|
@@ -308,7 +308,9 @@ void Game::processCloseContainer(int containerId)
|
||||
{
|
||||
ContainerPtr container = getContainer(containerId);
|
||||
if(!container) {
|
||||
g_logger.traceError("container not found");
|
||||
/* happens if you close and restart client with container opened
|
||||
* g_logger.traceError("container not found");
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -338,7 +340,7 @@ void Game::processContainerUpdateItem(int containerId, int slot, const ItemPtr&
|
||||
container->onUpdateItem(slot, item);
|
||||
}
|
||||
|
||||
void Game::processContainerRemoveItem(int containerId, int slot)
|
||||
void Game::processContainerRemoveItem(int containerId, int slot, const ItemPtr& lastItem)
|
||||
{
|
||||
ContainerPtr container = getContainer(containerId);
|
||||
if(!container) {
|
||||
@@ -346,7 +348,7 @@ void Game::processContainerRemoveItem(int containerId, int slot)
|
||||
return;
|
||||
}
|
||||
|
||||
container->onRemoveItem(slot);
|
||||
container->onRemoveItem(slot, lastItem);
|
||||
}
|
||||
|
||||
void Game::processInventoryChange(int slot, const ItemPtr& item)
|
||||
@@ -1404,6 +1406,20 @@ void Game::answerModalDialog(int dialog, int button, int choice)
|
||||
m_protocolGame->sendAnswerModalDialog(dialog, button, choice);
|
||||
}
|
||||
|
||||
void Game::browseField(const Position& position)
|
||||
{
|
||||
if(!canPerformGameAction())
|
||||
return;
|
||||
m_protocolGame->sendBrowseField(position);
|
||||
}
|
||||
|
||||
void Game::seekInContainer(int cid, int index)
|
||||
{
|
||||
if(!canPerformGameAction())
|
||||
return;
|
||||
m_protocolGame->sendSeekInContainer(cid, index);
|
||||
}
|
||||
|
||||
void Game::ping()
|
||||
{
|
||||
if(!m_protocolGame || !m_protocolGame->isConnected())
|
||||
@@ -1558,6 +1574,10 @@ void Game::setProtocolVersion(int version)
|
||||
enableFeature(Otc::GameThingMarks);
|
||||
}
|
||||
|
||||
if(version >= 984) {
|
||||
enableFeature(Otc::GameBrowseField);
|
||||
}
|
||||
|
||||
if(version >= 1000) {
|
||||
enableFeature(Otc::GamePVPMode);
|
||||
}
|
||||
|
@@ -85,7 +85,7 @@ protected:
|
||||
void processCloseContainer(int containerId);
|
||||
void processContainerAddItem(int containerId, const ItemPtr& item, int slot);
|
||||
void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item);
|
||||
void processContainerRemoveItem(int containerId, int slot);
|
||||
void processContainerRemoveItem(int containerId, int slot, const ItemPtr& lastItem);
|
||||
|
||||
// channel related
|
||||
void processChannelList(const std::vector<std::tuple<int, std::string> >& channelList);
|
||||
@@ -258,6 +258,10 @@ public:
|
||||
// >= 970 modal dialog
|
||||
void answerModalDialog(int dialog, int button, int choice);
|
||||
|
||||
// >= 984 browse field
|
||||
void browseField(const Position& position);
|
||||
void seekInContainer(int cid, int index);
|
||||
|
||||
//void reportRuleViolation2();
|
||||
void ping();
|
||||
void setPingDelay(int delay) { m_pingDelay = delay; }
|
||||
|
@@ -295,6 +295,8 @@ void Client::registerLuaFunctions()
|
||||
g_lua.bindSingletonFunction("g_game", "disableFeature", &Game::disableFeature, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isGM", &Game::isGM, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "answerModalDialog", &Game::answerModalDialog, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "browseField", &Game::browseField, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "seekInContainer", &Game::seekInContainer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getLastWalkDir", &Game::getLastWalkDir, &g_game);
|
||||
|
||||
g_lua.registerSingletonClass("g_shaders");
|
||||
|
@@ -228,6 +228,8 @@ namespace Proto {
|
||||
ClientCancelAttackAndFollow = 190,
|
||||
ClientUpdateTile = 201,
|
||||
ClientRefreshContainer = 202,
|
||||
ClientBrowseField = 203,
|
||||
ClientSeekInContainer = 204,
|
||||
ClientRequestOutfit = 210,
|
||||
ClientChangeOutfit = 211,
|
||||
ClientMount = 212, // 870
|
||||
|
@@ -111,6 +111,8 @@ public:
|
||||
void sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation);
|
||||
void sendRequestItemInfo(int itemId, int subType, int index);
|
||||
void sendAnswerModalDialog(int dialog, int button, int choice);
|
||||
void sendBrowseField(const Position& position);
|
||||
void sendSeekInContainer(int cid, int index);
|
||||
|
||||
// otclient only
|
||||
void sendChangeMapAwareRange(int xrange, int yrange);
|
||||
|
@@ -686,16 +686,17 @@ void ProtocolGame::parseContainerRemoveItem(const InputMessagePtr& msg)
|
||||
{
|
||||
int containerId = msg->getU8();
|
||||
int slot;
|
||||
ItemPtr lastItem;
|
||||
if(g_game.getFeature(Otc::GameContainerPagination)) {
|
||||
slot = msg->getU16();
|
||||
|
||||
int itemId = msg->getU16();
|
||||
if(itemId != 0)
|
||||
getItem(msg, itemId);
|
||||
lastItem = getItem(msg, itemId);
|
||||
} else {
|
||||
slot = msg->getU8();
|
||||
}
|
||||
g_game.processContainerRemoveItem(containerId, slot);
|
||||
g_game.processContainerRemoveItem(containerId, slot, lastItem);
|
||||
}
|
||||
|
||||
void ProtocolGame::parseAddInventoryItem(const InputMessagePtr& msg)
|
||||
|
@@ -831,6 +831,29 @@ void ProtocolGame::sendAnswerModalDialog(int dialog, int button, int choice)
|
||||
send(msg);
|
||||
}
|
||||
|
||||
void ProtocolGame::sendBrowseField(const Position& position)
|
||||
{
|
||||
if(!g_game.getFeature(Otc::GameBrowseField))
|
||||
return;
|
||||
|
||||
OutputMessagePtr msg(new OutputMessage);
|
||||
msg->addU8(Proto::ClientBrowseField);
|
||||
addPosition(msg, position);
|
||||
send(msg);
|
||||
}
|
||||
|
||||
void ProtocolGame::sendSeekInContainer(int cid, int index)
|
||||
{
|
||||
if(!g_game.getFeature(Otc::GameContainerPagination))
|
||||
return;
|
||||
|
||||
OutputMessagePtr msg(new OutputMessage);
|
||||
msg->addU8(Proto::ClientSeekInContainer);
|
||||
msg->addU8(cid);
|
||||
msg->addU16(index);
|
||||
send(msg);
|
||||
}
|
||||
|
||||
void ProtocolGame::sendChangeMapAwareRange(int xrange, int yrange)
|
||||
{
|
||||
if(!g_game.getFeature(Otc::GameChangeMapAwareRange))
|
||||
|
Reference in New Issue
Block a user