Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into kokekanon/all-featu…
Browse files Browse the repository at this point in the history
…re-redemption
  • Loading branch information
kokekanon committed Jan 12, 2025
2 parents 764af1b + cb1e3d5 commit 73896db
Show file tree
Hide file tree
Showing 22 changed files with 159 additions and 39 deletions.
2 changes: 1 addition & 1 deletion data-otservbr-global/monster/bosses/chagorz.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local monster = {}
monster.description = "Chagorz"
monster.experience = 3250000
monster.outfit = {
lookType = 1665,
lookType = 1666,
lookHead = 0,
lookBody = 0,
lookLegs = 0,
Expand Down
2 changes: 1 addition & 1 deletion data-otservbr-global/monster/bosses/vemiath.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local monster = {}
monster.description = "Vemiath"
monster.experience = 3250000
monster.outfit = {
lookType = 1665,
lookType = 1668,
lookHead = 0,
lookBody = 0,
lookLegs = 0,
Expand Down
2 changes: 1 addition & 1 deletion data-otservbr-global/monster/familiars/druid_familiar.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local mType = Game.createMonsterType("Druid Familiar")
local mType = Game.createMonsterType("Druid familiar")
local monster = {}

monster.description = "a druid familiar"
Expand Down
2 changes: 1 addition & 1 deletion data-otservbr-global/monster/familiars/knight_familiar.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local mType = Game.createMonsterType("Knight Familiar")
local mType = Game.createMonsterType("Knight familiar")
local monster = {}

monster.description = "a knight familiar"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local mType = Game.createMonsterType("Paladin Familiar")
local mType = Game.createMonsterType("Paladin familiar")
local monster = {}

monster.description = "a paladin familiar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ local function initialize(monster)
end

-- Functions for the fight
mType.onSpawn = function(monster, spawnPosition)
initialize(monster)
end

local function getHazardPoints(monster)
local hazard = Hazard.getByName("hazard.gnomprona-gardens")
if not hazard then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local monster = {}
monster.description = "a Mushroom"
monster.experience = 0
monster.outfit = {
lookType = 1669, --todo get correct lookType
lookType = 1773,
lookHead = 0,
lookBody = 0,
lookLegs = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ mType.onThink = function(monster, interval)
end
end

mType.onSpawn = function(monsterCallback)
firstTime = 0
end

mType.onDisappear = function(monster, creature)
if creature:getName() == "Goshnar's Cruelty" then
local eyeCreature = Creature("A Greedy Eye")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,8 @@ mType.onDisappear = function(monster, creature)
end
end

mType.onSpawn = function(monster)
monster:resetHatredDamageMultiplier()
end

mType:register(monster)
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,15 @@ monster.immunities = {
{ type = "bleed", condition = false },
}

mType.onSpawn = function(monster, spawnPosition)
if monster:getType():isRewardBoss() then
-- reset global storage state to default / ensure sqm's reset for the next team
Game.setStorageValue(GlobalStorage.TheDreamCourts.FacelessBane.Deaths, -1)
Game.setStorageValue(GlobalStorage.TheDreamCourts.FacelessBane.StepsOn, -1)
Game.setStorageValue(GlobalStorage.TheDreamCourts.FacelessBane.ResetSteps, 1)
monster:registerEvent("facelessBaneImmunity")
monster:setReward(true)
end
end

mType:register(monster)
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,16 @@ monster.immunities = {
{ type = "bleed", condition = false },
}

mType.onSpawn = function(monster, spawnPosition)
for i = 1, 5 do
local sum = Game.createMonster(monster:getType():getSummonList()[math.random(1, #monster:getType():getSummonList())].name, monster:getPosition(), true)
if sum then
monster:setSummon(sum)
sum:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
sum:setStorageValue(Storage.TheOrderOfTheLion.Drume.Commander, 1)
end
end
monster:setStorageValue(Storage.TheOrderOfTheLion.Drume.Commander, 1)
end

mType:register(monster)
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,17 @@ monster.immunities = {
{ type = "bleed", condition = false },
}

mType.onSpawn = function(monster, spawnPosition)
local sum
for i = 1, 5 do
sum = Game.createMonster(monster:getType():getSummonList()[math.random(1, #monster:getType():getSummonList())].name, monster:getPosition(), true)
if sum then
monster:setSummon(sum)
sum:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
sum:setStorageValue(Storage.TheOrderOfTheLion.Drume.Commander, 1)
end
end
monster:setStorageValue(Storage.TheOrderOfTheLion.Drume.Commander, 1)
end

mType:register(monster)
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ monster.immunities = {
{ type = "bleed", condition = false },
}

mType.onSpawn = function(monster, spawnPosition)
monster:setStorageValue(GrandMasterOberonConfig.Storage.Asking, 1)
monster:setStorageValue(GrandMasterOberonConfig.Storage.Life, 1)
end

mType.onThink = function(monster, interval)
if monster:getStorageValue(GrandMasterOberonConfig.Storage.Life) <= GrandMasterOberonConfig.AmountLife then
local percentageHealth = (monster:getHealth() * 100) / monster:getMaxHealth()
Expand Down
2 changes: 1 addition & 1 deletion data/scripts/actions/objects/cask_and_kegs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ local targetIdList = {
local flasks = Action()

function flasks.onUse(player, item, fromPosition, target, toPosition, isHotkey)
if not target or not target:getItem() then
if not target or not target:isItem() then
return false
end

Expand Down
2 changes: 1 addition & 1 deletion data/scripts/lib/register_monster_type.lua
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ registerMonsterType.flags = function(mtype, mask)
if mask.flags.rewardBoss then
mtype:isRewardBoss(mask.flags.rewardBoss)
mtype.onSpawn = function(monster, spawnPosition)
monster:setRewardBoss()
monster:setReward(true)
end
end
if mask.flags.familiar then
Expand Down
67 changes: 57 additions & 10 deletions src/config/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ bool ConfigManager::load() {
}

bool ConfigManager::reload() {
m_configString.clear();
m_configInteger.clear();
m_configBoolean.clear();
m_configFloat.clear();
const bool result = load();
if (transformToSHA1(getString(SERVER_MOTD)) != g_game().getMotdHash()) {
g_game().incrementMotdNum();
Expand Down Expand Up @@ -439,34 +443,77 @@ float ConfigManager::loadFloatConfig(lua_State* L, const ConfigKey_t &key, const
}

const std::string &ConfigManager::getString(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
static const std::string dummyStr;
if (configs.contains(key) && std::holds_alternative<std::string>(configs.at(key))) {
return std::get<std::string>(configs.at(key));
auto itCache = m_configString.find(key);
if (itCache != m_configString.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (const auto* value = std::get_if<std::string>(&it->second)) {
m_configString[key] = *value;
return *value;
}
}

static const std::string staticEmptyString;
g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return dummyStr;
return staticEmptyString;
}

int32_t ConfigManager::getNumber(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
if (configs.contains(key) && std::holds_alternative<int32_t>(configs.at(key))) {
return std::get<int32_t>(configs.at(key));
auto itCache = m_configInteger.find(key);
if (itCache != m_configInteger.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (std::holds_alternative<int32_t>(it->second)) {
const auto value = std::get<int32_t>(it->second);
m_configInteger[key] = value;
return value;
}
}

g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return 0;
}

bool ConfigManager::getBoolean(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
if (configs.contains(key) && std::holds_alternative<bool>(configs.at(key))) {
return std::get<bool>(configs.at(key));
auto itCache = m_configBoolean.find(key);
if (itCache != m_configBoolean.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (std::holds_alternative<bool>(it->second)) {
const auto value = std::get<bool>(it->second);
m_configBoolean[key] = value;
return value;
}
}

g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return false;
}

float ConfigManager::getFloat(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
if (configs.contains(key) && std::holds_alternative<float>(configs.at(key))) {
return std::get<float>(configs.at(key));
auto itCache = m_configFloat.find(key);
if (itCache != m_configFloat.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (std::holds_alternative<float>(it->second)) {
const auto value = std::get<float>(it->second);
m_configFloat[key] = value;
return value;
}
}

g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return 0.0f;
}
Expand Down
7 changes: 6 additions & 1 deletion src/config/configmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ class ConfigManager {
OTCFeatures getDisabledFeaturesOTC() const;

private:
phmap::flat_hash_map<ConfigKey_t, ConfigValue> configs;
mutable std::unordered_map<ConfigKey_t, std::string> m_configString;
mutable std::unordered_map<ConfigKey_t, bool> m_configBoolean;
mutable std::unordered_map<ConfigKey_t, int32_t> m_configInteger;
mutable std::unordered_map<ConfigKey_t, float> m_configFloat;

std::unordered_map<ConfigKey_t, ConfigValue> configs;
std::string loadStringConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const std::string &defaultValue);
int32_t loadIntConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const int32_t &defaultValue);
bool loadBoolConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const bool &defaultValue);
Expand Down
6 changes: 3 additions & 3 deletions src/creatures/npcs/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,13 +812,13 @@ void Npc::removeShopPlayer(uint32_t playerGUID) {
}

void Npc::closeAllShopWindows() {
for (const auto playerGUID : shopPlayers | std::views::keys) {
const auto &player = g_game().getPlayerByGUID(playerGUID);
for (auto it = shopPlayers.begin(); it != shopPlayers.end();) {
const auto &player = g_game().getPlayerByGUID(it->first);
if (player) {
player->closeShopWindow();
}
it = shopPlayers.erase(it);
}
shopPlayers.clear();
}

void Npc::handlePlayerMove(const std::shared_ptr<Player> &player, const Position &newPos) {
Expand Down
9 changes: 5 additions & 4 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9143,12 +9143,13 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite
}

uint64_t totalPrice = price * amount;
uint64_t totalFee = totalPrice * 0.02;
uint64_t maxFee = std::min<uint64_t>(1000000, totalFee);
uint64_t fee = std::max<uint64_t>(20, totalFee);
uint64_t totalFee = totalPrice * 0.02; // 2% fee
uint64_t maxFee = std::min<uint64_t>(1000000, totalFee); // Max fee is 1kk
uint64_t fee = std::clamp(totalFee, uint64_t(20), maxFee); // Limit between 20 and maxFee

if (type == MARKETACTION_SELL) {
if (fee > (player->getBankBalance() + player->getMoney())) {
uint64_t totalPriceWithFee = totalPrice + fee;
if (totalPriceWithFee > (player->getMoney() + player->getBankBalance())) {
offerStatus << "Fee is greater than player money";
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/items/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ Item::Item(const uint16_t itemId, uint16_t itemCount /*= 0*/) :
const ItemType &it = items[id];
const auto itemCharges = it.charges;
if (it.isFluidContainer() || it.isSplash()) {
const auto fluidType = std::clamp<uint16_t>(itemCount, 1, FLUID_INK);
const auto fluidType = std::clamp<uint16_t>(itemCount, 0, magic_enum::enum_count<Fluids_t>());
setAttribute(ItemAttribute_t::FLUIDTYPE, fluidType);
} else if (it.stackable) {
if (itemCount != 0) {
Expand Down
20 changes: 17 additions & 3 deletions src/items/tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1876,11 +1876,25 @@ std::shared_ptr<Item> Tile::getUseItem(int32_t index) const {
return ground;
}

if (const auto &thing = getThing(index)) {
return thing->getItem();
if (index >= 0 && index < static_cast<int32_t>(items->size())) {
if (const auto &thing = getThing(index)) {
if (auto thingItem = thing->getItem()) {
return thingItem;
}
}
}

return nullptr;
if (auto topDownItem = getTopDownItem()) {
return topDownItem;
}

for (auto it = items->rbegin(), end = items->rend(); it != end; ++it) {
if ((*it)->getDoor()) {
return (*it)->getItem();
}
}

return !items->empty() ? *items->begin() : nullptr;
}

std::shared_ptr<Item> Tile::getDoorItem() const {
Expand Down
18 changes: 9 additions & 9 deletions src/map/spectators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ bool Spectators::checkCache(const SpectatorsCache::FloorData &specData, bool onl
for (const auto &creature : *list) {
const auto &specPos = creature->getPosition();
if ((centerPos.x - specPos.x >= minRangeX
&& centerPos.y - specPos.y >= minRangeY
&& centerPos.x - specPos.x <= maxRangeX
&& centerPos.y - specPos.y <= maxRangeY
&& (multifloor || specPos.z == centerPos.z)
&& ((onlyPlayers && creature->getPlayer())
|| (onlyMonsters && creature->getMonster())
|| (onlyNpcs && creature->getNpc()))
|| (!onlyPlayers && !onlyMonsters && !onlyNpcs))) {
&& centerPos.y - specPos.y >= minRangeY
&& centerPos.x - specPos.x <= maxRangeX
&& centerPos.y - specPos.y <= maxRangeY
&& (multifloor || specPos.z == centerPos.z)
&& ((onlyPlayers && creature->getPlayer())
|| (onlyMonsters && creature->getMonster())
|| (onlyNpcs && creature->getNpc())))
|| (!onlyPlayers && !onlyMonsters && !onlyNpcs)) {
spectators.emplace_back(creature);
}
}
Expand Down Expand Up @@ -257,7 +257,7 @@ Spectators Spectators::excludePlayerMaster() const {
specs.creatures.reserve(creatures.size());

for (const auto &c : creatures) {
if ((c->getMonster() != nullptr && !c->getMaster() || !c->getMaster()->getPlayer())) {
if ((c->getMonster() != nullptr && !c->getMaster()) || (!c->getMaster() || !c->getMaster()->getPlayer())) {
specs.insert(c);
}
}
Expand Down

0 comments on commit 73896db

Please sign in to comment.