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

fix: use item and use with for guests in houses #1338

Merged
merged 15 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 13 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
7 changes: 5 additions & 2 deletions data-otservbr-global/scripts/actions/other/teleport.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
local upFloorIds = {1948, 1968, 5542, 20474, 20475, 1968, 28656, 31262, 31129, 31130, 34243}
local ladderTable = Game.getLadderIds()

local upFloorIds = ladderTable

local teleport = Action()

Expand All @@ -12,5 +14,6 @@ function teleport.onUse(player, item, fromPosition, target, toPosition, isHotkey
return true
end

teleport:id(435, 1948, 1968, 5542, 20474, 20475, 28656, 31129, 31130, 31262, 34243)
teleport:id(435)
teleport:id(unpack(ladderTable))
teleport:register()
58 changes: 50 additions & 8 deletions data/items/items.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2675,7 +2675,9 @@
<item id="1947" name="stairs">
<attribute key="floorchange" value="north"/>
</item>
<item id="1948" article="a" name="ladder"/>
<item id="1948" article="a" name="ladder">
<attribute key="type" value="ladder"/>
</item>
<item id="1949" article="a" name="magic forcefield">
<attribute key="type" value="teleport"/>
<attribute key="description" value="You can see the other side through it."/>
Expand Down Expand Up @@ -2721,7 +2723,9 @@
<attribute key="floorchange" value="north"/>
</item>
<item id="1967" article="a" name="ramp"/>
<item id="1968" article="a" name="ladder"/>
<item id="1968" article="a" name="ladder">
<attribute key="type" value="ladder"/>
</item>
<item id="1969" article="a" name="ramp">
<attribute key="floorchange" value="east"/>
</item>
Expand Down Expand Up @@ -11075,7 +11079,9 @@
<attribute key="decayTo" value="0"/>
<attribute key="weight" value="4000"/>
</item>
<item id="5542" article="a" name="rope-ladder"/>
<item id="5542" article="a" name="rope-ladder">
<attribute key="type" value="ladder"/>
</item>
<item id="5543" article="a" name="cart"/>
<item id="5544" article="a" name="trapdoor">
<attribute key="floorchange" value="down"/>
Expand Down Expand Up @@ -31520,7 +31526,9 @@
<item fromid="20469" toid="20473" name="ladder rung">
<attribute key="floorchange" value="down"/>
</item>
<item fromid="20474" toid="20475" name="ladder rung"/>
<item fromid="20474" toid="20475" name="ladder rung">
<attribute key="type" value="ladder"/>
</item>
<item fromid="20476" toid="20477" article="a" name="wall"/>
<item fromid="20478" toid="20479" article="a" name="city foundation"/>
<item fromid="20480" toid="20485" article="a" name="buttress"/>
Expand Down Expand Up @@ -40932,39 +40940,63 @@
</item>
<item id="28558" article="an" name="exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this exercise dummy."/>
<attribute key="type" value="dummy">
<attribute key="premium" value="0"/>
</attribute>
</item>
<item id="28559" article="a" name="ferumbras exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this expert exercise dummy"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="28560"/>
<attribute key="type" value="dummy">
<attribute key="premium" value="1"/>
</attribute>
</item>
<item id="28560" article="a" name="ferumbras exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this expert exercise dummy"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="28559"/>
<attribute key="type" value="dummy">
<attribute key="premium" value="1"/>
</attribute>
</item>
<item id="28561" article="a" name="demon exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this expert exercise dummy"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="28562"/>
<attribute key="type" value="dummy">
<attribute key="premium" value="1"/>
</attribute>
</item>
<item id="28562" article="a" name="demon exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this expert exercise dummy"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="28561"/>
<attribute key="type" value="dummy">
<attribute key="premium" value="1"/>
</attribute>
</item>
<item id="28563" article="a" name="monk exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this expert exercise dummy"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="28564"/>
<attribute key="type" value="dummy">
<attribute key="premium" value="1"/>
</attribute>
</item>
<item id="28564" article="a" name="monk exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this expert exercise dummy"/>
<attribute key="wrapableto" value="23398"/>
<attribute key="rotateto" value="28563"/>
<attribute key="type" value="dummy">
<attribute key="premium" value="1"/>
</attribute>
</item>
<item id="28565" article="an" name="exercise dummy">
<attribute key="description" value="You can train your skills by using training weapons with this exercise dummy."/>
<attribute key="type" value="dummy">
<attribute key="premium" value="0"/>
</attribute>
</item>
<item id="28566" article="a" name="silken bookmark">
<attribute key="weight" value="100"/>
Expand Down Expand Up @@ -41364,7 +41396,9 @@
<item id="28655" article="a" name="hole">
<attribute key="floorchange" value="down"/>
</item>
<item id="28656" article="a" name="ladder"/>
<item id="28656" article="a" name="ladder">
<attribute key="type" value="ladder"/>
</item>
<item id="28657" name="unknown item"/>
<item fromid="28658" toid="28659" article="a" name="closed door">
<attribute key="type" value="door"/>
Expand Down Expand Up @@ -44588,9 +44622,11 @@
</item>
<item id="31129" article="a" name="wooden ladder">
<attribute key="floorchange" value="north"/>
<attribute key="type" value="ladder"/>
</item>
<item id="31130" article="a" name="wooden ladder">
<attribute key="floorchange" value="west"/>
<attribute key="type" value="ladder"/>
</item>
<item fromid="31131" toid="31133" article="a" name="obelisk"/>
<item fromid="31134" toid="31138" name="RESERVED SPRITE"/>
Expand Down Expand Up @@ -44792,7 +44828,9 @@
<item id="31261" article="a" name="box with waterproof balm">
<attribute key="weight" value="240"/>
</item>
<item id="31262" article="a" name="ladder"/>
<item id="31262" article="a" name="ladder">
<attribute key="type" value="ladder"/>
</item>
<item id="31263" article="a" name="Ring of Secret Thoughts">
<attribute key="weight" value="90"/>
</item>
Expand Down Expand Up @@ -49089,7 +49127,9 @@
<attribute key="blockProjectile" value="1"/>
</item>
<item id="33769" article="a" name="smoke"/>
<item id="33770" article="a" name="ladder"/>
<item id="33770" article="a" name="ladder">
<attribute key="type" value="ladder"/>
</item>
<item fromid="33772" toid="33774" article="a" name="pool"/>
<item id="33776" article="a" name="bard doll">
<attribute key="description" value="A mythical bard rumoured to magically appear in Tibian taverns with a lute and a mug to tell amazing and funny stories. Granted by Tibiaria.com"/>
Expand Down Expand Up @@ -50824,7 +50864,9 @@
<item fromid="34228" toid="34231" article="a" name="statue"/>
<item id="34237" name="dead frog"/>
<item id="34238" article="a" name="paper"/>
<item id="34243" article="a" name="ladder"/>
<item id="34243" article="a" name="ladder">
<attribute key="type" value="ladder"/>
</item>
<item id="34244" article="a" name="dead white lion">
<attribute key="duration" value="10"/>
<attribute key="decayTo" value="34245"/>
Expand Down
6 changes: 4 additions & 2 deletions data/libs/exercise_training.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ ExerciseWeaponsTable = {
[35290] = { skill = SKILL_MAGLEVEL, effect = CONST_ANI_FIRE, allowFarUse = true }
}

FreeDummies = {28558, 28565}
local dummyIds = Game.getDummyIds()
FreeDummies = {unpack(dummyIds[false])}
HouseDummies = {unpack(dummyIds[true])}

MaxAllowedOnADummy = configManager.getNumber(configKeys.MAX_ALLOWED_ON_A_DUMMY)
HouseDummies = {28559, 28560, 28561, 28562, 28563, 28564}

local magicLevelRate = configManager.getNumber(configKeys.RATE_MAGIC)
local skillLevelRate = configManager.getNumber(configKeys.RATE_SKILL)
Expand Down
82 changes: 66 additions & 16 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,66 @@ namespace InternalGame {
}
}

