Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
498228c
Update login.lua
LeoTKBR Oct 4, 2023
e492edf
Create autosync.yml
LeoTKBR Nov 1, 2023
b312e75
Update autosync.yml
LeoTKBR Nov 1, 2023
13c7799
Update autosync.yml
LeoTKBR Nov 1, 2023
abcc3a2
Update autosync.yml
LeoTKBR Nov 1, 2023
a383e95
Update autosync.yml
LeoTKBR Nov 1, 2023
e0b9d70
Update autosync.yml
LeoTKBR Nov 1, 2023
467fe4e
Update autosync.yml
LeoTKBR Nov 1, 2023
ae7e3ec
Update autosync.yml
LeoTKBR Nov 1, 2023
40f9d9e
Update autosync.yml
LeoTKBR Nov 1, 2023
430c489
Update autosync.yml
LeoTKBR Nov 1, 2023
965160d
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 4, 2023
708239f
Update autosync.yml
LeoTKBR Nov 4, 2023
203fa21
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 4, 2023
6927683
Merge branch 'main' of https://github.com/LeoTKBR/canary
LeoTKBR Nov 5, 2023
6dbe8ea
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 7, 2023
bfaef08
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 9, 2023
eabbcc5
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 16, 2023
61541d4
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 19, 2023
82c3ebf
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 23, 2023
67f7a9a
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 30, 2023
65f4896
Merge branch 'opentibiabr:main' into main
LeoTKBR Dec 5, 2023
45c764f
Merge branch 'opentibiabr:main' into main
LeoTKBR Sep 17, 2024
9c2f4db
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 7, 2024
d35e4a8
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 21, 2024
691870f
Merge branch 'opentibiabr:main' into main
LeoTKBR Nov 22, 2024
325a906
Merge branch 'opentibiabr:main' into main
LeoTKBR Mar 28, 2025
3d54c02
All Loot Corpses Otimization
LeoTKBR Mar 28, 2025
ad4e5ae
Code format - (Clang-format)
github-actions[bot] Mar 28, 2025
623b4c8
fix error
LeoTKBR Mar 28, 2025
182ea82
Delete .github/workflows/autosync.yml
LeoTKBR Mar 28, 2025
b301ea2
#Change BatchSize Value
LeoTKBR Mar 28, 2025
7b3d1fa
Code format - (Clang-format)
github-actions[bot] Mar 29, 2025
2b3f358
#Update otimization
LeoTKBR Mar 29, 2025
4895f32
#Update Otimization
LeoTKBR Apr 1, 2025
8804652
Merge branch 'all-loot-corpses-otimization' of https://github.com/Leo…
LeoTKBR Apr 1, 2025
4f56a1a
Code format - (Clang-format)
github-actions[bot] Apr 1, 2025
3c56d33
Code format - (Clang-format)
github-actions[bot] Apr 1, 2025
7fccf9a
#Update QuickLootCorpse
LeoTKBR Apr 1, 2025
04c3d50
#remove comment
LeoTKBR Apr 1, 2025
3a26f43
Merge branch 'all-loot-corpses-otimization' of https://github.com/Leo…
LeoTKBR Apr 1, 2025
8f5f53a
Code format - (Clang-format)
github-actions[bot] Apr 1, 2025
7ebf411
#Update QuickLootCorpse & LootAllCorpse
LeoTKBR Apr 1, 2025
e214863
Code format - (Clang-format)
github-actions[bot] Apr 1, 2025
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
30 changes: 27 additions & 3 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7614,6 +7614,13 @@ void Player::sendTakeScreenshot(Screenshot_t screenshotType) const {
void Player::onThink(uint32_t interval) {
Creature::onThink(interval);

currentTime = std::chrono::steady_clock::now();
currentTimeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime.time_since_epoch()).count();
if (updateInventory && !updatedItems.empty()) {
sendInventoryIds();
updatedItems.clear();
updateInventory = false;
}
sendPing();

MessageBufferTicks += interval;
Expand Down Expand Up @@ -7661,6 +7668,8 @@ void Player::postAddNotification(const std::shared_ptr<Thing> &thing, const std:
g_moveEvents().onPlayerEquip(getPlayer(), thing->getItem(), static_cast<Slots_t>(index), false);
}

currentTime = std::chrono::steady_clock::now();
currentTimeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime.time_since_epoch()).count();
bool requireListUpdate = true;
if (link == LINK_OWNER || link == LINK_TOPPARENT) {
const auto &item = oldParent ? oldParent->getItem() : nullptr;
Expand All @@ -7673,7 +7682,13 @@ void Player::postAddNotification(const std::shared_ptr<Thing> &thing, const std:

updateInventoryWeight();
updateItemsLight();
sendInventoryIds();
if (std::shared_ptr<Item> item = thing->getItem()) {
updatedItems.push_back(item);
}
if (updatedItems.size() >= maxUpdatesPerBatch || (currentTimeMillis - lastUpdateTime) > updateCooldown) {
updateInventory = true;
lastUpdateTime = currentTimeMillis;
}
sendStats();
}

Expand Down Expand Up @@ -7721,8 +7736,10 @@ void Player::postRemoveNotification(const std::shared_ptr<Thing> &thing, const s
g_moveEvents().onPlayerDeEquip(getPlayer(), item, static_cast<Slots_t>(index));
}
}
bool requireListUpdate = true;

