Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: protocol 13.21 #1523

Merged
merged 15 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ function spell.onCastSpell(creature, var)
end

local grade = creature:revelationStageWOD("Executioner's Throw")
Spdlog.info(grade)
if grade == 0 then
creature:sendCancelMessage("You cannot cast this spell")
creature:getPosition():sendMagicEffect(CONST_ME_POFF)
Expand Down
Binary file modified data/items/appearances.dat
Binary file not shown.
24 changes: 24 additions & 0 deletions data/items/items.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37971,18 +37971,21 @@
<item id="25879" article="a" name="health cask">
<attribute key="description" value="This cask can be used to refill health potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item id="25880" article="a" name="strong health cask">
<attribute key="description" value="This cask can be used to refill strong health potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item id="25881" article="a" name="great health cask">
<attribute key="description" value="This cask can be used to refill great health potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
Expand All @@ -37995,19 +37998,22 @@
<item id="25883" article="a" name="supreme health cask">
<attribute key="description" value="This cask can be used to refill supreme health potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item fromid="25884" toid="25888" name="RESERVED SPRITE"/>
<item id="25889" article="a" name="mana cask">
<attribute key="description" value="This cask can be used to refill mana potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item id="25890" article="a" name="strong mana cask">
<attribute key="description" value="This cask can be used to refill strong mana potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
Expand All @@ -38020,96 +38026,112 @@
<item id="25892" article="an" name="ultimate mana cask">
<attribute key="description" value="This cask can be used to refill ultimate mana potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item id="25893" article="a" name="supreme mana cask">
<attribute key="description" value="This cask can be used to refill supreme mana potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item id="25899" article="a" name="great spirit cask">
<attribute key="description" value="This cask can be used to refill great spirit potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item id="25900" article="a" name="ultimate spirit cask">
<attribute key="description" value="This cask can be used to refill ultimate spirit potions"/>
<attribute key="charges" value="1000"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="200000"/>
</item>
<item id="25903" article="a" name="health keg">
<attribute key="description" value="This keg can be used to refill health potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="67500"/>
</item>
<item id="25904" article="a" name="strong health keg">
<attribute key="description" value="This keg can be used to refill strong health potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="72500"/>
</item>
<item id="25905" article="a" name="great health keg">
<attribute key="description" value="This keg can be used to refill great health potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="77500"/>
</item>
<item id="25906" article="an" name="ultimate health keg">
<attribute key="description" value="This keg can be used to refill ultimate health potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="77500"/>
</item>
<item id="25907" article="a" name="supreme health keg">
<attribute key="description" value="This keg can be used to refill supreme health potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="87500"/>
</item>
<item id="25908" article="a" name="mana keg">
<attribute key="description" value="This keg can be used to refill mana potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="67500"/>
</item>
<item id="25909" article="a" name="strong mana keg">
<attribute key="description" value="This keg can be used to refill strong mana potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="72500"/>
</item>
<item id="25910" article="a" name="great mana keg">
<attribute key="description" value="This keg can be used to refill great mana potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="77500"/>
</item>
<item id="25911" article="an" name="ultimate mana keg">
<attribute key="description" value="This keg can be used to refill ultimate mana potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="77500"/>
</item>
<item id="25912" article="a" name="supreme mana keg">
<attribute key="description" value="This keg can be used to refill supreme mana potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="12500"/>
</item>
<item id="25913" article="a" name="great spririt keg">
<attribute key="description" value="This keg can be used to refill great spririt potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="12500"/>
</item>
<item id="25914" article="an" name="ultimate spirit keg">
<attribute key="description" value="This keg can be used to refill ultimate spririt potions"/>
<attribute key="charges" value="500"/>
<attribute key="primarytype" value="consumable"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="weight" value="77500"/>
</item>
Expand Down Expand Up @@ -40302,10 +40324,12 @@
<item id="27661" article="an" name="alchemistic chair">
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="27662"/>
<attribute key="primarytype" value="furniture"/>
</item>
<item id="27662" article="an" name="alchemistic chair">
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="27661"/>
<attribute key="primarytype" value="furniture"/>
</item>
<item id="27663" article="an" name="alchemistic cabinet">
<attribute key="containersize" value="8"/>
Expand Down
9 changes: 5 additions & 4 deletions data/modules/scripts/gamestore/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1491,7 +1491,7 @@ function GameStore.processItemPurchase(player, offerId, offerCount, moveable)
end