bool playerCanUseItemOnHouseTile(Player* player, Item* item) {
if (!player || !item) {
return false;
}

auto itemTile = item->getTile();
if (!itemTile) {
return false;
}

if (HouseTile* houseTile = dynamic_cast<HouseTile*>(itemTile)) {
House* house = houseTile->getHouse();
if (!house || !house->isInvited(player)) {
return false;
}

auto isGuest = house->getHouseAccessLevel(player) == HOUSE_GUEST;
auto itemParentContainer = item->getParent() ? item->getParent()->getContainer() : nullptr;
auto isItemParentContainerBrowseField = itemParentContainer && itemParentContainer->getID() == ITEM_BROWSEFIELD;
if (isGuest && isItemParentContainerBrowseField) {
return false;
}

auto realItemParent = item->getRealParent();
auto isItemInGuestInventory = realItemParent && (realItemParent == player || realItemParent->getContainer());
if (isGuest && !isItemInGuestInventory && !item->isLadder()) {
return false;
}
}

return true;
}

bool playerCanUseItemWithOnHouseTile(Player* player, Item* item, const Position &toPos, int toStackPos, int toItemId) {
if (!player || !item) {
return false;
}

auto itemTile = item->getTile();
if (!itemTile) {
return false;
}

if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) {
if (HouseTile* houseTile = dynamic_cast<HouseTile*>(itemTile)) {
House* house = houseTile->getHouse();
Thing* targetThing = g_game().internalGetThing(player, toPos, toStackPos, toItemId, STACKPOS_FIND_THING);
auto targetItem = targetThing ? targetThing->getItem() : nullptr;
uint16_t targetId = targetItem ? targetItem->getID() : 0;
auto invitedCheckUseWith = house && item->getRealParent() && item->getRealParent() != player && (!house->isInvited(player) || house->getHouseAccessLevel(player) == HOUSE_GUEST);
if (targetId != 0 && targetItem && !targetItem->isDummy() && invitedCheckUseWith) {
player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT);
return false;
}
}
}

