Skip to content

Instantly share code, notes, and snippets.

@dbjorkholm
Last active November 28, 2016 22:53
Show Gist options
  • Save dbjorkholm/ec6a8ef25072482ea688 to your computer and use it in GitHub Desktop.
Save dbjorkholm/ec6a8ef25072482ea688 to your computer and use it in GitHub Desktop.
Equip Hotkey
From 78f6fef7a9083f28d06b203cd9d863a9f6f7dc6d Tue, 15 Mar 2016 00:08:42 +0100
From: Daniel Björkholm <danielbjorkholm@gmail.com>
Date: Tue, 15 Mar 2016 00:08:42 +0100
Subject: [PATCH] Equip Hotkey
---
creature.h | 11 +++++++++++
player.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++
player.h | 7 +++++++
protocolgame.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
protocolgame.h | 2 ++
5 files changed, 127 insertions(+)
diff --git a/creature.h b/creature.h
index 06c4a86..7c7734d 100644
--- a/creature.h
+++ b/creature.h
@@ -48,6 +48,17 @@ enum slots_t : uint8_t {
CONST_SLOT_LAST = CONST_SLOT_AMMO,
};
+enum clientSlots_t : uint16_t {
+ CLIENT_SLOT_HAND = 48,
+ CLIENT_SLOT_HEAD = 49,
+ CLIENT_SLOT_NECKLACE = 50,
+ CLIENT_SLOT_ARMOR = 56,
+ CLIENT_SLOT_LEGS = 112,
+ CLIENT_SLOT_FEET = 176,
+ CLIENT_SLOT_RING = 304,
+ CLIENT_SLOT_AMMO = 560,
+};
+
struct FindPathParams {
bool fullPathSearch;
bool clearSight;
diff --git a/player.cpp b/player.cpp
index 04b1097..37ab415 100644
--- a/player.cpp
+++ b/player.cpp
@@ -3040,6 +3040,51 @@ std::map<uint32_t, uint32_t>& Player::getAllItemTypeCount(std::map<uint32_t, uin
return countMap;
}
+Item* Player::getItemByClientId(uint16_t clientId) const
+{
+ for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) {
+ Item* item = inventory[i];
+ if (!item) {
+ continue;
+ }
+
+ if (item->getClientID() == clientId) {
+ return item;
+ }
+
+ if (Container* container = item->getContainer()) {
+ for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) {
+ if ((*it)->getClientID() == clientId) {
+ return (*it);
+ }
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+std::map<uint16_t, uint16_t> Player::getInventoryClientIds() const
+{
+ std::map<uint16_t, uint16_t> itemMap;
+ for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) {
+ Item* item = inventory[i];
+ if (!item) {
+ continue;
+ }
+
+ itemMap.emplace(item->getClientID(), Item::countByType(item, -1));
+
+ if (Container* container = item->getContainer()) {
+ for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) {
+ itemMap.emplace((*it)->getClientID(), Item::countByType(*it, -1));
+ }
+ }
+ }
+
+ return itemMap;
+}
+
Thing* Player::getThing(size_t index) const
{
if (index >= CONST_SLOT_FIRST && index <= CONST_SLOT_LAST) {
@@ -3072,6 +3117,7 @@ void Player::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_
updateInventoryWeight();
updateItemsLight();
+ sendInventoryClientIds();
sendStats();
}
@@ -3126,6 +3172,7 @@ void Player::postRemoveNotification(Thing* thing, const Cylinder* newParent, int
updateInventoryWeight();
updateItemsLight();
+ sendInventoryClientIds();
sendStats();
}
diff --git a/player.h b/player.h
index 9eea383..994f2c8 100644
--- a/player.h
+++ b/player.h
@@ -851,6 +851,11 @@ class Player final : public Creature, public Cylinder
client->sendInventoryItem(slot, item);
}
}
+ void sendInventoryClientIds() {
+ if (client) {
+ client->sendInventoryClientIds();
+ }
+ }
//event methods
void onUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem,
@@ -1178,6 +1183,8 @@ class Player final : public Creature, public Cylinder
size_t getLastIndex() const final;
uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const final;
std::map<uint32_t, uint32_t>& getAllItemTypeCount(std::map<uint32_t, uint32_t> &countMap) const final;
+ Item* getItemByClientId(uint16_t clientId) const;
+ std::map<uint16_t, uint16_t> getInventoryClientIds() const;
Thing*getThing(size_t index) const final;
void internalAddThing(Thing* thing) final;
diff --git a/protocolgame.cpp b/protocolgame.cpp
index 85a42d3..bc7693e 100644
--- a/protocolgame.cpp
+++ b/protocolgame.cpp
@@ -432,6 +432,7 @@ void ProtocolGame::parsePacket(NetworkMessage& msg)
case 0x70: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), DIRECTION_EAST); break;
case 0x71: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), DIRECTION_SOUTH); break;
case 0x72: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), DIRECTION_WEST); break;
+ case 0x77: parseEquipObject(msg); break;
case 0x78: parseThrow(msg); break;
case 0x79: parseLookInShop(msg); break;
case 0x7A: parsePlayerPurchase(msg); break;
@@ -818,6 +819,41 @@ void ProtocolGame::parseUpdateContainer(NetworkMessage& msg)
addGameTask(&Game::playerUpdateContainer, player->getID(), cid);
}
+void ProtocolGame::parseEquipObject(NetworkMessage& msg)
+{
+ uint16_t objectId = msg.get<uint16_t>();
+ //uint8_t data = msg.get<uint8_t>();
+
+ if (!player->canDoAction()) {
+ return;
+ }
+
+ Item* item = player->getItemByClientId(objectId);
+ if (!item) {
+ return;
+ }
+
+ uint16_t slot = CONST_SLOT_WHEREEVER;
+ switch (item->getSlotPosition()) {
+ case CLIENT_SLOT_HEAD: slot = CONST_SLOT_HEAD; break;
+ case CLIENT_SLOT_NECKLACE: slot = CONST_SLOT_NECKLACE; break;
+ case CLIENT_SLOT_ARMOR: slot = CONST_SLOT_ARMOR; break;
+ case CLIENT_SLOT_HAND: slot = item->getWeaponType() != WEAPON_SHIELD ? CONST_SLOT_LEFT : CONST_SLOT_RIGHT; break;
+ case CLIENT_SLOT_RING: slot = CONST_SLOT_RING; break;
+ case CLIENT_SLOT_LEGS: slot = CONST_SLOT_LEGS; break;
+ case CLIENT_SLOT_FEET: slot = CONST_SLOT_FEET; break;
+ case CLIENT_SLOT_AMMO: slot = CONST_SLOT_AMMO; break;
+
+ default:
+ break;
+ }
+
+ player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::ACTIONS_DELAY_INTERVAL));
+
+ Item* slotItem = player->getInventoryItem(static_cast<slots_t>(slot));
+ g_game.internalMoveItem(item->getParent(), player, (slotItem && slotItem == item ? CONST_SLOT_WHEREEVER : slot), item, item->getItemCount(), nullptr);
+}
+
void ProtocolGame::parseThrow(NetworkMessage& msg)
{
Position fromPos = msg.getPosition();
@@ -2453,6 +2489,7 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position& pos
}
sendBasicData();
+ sendInventoryClientIds();
player->sendIcons();
}
@@ -2533,6 +2570,29 @@ void ProtocolGame::sendInventoryItem(slots_t slot, const Item* item)
writeToOutputBuffer(msg);
}
+void ProtocolGame::sendInventoryClientIds()
+{
+ std::map<uint16_t, uint16_t> items = player->getInventoryClientIds();
+
+ NetworkMessage msg;
+ msg.addByte(0xF5);
+ msg.add<uint16_t>(items.size() + 11);
+
+ for (uint16_t i = 1; i <= 11; i++) {
+ msg.add<uint16_t>(i);
+ msg.addByte(0x00);
+ msg.add<uint16_t>(0x01);
+ }
+
+ for (const auto& it : items) {
+ msg.add<uint16_t>(it.first);
+ msg.addByte(0x00);
+ msg.add<uint16_t>(it.second);
+ }
+
+ writeToOutputBuffer(msg);
+}
+
void ProtocolGame::sendAddContainerItem(uint8_t cid, uint16_t slot, const Item* item)
{
NetworkMessage msg;
diff --git a/protocolgame.h b/protocolgame.h
index 785ee86..0dd0421 100644
--- a/protocolgame.h
+++ b/protocolgame.h
@@ -113,6 +113,7 @@ class ProtocolGame final : public Protocol
void parseBugReport(NetworkMessage& msg);
void parseDebugAssert(NetworkMessage& msg);
+ void parseEquipObject(NetworkMessage& msg);
void parseThrow(NetworkMessage& msg);
void parseUseItemEx(NetworkMessage& msg);
void parseUseWithCreature(NetworkMessage& msg);
@@ -268,6 +269,7 @@ class ProtocolGame final : public Protocol
//inventory
void sendInventoryItem(slots_t slot, const Item* item);
+ void sendInventoryClientIds();
//messages
void sendModalWindow(const ModalWindow& modalWindow);
--
2.6.3.windows.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment