diff --git a/src/creatures/combat/condition.cpp b/src/creatures/combat/condition.cpp index e49a6662991..da90b03f65a 100644 --- a/src/creatures/combat/condition.cpp +++ b/src/creatures/combat/condition.cpp @@ -2540,7 +2540,7 @@ void ConditionLight::addCondition(std::shared_ptr creature, const std: const auto &conditionLight = condition->static_self_cast(); lightInfo.level = conditionLight->lightInfo.level; lightInfo.color = conditionLight->lightInfo.color; - lightChangeInterval = ticks / lightInfo.level; + lightChangeInterval = ticks / std::max(1, lightInfo.level); internalLightTicks = 0; creature->setCreatureLight(lightInfo); g_game().changeLight(creature); @@ -2558,9 +2558,13 @@ bool ConditionLight::setParam(ConditionParam_t param, int32_t value) { } switch (param) { - case CONDITION_PARAM_LIGHT_LEVEL: - lightInfo.level = value; + case CONDITION_PARAM_LIGHT_LEVEL: { + if (value < 1) { + g_logger().warn("[ConditionLight::setParam] Trying to set invalid light value: '{}', defaulting to 1.", value); + } + lightInfo.level = std::max(1, static_cast(value)); return true; + } case CONDITION_PARAM_LIGHT_COLOR: lightInfo.color = value; diff --git a/src/creatures/combat/condition.hpp b/src/creatures/combat/condition.hpp index 1cc798624e3..50d072059a2 100644 --- a/src/creatures/combat/condition.hpp +++ b/src/creatures/combat/condition.hpp @@ -391,7 +391,7 @@ class ConditionLight final : public Condition { bool unserializeProp(ConditionAttr_t attr, PropStream &propStream) override; private: - LightInfo lightInfo; + LightInfo lightInfo { 1, 215 }; uint32_t internalLightTicks = 0; uint32_t lightChangeInterval = 0; }; diff --git a/src/creatures/combat/spells.hpp b/src/creatures/combat/spells.hpp index c12c3af3686..ab34fa6dbce 100644 --- a/src/creatures/combat/spells.hpp +++ b/src/creatures/combat/spells.hpp @@ -50,7 +50,6 @@ class Spells final : public Scripts { std::list getSpellsByVocation(uint16_t vocationId); [[nodiscard]] const std::map> &getInstantSpells() const; - ; [[nodiscard]] bool hasInstantSpell(const std::string &word) const; diff --git a/src/creatures/players/cyclopedia/player_badge.cpp b/src/creatures/players/cyclopedia/player_badge.cpp index 0d97747a248..c27e98cb1aa 100644 --- a/src/creatures/players/cyclopedia/player_badge.cpp +++ b/src/creatures/players/cyclopedia/player_badge.cpp @@ -127,7 +127,8 @@ std::vector> PlayerBadge::getPlayersInfoByAccount(const if (!namesList.empty()) { namesList += ", "; } - namesList += fmt::format("'{}'", name); + std::string escapedName = g_database().escapeString(name); + namesList += fmt::format("{}", escapedName); } auto query = fmt::format("SELECT name, level, vocation FROM players WHERE name IN ({})", namesList); diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 65ace44f5f6..dfdf467aa97 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -9138,8 +9138,6 @@ void Player::forgeTransferItemTier(ForgeAction_t actionType, uint16_t donorItemI g_logger().error("[Log 8] Failed to remove transfer dusts from player with name {}", getName()); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); return; - } else { - setForgeDusts(getForgeDusts() - g_configManager().getNumber(configKey)); } setForgeDusts(getForgeDusts() - g_configManager().getNumber(configKey)); @@ -10073,7 +10071,7 @@ bool Player::setAccount(uint32_t accountId) { } uint8_t Player::getAccountType() const { - return account ? account->getAccountType() : static_cast(AccountType::ACCOUNT_TYPE_NORMAL); + return account ? account->getAccountType() : AccountType::ACCOUNT_TYPE_NORMAL; } uint32_t Player::getAccountId() const { diff --git a/src/io/functions/iologindata_load_player.cpp b/src/io/functions/iologindata_load_player.cpp index 02f58bec04b..477572dfbc8 100644 --- a/src/io/functions/iologindata_load_player.cpp +++ b/src/io/functions/iologindata_load_player.cpp @@ -179,10 +179,28 @@ bool IOLoginDataLoad::loadPlayerBasicInfo(const std::shared_ptr &player, player->setOfflineTrainingSkill(skill); const auto &town = g_game().map.towns.getTown(result->getNumber("town_id")); if (!town) { - g_logger().error("Player {} has town id {} which doesn't exist", player->name, result->getNumber("town_id")); - return false; + g_logger().error("Player {} has invalid town id {}. Attempting to set the correct town.", player->name, result->getNumber("town_id")); + + const auto &thaisTown = g_game().map.towns.getTown("Thais"); + if (thaisTown) { + player->town = thaisTown; + g_logger().warn("Assigned town 'Thais' to player {}", player->name); + } else { + for (const auto &[townId, currentTown] : g_game().map.towns.getTowns()) { + if (townId != 0 && currentTown) { + player->town = currentTown; + g_logger().warn("Assigned first valid town {} (id: {}) to player {}", currentTown->getName(), townId, player->name); + } + } + + if (!player->town) { + g_logger().error("Player {} has invalid town id {}. No valid town found to assign.", player->name, result->getNumber("town_id")); + return false; + } + } + } else { + player->town = town; } - player->town = town; const Position &loginPos = player->loginPosition; if (loginPos.x == 0 && loginPos.y == 0 && loginPos.z == 0) { diff --git a/src/io/functions/iologindata_save_player.cpp b/src/io/functions/iologindata_save_player.cpp index c6b92514969..b38e6e2b84c 100644 --- a/src/io/functions/iologindata_save_player.cpp +++ b/src/io/functions/iologindata_save_player.cpp @@ -127,7 +127,6 @@ bool IOLoginDataSave::saveItems(const std::shared_ptr &player, const Ite // Serialize item attributes propWriteStream.clear(); item->serializeAttr(propWriteStream); - item->stopDecaying(); size_t attributesSize; const char* attributes = propWriteStream.getStream(attributesSize);