return true;
}

} // Namespace InternalGame

Game::Game() {
Expand Down Expand Up @@ -3047,14 +3107,9 @@ void Game::playerUseItemEx(uint32_t playerId, const Position &fromPos, uint8_t f
return;
}

if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) {
if (HouseTile* houseTile = dynamic_cast<HouseTile*>(item->getTile())) {
House* house = houseTile->getHouse();
if (house && item->getRealParent() && item->getRealParent() != player && (!house->isInvited(player) || house->getHouseAccessLevel(player) == HOUSE_GUEST)) {
player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT);
return;
}
}
if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS) && !InternalGame::playerCanUseItemWithOnHouseTile(player, item, toPos, toStackPos, toItemId)) {
player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT);
return;
}

Position walkToPos = fromPos;
Expand Down Expand Up @@ -3181,14 +3236,9 @@ void Game::playerUseItem(uint32_t playerId, const Position &pos, uint8_t stackPo
return;
}

if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS)) {
if (HouseTile* houseTile = dynamic_cast<HouseTile*>(item->getTile())) {
House* house = houseTile->getHouse();
if (house && item->getRealParent() && item->getRealParent() != player && (!house->isInvited(player) || house->getHouseAccessLevel(player) == HOUSE_GUEST)) {
player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT);
return;
}
}
if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS) && !InternalGame::playerCanUseItemOnHouseTile(player, item)) {
player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT);
return;
}

const ItemType &it = Item::items[item->getID()];
Expand Down
30 changes: 28 additions & 2 deletions src/items/functions/item/item_parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

