Skip to content

Commit

Permalink
fix: monsters/summons can walk no-walkable items after set unique id (o…
Browse files Browse the repository at this point in the history
…pentibiabr#856)

This fixes an issue where monsters and summons could walk on non-walkable items after their unique ID had been set. The fix ensures that the pathfinding algorithm takes these non-walkable items into account when moving the monsters and summons, preventing them from moving through areas that are designated as non-walkable.
  • Loading branch information
ElimarCosta authored Feb 17, 2023
1 parent bd872b9 commit 5c53a39
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 10 deletions.
6 changes: 2 additions & 4 deletions data/events/scripts/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,7 @@ local function antiPush(self, item, count, fromPosition, toPosition, fromCylinde
end

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
-- No move items with actionID = 100
if item:getActionId() == NOT_MOVEABLE_ACTION then
if item:getActionId() == IMMOVABLE_ACTION_ID then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return false
end
Expand Down Expand Up @@ -582,8 +581,7 @@ function Player:onTurn(direction)
end

function Player:onTradeRequest(target, item)
-- No trade items with actionID = 100
if item:getActionId() == NOT_MOVEABLE_ACTION then
if item:getActionId() == IMMOVABLE_ACTION_ID then
return false
end

Expand Down
1 change: 0 additions & 1 deletion data/global.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ function IsRunningGlobalDatapack()
end
end

NOT_MOVEABLE_ACTION = 100
PARTY_PROTECTION = 1 -- Set to 0 to disable.
ADVANCED_SECURE_MODE = 1 -- Set to 0 to disable.

Expand Down
2 changes: 1 addition & 1 deletion src/creatures/monsters/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ void Monster::pushItems(Tile* tile, const Direction &nextDirection) {
auto it = items->begin();
while (it != items->end()) {
Item* item = *it;
if (item && item->hasProperty(CONST_PROP_MOVEABLE) && (item->hasProperty(CONST_PROP_BLOCKPATH) || item->hasProperty(CONST_PROP_BLOCKSOLID)) && item->getAttribute<uint16_t>(ItemAttribute_t::ACTIONID) != 100 /* non-moveable action*/) {
if (item && item->hasProperty(CONST_PROP_MOVEABLE) && (item->hasProperty(CONST_PROP_BLOCKPATH) || item->hasProperty(CONST_PROP_BLOCKSOLID)) && item->getAttribute<uint16_t>(ItemAttribute_t::ACTIONID) != IMMOVABLE_ACTION_ID) {
if (moveCount < 20 && pushItem(item, nextDirection)) {
++moveCount;
} else if (!item->isCorpse() && g_game().internalRemoveItem(item) == RETURNVALUE_NOERROR) {
Expand Down
18 changes: 14 additions & 4 deletions src/items/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ bool Item::hasProperty(ItemProperty prop) const {
case CONST_PROP_BLOCKSOLID:
return it.blockSolid;
case CONST_PROP_MOVEABLE:
return it.moveable && !hasAttribute(ItemAttribute_t::UNIQUEID);
return canBeMoved();
case CONST_PROP_HASHEIGHT:
return it.hasHeight;
case CONST_PROP_BLOCKPROJECTILE:
Expand All @@ -966,11 +966,11 @@ bool Item::hasProperty(ItemProperty prop) const {
case CONST_PROP_ISHORIZONTAL:
return it.isHorizontal;
case CONST_PROP_IMMOVABLEBLOCKSOLID:
return it.blockSolid && (!it.moveable || hasAttribute(ItemAttribute_t::UNIQUEID));
return it.blockSolid && !canBeMoved();
case CONST_PROP_IMMOVABLEBLOCKPATH:
return it.blockPathFind && (!it.moveable || hasAttribute(ItemAttribute_t::UNIQUEID));
return it.blockPathFind && !canBeMoved();
case CONST_PROP_IMMOVABLENOFIELDBLOCKPATH:
return !it.isMagicField() && it.blockPathFind && (!it.moveable || hasAttribute(ItemAttribute_t::UNIQUEID));
return !it.isMagicField() && it.blockPathFind && !canBeMoved();
case CONST_PROP_NOFIELDBLOCKPATH:
return !it.isMagicField() && it.blockPathFind;
case CONST_PROP_SUPPORTHANGABLE:
Expand All @@ -980,6 +980,10 @@ bool Item::hasProperty(ItemProperty prop) const {
}
}

bool Item::canBeMoved() const {
return isMoveable() && !hasAttribute(UNIQUEID) && (!hasAttribute(ACTIONID) || getAttribute<uint16_t>(ItemAttribute_t::ACTIONID) != IMMOVABLE_ACTION_ID);
}

uint32_t Item::getWeight() const {
uint32_t baseWeight = getBaseWeight();
if (isStackable()) {
Expand Down Expand Up @@ -2554,3 +2558,9 @@ bool Item::isInsideDepot(bool includeInbox /* = false*/) const {

return false;
}

void Item::updateTileFlags() {
if (auto tile = getTile()) {
tile->updateTileFlags(this);
}
}
4 changes: 4 additions & 0 deletions src/items/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ class Item : virtual public Thing, public ItemProperties {
return items[id].upgradeClassification;
}

void updateTileFlags();

protected:
Cylinder* parent = nullptr;

Expand All @@ -646,6 +648,8 @@ class Item : virtual public Thing, public ItemProperties {
std::string getWeightDescription(uint32_t weight) const;

friend class Decay;

bool canBeMoved() const;
};

using ItemList = std::list<Item*>;
Expand Down
5 changes: 5 additions & 0 deletions src/items/tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,11 @@ void Tile::internalAddThing(uint32_t, Thing* thing) {
}
}

void Tile::updateTileFlags(const Item* item) {
resetTileFlags(item);
setTileFlags(item);
}

void Tile::setTileFlags(const Item* item) {
if (!hasFlag(TILESTATE_FLOORCHANGE)) {
const ItemType &it = Item::items[item->getID()];
Expand Down
1 change: 1 addition & 0 deletions src/items/tile.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class Tile : public Cylinder {
void addThing(Thing* thing) override final;
void addThing(int32_t index, Thing* thing) override;

void updateTileFlags(const Item* item);
void updateThing(Thing* thing, uint16_t itemId, uint32_t count) override final;
void replaceThing(uint32_t index, Thing* thing) override final;

Expand Down
2 changes: 2 additions & 0 deletions src/lua/functions/core/game/lua_enums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ void LuaEnums::initOthersEnums(lua_State* L) {
registerEnum(L, LIGHT_STATE_SUNRISE);
registerEnum(L, STORAGEVALUE_EMOTE);

registerEnum(L, IMMOVABLE_ACTION_ID);

registerEnum(L, MAX_LOOTCHANCE);

registerEnum(L, ORIGIN_NONE);
Expand Down
2 changes: 2 additions & 0 deletions src/lua/functions/items/item_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,10 +422,12 @@ int ItemFunctions::luaItemSetAttribute(lua_State* L) {
}

item->setAttribute(attribute, getNumber<int64_t>(L, 3));
item->updateTileFlags();
pushBoolean(L, true);
} else if (item->isAttributeString(attribute)) {
auto newAttributeString = getString(L, 3);
item->setAttribute(attribute, newAttributeString);
item->updateTileFlags();
pushBoolean(L, true);
} else {
lua_pushnil(L);
Expand Down
2 changes: 2 additions & 0 deletions src/utils/const.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ static constexpr int32_t PSTRG_MOUNTS_CURRENTMOUNT = (PSTRG_MOUNTS_RANGE_START +
static constexpr int32_t PSTRG_FAMILIARS_RANGE_START = (PSTRG_RESERVED_RANGE_START + 3000);
static constexpr int32_t PSTRG_FAMILIARS_RANGE_SIZE = 500;

static constexpr int32_t IMMOVABLE_ACTION_ID = 100;

#define IS_IN_KEYRANGE(key, range) \
(key >= PSTRG_##range##_START && ((key - PSTRG_##range##_START) <= PSTRG_##range##_SIZE))

Expand Down

0 comments on commit 5c53a39

Please sign in to comment.