currentTime = std::chrono::steady_clock::now();
currentTimeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime.time_since_epoch()).count();
bool requireListUpdate = true;
if (link == LINK_OWNER || link == LINK_TOPPARENT) {
const auto &item = copyNewParent ? copyNewParent->getItem() : nullptr;
const auto &container = item ? item->getContainer() : nullptr;
Expand All @@ -7734,7 +7751,14 @@ void Player::postRemoveNotification(const std::shared_ptr<Thing> &thing, const s

updateInventoryWeight();
updateItemsLight();
sendInventoryIds();
if (std::shared_ptr<Item> item = thing->getItem()) {
updatedItems.push_back(item);
}

if (updatedItems.size() >= maxUpdatesPerBatch || (currentTimeMillis - lastUpdateTime) > updateCooldown) {
updateInventory = true;
lastUpdateTime = currentTimeMillis;
}
sendStats();
}

Expand Down
8 changes: 7 additions & 1 deletion src/creatures/players/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,13 @@ class Player final : public Creature, public Cylinder, public Bankable {
void sendTakeScreenshot(Screenshot_t screenshotType) const;

void onThink(uint32_t interval) override;

bool updateInventory = false;
std::vector<std::shared_ptr<Item>> updatedItems;
const size_t maxUpdatesPerBatch = 100;
unsigned int lastUpdateTime = 0;
unsigned int updateCooldown = 500;
std::chrono::steady_clock::time_point currentTime;
long long currentTimeMillis = 0;
void postAddNotification(const std::shared_ptr<Thing> &thing, const std::shared_ptr<Cylinder> &oldParent, int32_t index, CylinderLink_t link = LINK_OWNER) override;
void postRemoveNotification(const std::shared_ptr<Thing> &thing, const std::shared_ptr<Cylinder> &newParent, int32_t index, CylinderLink_t link = LINK_OWNER) override;

Expand Down
202 changes: 98 additions & 104 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2930,15 +2930,18 @@ void Game::playerQuickLootCorpse(const std::shared_ptr<Player> &player, const st
return;
}

std::vector<std::shared_ptr<Item>> itemList;
bool ignoreListItems = (player->quickLootFilter == QUICKLOOTFILTER_SKIPPEDLOOT);

bool missedAnyGold = false;
bool missedAnyItem = false;
bool shouldNotifyCapacity = false;
ObjectCategory_t shouldNotifyNotEnoughRoom = OBJECTCATEGORY_NONE;
uint32_t totalLootedGold = 0;
uint32_t totalLootedItems = 0;

for (ContainerIterator it = corpse->iterator(); it.hasNext(); it.advance()) {
const auto &item = *it;
bool listed = player->isQuickLootListedItem(item);

if ((listed && ignoreListItems) || (!listed && !ignoreListItems)) {
if (item->getWorth() != 0) {
missedAnyGold = true;
Expand All @@ -2948,15 +2951,6 @@ void Game::playerQuickLootCorpse(const std::shared_ptr<Player> &player, const st
continue;
}

itemList.push_back(item);
}

bool shouldNotifyCapacity = false;
ObjectCategory_t shouldNotifyNotEnoughRoom = OBJECTCATEGORY_NONE;

uint32_t totalLootedGold = 0;
uint32_t totalLootedItems = 0;
for (const std::shared_ptr<Item> &item : itemList) {
uint32_t worth = item->getWorth();
uint16_t baseCount = item->getItemCount();
ObjectCategory_t category = getObjectCategory(item);
Expand All @@ -2975,7 +2969,6 @@ void Game::playerQuickLootCorpse(const std::shared_ptr<Player> &player, const st
player->sendLootStats(item, baseCount);
totalLootedGold += worth;
} else {
// item is not completely moved
totalLootedGold += worth - item->getWorth();
}
} else {
Expand All @@ -2987,78 +2980,79 @@ void Game::playerQuickLootCorpse(const std::shared_ptr<Player> &player, const st
}
}

std::stringstream ss;
if (totalLootedGold != 0 || missedAnyGold || totalLootedItems != 0 || missedAnyItem) {
bool lootedAllGold = totalLootedGold != 0 && !missedAnyGold;
bool lootedAllItems = totalLootedItems != 0 && !missedAnyItem;
if (lootedAllGold) {
if (totalLootedItems != 0 || missedAnyItem) {
ss << "You looted the complete " << totalLootedGold << " gold";

if (lootedAllItems) {
ss << " and all dropped items";
} else if (totalLootedItems != 0) {
ss << ", but you only looted some of the items";
} else if (missedAnyItem) {
ss << " but none of the dropped items";
}
} else {
ss << "You looted " << totalLootedGold << " gold";
}
} else if (lootedAllItems) {
if (totalLootedItems == 1) {
ss << "You looted 1 item";
} else if (totalLootedGold != 0 || missedAnyGold) {
ss << "You looted all of the dropped items";
} else {
ss << "You looted all items";
}
if (!(totalLootedGold != 0 || missedAnyGold || totalLootedItems != 0 || missedAnyItem)) {
player->sendTextMessage(MESSAGE_STATUS, "No loot.");
return;
}

if (totalLootedGold != 0) {
ss << ", but you only looted " << totalLootedGold << " of the dropped gold";
} else if (missedAnyGold) {
ss << " but none of the dropped gold";
}
} else if (totalLootedGold != 0) {
ss << "You only looted " << totalLootedGold << " of the dropped gold";
if (totalLootedItems != 0) {
ss << " and some of the dropped items";
std::string message;
message.reserve(128);

bool lootedAllGold = totalLootedGold != 0 && !missedAnyGold;
bool lootedAllItems = totalLootedItems != 0 && !missedAnyItem;

if (lootedAllGold) {
message = "You looted the complete " + std::to_string(totalLootedGold) + " gold";

if (totalLootedItems != 0 || missedAnyItem) {
if (lootedAllItems) {
message += " and all dropped items";
} else if (totalLootedItems != 0) {
message += ", but you only looted some of the items";
} else if (missedAnyItem) {
ss << " but none of the dropped items";
}
} else if (totalLootedItems != 0) {
ss << "You looted some of the dropped items";
if (missedAnyGold) {
ss << " but none of the dropped gold";
message += " but none of the dropped items";
}
}
} else if (lootedAllItems) {
if (totalLootedItems == 1) {
message = "You looted 1 item";
} else if (totalLootedGold != 0 || missedAnyGold) {
message = "You looted all of the dropped items";
} else {
message = "You looted all items";
}

if (totalLootedGold != 0) {
message += ", but you only looted " + std::to_string(totalLootedGold) + " of the dropped gold";
} else if (missedAnyGold) {
ss << "You looted none of the dropped gold";
if (missedAnyItem) {
ss << " and none of the items";
}
message += " but none of the dropped gold";
}
} else if (totalLootedGold != 0) {
message = "You only looted " + std::to_string(totalLootedGold) + " of the dropped gold";
if (totalLootedItems != 0) {
message += " and some of the dropped items";
} else if (missedAnyItem) {
ss << "You looted none of the dropped items";
message += " but none of the dropped items";
}
} else {
ss << "No loot";
} else if (totalLootedItems != 0) {
message = "You looted some of the dropped items";
if (missedAnyGold) {
message += " but none of the dropped gold";
}
} else if (missedAnyGold) {
message = "You looted none of the dropped gold";
if (missedAnyItem) {
message += " and none of the items";
}
} else if (missedAnyItem) {
message = "You looted none of the dropped items";
}
ss << ".";
player->sendTextMessage(MESSAGE_STATUS, ss.str());

message += ".";
player->sendTextMessage(MESSAGE_STATUS, message);

if (shouldNotifyCapacity) {
ss.str(std::string());
ss << "Attention! The loot you are trying to pick up is too heavy for you to carry.";
message = "Attention! The loot you are trying to pick up is too heavy for you to carry.";
} else if (shouldNotifyNotEnoughRoom != OBJECTCATEGORY_NONE) {
ss.str(std::string());
ss << "Attention! The container assigned to category " << getObjectCategoryName(shouldNotifyNotEnoughRoom) << " is full.";
message = "Attention! The container assigned to category " + std::string(getObjectCategoryName(shouldNotifyNotEnoughRoom)) + " is full.";
} else {
return;
}

if (player->lastQuickLootNotification + 15000 < OTSYS_TIME()) {
player->sendTextMessage(MESSAGE_GAME_HIGHLIGHT, ss.str());
player->sendTextMessage(MESSAGE_GAME_HIGHLIGHT, message);
} else {
player->sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str());
player->sendTextMessage(MESSAGE_EVENT_ADVANCE, message);
}

player->lastQuickLootNotification = OTSYS_TIME();
Expand Down Expand Up @@ -5696,52 +5690,52 @@ void Game::playerQuickLoot(uint32_t playerId, const Position &pos, uint16_t item
}
}

void Game::playerLootAllCorpses(const std::shared_ptr<Player> &player, const Position &pos, bool lootAllCorpses) {
if (lootAllCorpses) {
std::shared_ptr<Tile> tile = g_game().map.getTile(pos.x, pos.y, pos.z);
if (!tile) {
player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
return;
}
void Game::playerLootAllCorpses(std::shared_ptr<Player> player, const Position &pos, bool lootAllCorpses) {
if (!lootAllCorpses) {
browseField = false;
return;
}

const TileItemVector* itemVector = tile->getItemList();
uint16_t corpses = 0;
for (auto &tileItem : *itemVector) {
if (!tileItem) {
continue;
}
std::shared_ptr<Tile> tile = g_game().map.getTile(pos.x, pos.y, pos.z);
if (!tile) {
return;
}

std::shared_ptr<Container> tileCorpse = tileItem->getContainer();
if (!tileCorpse || !tileCorpse->isCorpse() || tileCorpse->hasAttribute(ItemAttribute_t::UNIQUEID) || tileCorpse->hasAttribute(ItemAttribute_t::ACTIONID)) {
continue;
}
const TileItemVector* itemVector = tile->getItemList();
uint16_t corpses = 0;
constexpr uint16_t maxCorpses = 30;

if (!tileCorpse->isRewardCorpse()
&& tileCorpse->getCorpseOwner() != 0
&& !player->canOpenCorpse(tileCorpse->getCorpseOwner())) {
player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE);
g_logger().debug("Player {} cannot loot corpse from id {} in position {}", player->getName(), tileItem->getID(), tileItem->getPosition().toString());
continue;
}
std::string message;
message.reserve(128);

corpses++;
playerQuickLootCorpse(player, tileCorpse, tileCorpse->getPosition());
if (corpses >= 30) {
break;
}
for (auto &tileItem : *itemVector) {
if (!tileItem) {
continue;
}

if (corpses > 0) {
if (corpses > 1) {
std::stringstream string;
string << "You looted " << corpses << " corpses.";
player->sendTextMessage(MESSAGE_LOOT, string.str());
}
std::shared_ptr<Container> tileCorpse = tileItem->getContainer();
if (!tileCorpse || !tileCorpse->isCorpse() || tileCorpse->hasAttribute(ItemAttribute_t::UNIQUEID) || tileCorpse->hasAttribute(ItemAttribute_t::ACTIONID)) {
continue;
}

return;
if (!tileCorpse->isRewardCorpse() && tileCorpse->getCorpseOwner() != 0 && !player->canOpenCorpse(tileCorpse->getCorpseOwner())) {
g_logger().debug("Player {} cannot loot corpse from id {} in position {}", player->getName(), tileItem->getID(), tileItem->getPosition().toString());
continue;
}

playerQuickLootCorpse(player, tileCorpse, tileCorpse->getPosition());

if (++corpses >= maxCorpses) {
break;
}
}

if (corpses > 0) {
std::stringstream string;
string << "You looted " << corpses << (corpses > 1 ? " corpses." : " corpse.");
player->sendTextMessage(MESSAGE_LOOT, string.str());
}

browseField = false;
}

Expand Down