local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
if inbox and inbox:getEmptySlots() > offerCount then
if inbox then
for t = 1, offerCount do
local inboxItem = inbox:addItem(offerId, offerCount or 1)
if moveable ~= true and inboxItem then
Expand All @@ -1509,7 +1509,7 @@ function GameStore.processChargesPurchase(player, itemtype, name, charges, movea
end

local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
if inbox and inbox:getEmptySlots() > 1 then
if inbox then
local inboxItem = inbox:addItem(itemtype, charges)

if moveable ~= true and inboxItem then
Expand Down Expand Up @@ -1570,7 +1570,7 @@ function GameStore.processStackablePurchase(player, offerId, offerCount, offerNa
end

local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
if inbox and inbox:getEmptySlots() > 0 then
if inbox then
if (isKeg and offerCount > 500) or offerCount > 100 then
local parcel = inbox:addItem(PARCEL_ID, 1)
parcel:setAttribute(ITEM_ATTRIBUTE_STORE, systemTime());
Expand Down Expand Up @@ -1627,7 +1627,7 @@ function GameStore.processHouseRelatedPurchase(player, offer)
if type(itemIds) ~= "table" then
itemIds = { itemIds }
end
if inbox and inbox:getEmptySlots() >= #itemIds then
if inbox then
for _, itemId in ipairs(itemIds) do
local decoKit = inbox:addItem(23398, 1)
if decoKit then
Expand All @@ -1642,6 +1642,7 @@ function GameStore.processHouseRelatedPurchase(player, offer)
end
end
end
player:sendUpdateContainer(inbox)
else
return error({ code = 0, message = "Please make sure you have free slots in your store inbox." })
end
Expand Down
2 changes: 1 addition & 1 deletion src/config/config_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ enum integerConfig_t {
STATUS_PORT,
STAIRHOP_DELAY,
MAX_CONTAINER,
MAX_ITEM,
MAX_CONTAINER_ITEM,
MARKET_OFFER_DURATION,
DEPOT_BOXES,
FREE_DEPOT_LIMIT,
Expand Down
2 changes: 1 addition & 1 deletion src/config/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ bool ConfigManager::load() {
integer[WHITE_SKULL_TIME] = getGlobalNumber(L, "whiteSkullTime", 15 * 60 * 1000);
integer[STAIRHOP_DELAY] = getGlobalNumber(L, "stairJumpExhaustion", 2000);
integer[MAX_CONTAINER] = getGlobalNumber(L, "maxContainer", 500);
integer[MAX_ITEM] = getGlobalNumber(L, "maxItem", 10000);
integer[MAX_CONTAINER_ITEM] = getGlobalNumber(L, "maxItem", 5000);
integer[EXP_FROM_PLAYERS_LEVEL_RANGE] = getGlobalNumber(L, "expFromPlayersLevelRange", 75);
integer[CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES] = getGlobalNumber(L, "checkExpiredMarketOffersEachMinutes", 60);
integer[MAX_MARKET_OFFERS_AT_A_TIME_PER_PLAYER] = getGlobalNumber(L, "maxMarketOffersAtATimePerPlayer", 100);
Expand Down
2 changes: 1 addition & 1 deletion src/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ static constexpr auto STATUS_SERVER_DEVELOPERS = "OpenTibiaBR Organization";
static constexpr auto AUTHENTICATOR_DIGITS = 6U;
static constexpr auto AUTHENTICATOR_PERIOD = 30U;

static constexpr auto CLIENT_VERSION = 1320;
static constexpr auto CLIENT_VERSION = 1321;

#define CLIENT_VERSION_UPPER (CLIENT_VERSION / 100)
#define CLIENT_VERSION_LOWER (CLIENT_VERSION % 100)
2 changes: 1 addition & 1 deletion src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,7 @@ void Player::onCloseContainer(const Container* container) {
}

void Player::onSendContainer(const Container* container) {
if (!client) {
if (!client || !container) {
return;
}

Expand Down
1 change: 1 addition & 0 deletions src/enums/item_attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum ItemAttribute_t : uint64_t {
STORE = 31,
CUSTOM = 32,
LOOTMESSAGE_SUFFIX = 33,
STORE_INBOX_CATEGORY = 34,
};

enum ItemDecayState_t : uint8_t {
Expand Down
23 changes: 19 additions & 4 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
#include "creatures/npcs/npc.hpp"
#include "creatures/npcs/npcs.hpp"
#include "server/network/webhook/webhook.hpp"
#include "protobuf/appearances.pb.hpp"
#include "protobuf/appearances.pb.h"
#include "server/network/protocol/protocollogin.hpp"
#include "server/network/protocol/protocolstatus.hpp"

Expand Down Expand Up @@ -612,7 +612,12 @@ Thing* Game::internalGetThing(Player* player, const Position &pos, int32_t index
}

uint8_t slot = pos.z;
return parentContainer->getItemByIndex(player->getContainerIndex(fromCid) + slot);
auto containerIndex = player->getContainerIndex(fromCid) + slot;
if (parentContainer->isStoreInboxFiltered()) {
return parentContainer->getFilteredItemByIndex(containerIndex);
}

return parentContainer->getItemByIndex(containerIndex);
} else if (pos.y == 0x20 || pos.y == 0x21) {
// '0x20' -> From depot.
// '0x21' -> From inbox.
Expand Down Expand Up @@ -1853,7 +1858,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder,
return retMaxCount;
}

// looting analyser from this point forward
// Actor related actions
if (fromCylinder && actor && toCylinder) {
if (!fromCylinder->getContainer() || !actor->getPlayer() || !toCylinder->getContainer()) {
return ret;
Expand All @@ -1870,9 +1875,13 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder,
return ret;
}

// Looting analyser
if (it.isCorpse && toCylinder->getContainer()->getTopParent() == player && item->getIsLootTrackeable()) {
player->sendLootStats(item, static_cast<uint8_t>(item->getItemCount()));
}

player->onSendContainer(toCylinder->getContainer());
dudantas marked this conversation as resolved.
Show resolved Hide resolved
player->onSendContainer(fromCylinder->getContainer());
}
}

Expand Down Expand Up @@ -4108,7 +4117,7 @@ void Game::playerStashWithdraw(uint32_t playerId, uint16_t itemId, uint32_t coun
}
}

void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index) {
void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index, uint8_t containerCategory) {
Player* player = getPlayerByID(playerId);
if (!player) {
return;
Expand All @@ -4119,6 +4128,12 @@ void Game::playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_
return;
}

if (container->getID() == ITEM_STORE_INBOX) {
auto enumName = magic_enum::enum_name(static_cast<StoreInboxCategory_t>(containerCategory)).data();
container->setAttribute(ItemAttribute_t::STORE_INBOX_CATEGORY, enumName);
g_logger().debug("Setting new container with store inbox category name {}", enumName);
}

if ((index % container->capacity()) != 0 || index >= container->size()) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/game/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "creatures/players/grouping/team_finder.hpp"
#include "utils/wildcardtree.hpp"
#include "items/items_classification.hpp"
#include "protobuf/appearances.pb.hpp"
#include "protobuf/appearances.pb.h"

class ServiceManager;
class Creature;
Expand Down Expand Up @@ -295,7 +295,7 @@ class Game {
void playerWrapableItem(uint32_t playerId, const Position &pos, uint8_t stackPos, const uint16_t itemId);
void playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std::string &text);
void playerBrowseField(uint32_t playerId, const Position &pos);
void playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index);
void playerSeekInContainer(uint32_t playerId, uint8_t containerId, uint16_t index, uint8_t containerCategory);
void playerUpdateHouseWindow(uint32_t playerId, uint8_t listId, uint32_t windowTextId, const std::string &text);
void playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t stackPos, uint32_t tradePlayerId, uint16_t itemId);
void playerAcceptTrade(uint32_t playerId);
Expand Down
Loading