void ItemParse::initParse(const std::string &tmpStrValue, pugi::xml_node attributeNode, pugi::xml_attribute valueAttribute, ItemType &itemType) {
// Parse all item attributes
ItemParse::parseType(tmpStrValue, valueAttribute, itemType);
ItemParse::parseType(tmpStrValue, attributeNode, valueAttribute, itemType);
ItemParse::parseDescription(tmpStrValue, valueAttribute, itemType);
ItemParse::parseRuneSpellName(tmpStrValue, valueAttribute, itemType);
ItemParse::parseWeight(tmpStrValue, valueAttribute, itemType);
Expand Down Expand Up @@ -74,7 +74,27 @@ void ItemParse::initParse(const std::string &tmpStrValue, pugi::xml_node attribu
ItemParse::parseReflectDamage(tmpStrValue, valueAttribute, itemType);
}

void ItemParse::parseType(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType) {
void ItemParse::parseDummyPremium(pugi::xml_node attributeNode, ItemType &itemType) {
for (auto subAttributeNode : attributeNode.children()) {
pugi::xml_attribute subKeyAttribute = subAttributeNode.attribute("key");
if (!subKeyAttribute) {
continue;
}

pugi::xml_attribute subValueAttribute = subAttributeNode.attribute("value");
if (!subValueAttribute) {
continue;
}

auto stringValue = asLowerCaseString(subKeyAttribute.as_string());
if (stringValue == "premium") {
bool isPremium = subValueAttribute.as_bool();
Item::items.addDummyId(itemType.id, isPremium);
}
}
}

void ItemParse::parseType(const std::string &tmpStrValue, pugi::xml_node attributeNode, pugi::xml_attribute valueAttribute, ItemType &itemType) {
std::string stringValue = tmpStrValue;
if (stringValue == "type") {
stringValue = asLowerCaseString(valueAttribute.as_string());
Expand All @@ -84,6 +104,12 @@ void ItemParse::parseType(const std::string &tmpStrValue, pugi::xml_attribute va
if (itemType.type == ITEM_TYPE_CONTAINER) {
itemType.group = ITEM_GROUP_CONTAINER;
}
if (itemType.type == ITEM_TYPE_LADDER) {
Item::items.addLadderId(itemType.id);
}
if (itemType.type == ITEM_TYPE_DUMMY) {
parseDummyPremium(attributeNode, itemType);
}
} else {
SPDLOG_WARN("[Items::parseItemNode] - Unknown type: {}", valueAttribute.as_string());
}
Expand Down
8 changes: 6 additions & 2 deletions src/items/functions/item/item_parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ const phmap::flat_hash_map<std::string, ItemTypes_t> ItemTypesMap = {
{ "food", ITEM_TYPE_FOOD },
{ "valuable", ITEM_TYPE_VALUABLE },
{ "potion", ITEM_TYPE_POTION },

{ "ladder", ITEM_TYPE_LADDER },
{ "dummy", ITEM_TYPE_DUMMY },
};

const phmap::flat_hash_map<std::string, TileFlags_t> TileStatesMap = {
Expand Down Expand Up @@ -246,8 +249,9 @@ class ItemParse : public Items {
public:
static void initParse(const std::string &tmpStrValue, pugi::xml_node attributeNode, pugi::xml_attribute valueAttribute, ItemType &itemType);

protected:
static void parseType(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType);
private:
static void parseDummyPremium(pugi::xml_node attributeNode, ItemType &itemType);
static void parseType(const std::string &tmpStrValue, pugi::xml_node attributeNode, pugi::xml_attribute valueAttribute, ItemType &itemType);
static void parseDescription(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType);
static void parseRuneSpellName(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType);
static void parseWeight(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType);
Expand Down
6 changes: 6 additions & 0 deletions src/items/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,12 @@ class Item : virtual public Thing, public ItemProperties {
bool isSpellBook() const {
return items[id].isSpellBook();
}
bool isLadder() const {
return items[id].isLadder();
}
bool isDummy() const {
return items[id].isDummy();
}

const std::string &getName() const {
if (hasAttribute(ItemAttribute_t::NAME)) {
Expand Down
2 changes: 2 additions & 0 deletions src/items/items.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Items::Items() = default;

void Items::clear() {
items.clear();
ladders.clear();
dummys.clear();
nameToItems.clear();
}

Expand Down
Loading