Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mattyx14 committed Feb 8, 2025
1 parent b92b87a commit be1cc7e
Show file tree
Hide file tree
Showing 40 changed files with 849 additions and 96 deletions.
14 changes: 13 additions & 1 deletion config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ maxItem = 5000
maxContainer = 500
maxContainerDepth = 200

-- Animus Mastery - SoulPit (Get more info in: https://github.com/opentibiabr/canary/pull/3230)
-- NOTE: animusMasteryMaxMonsterXpMultiplier is the maximum experience the multiplier can be.
-- NOTE: animusMasteryMonsterXpMultiplier is the monster experience multiplier that has the animus mastery unlocked.
-- NOTE: animusMasteryMonstersXpMultiplier is the multiplier for each 'animusMasteryMonstersToIncreaseXpMultiplier' monsters that
-- the player has the animus mastery unlocked.
-- NOTE: animusMasteryMonstersToIncreaseXpMultiplier is the amount of monster to increase the experience multiplier by 'animusMasteryMonstersXpMultiplier'.
animusMasteryMaxMonsterXpMultiplier = 4.0
animusMasteryMonsterXpMultiplier = 2.0
animusMasteryMonstersXpMultiplier = 0.1
animusMasteryMonstersToIncreaseXpMultiplier = 10

-- Augments System (Get more info in: https://github.com/opentibiabr/canary/pull/2602)
-- NOTE: the following values are for all weapons and equipments that have type of "increase damage", "powerful impact" and "strong impact".
-- To customize the percentage of a particular item with these augment types, please add to the item "augments" section on items.xml as the example above.
Expand Down Expand Up @@ -344,9 +355,10 @@ deathLosePercent = -1
Setting this to false may pose risks; if a house is abandoned and contains a large number of items on the floor, those items will be transferred to the player's depot instantly.
• This could potentially freeze the server due to the heavy operation. It's advised to keep this setting enabled (true) to minimize risks.
]]
-- NOTE: When toggleCyclopediaHouseAuction = true, the !buyhouse commmand does not work.
-- Periods: daily/weekly/monthly/yearly/never
-- Base: sqm,rent,sqm+rent
toggleCyclopediaHouseAuction = true
toggleCyclopediaHouseAuction = false
daysToCloseBid = 7
housePriceRentMultiplier = 0.0
housePriceEachSQM = 1000
Expand Down
3 changes: 2 additions & 1 deletion schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `server_config` (
CONSTRAINT `server_config_pk` PRIMARY KEY (`config`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '48'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '49'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');

-- Table structure `accounts`
CREATE TABLE IF NOT EXISTS `accounts` (
Expand Down Expand Up @@ -149,6 +149,7 @@ CREATE TABLE IF NOT EXISTS `players` (
`forge_dust_level` bigint(21) NOT NULL DEFAULT '100',
`randomize_mount` tinyint(1) NOT NULL DEFAULT '0',
`boss_points` int NOT NULL DEFAULT '0',
`animus_mastery` mediumblob DEFAULT NULL,
INDEX `account_id` (`account_id`),
INDEX `vocation` (`vocation`),
CONSTRAINT `players_pk` PRIMARY KEY (`id`),
Expand Down
4 changes: 4 additions & 0 deletions src/config/config_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ enum ConfigKey_t : uint16_t {
AIMBOT_HOTKEY_ENABLED,
ALLOW_CHANGEOUTFIT,
ALLOW_RELOAD,
ANIMUS_MASTERY_MAX_MONSTER_XP_MULTIPLIER,
ANIMUS_MASTERY_MONSTER_XP_MULTIPLIER,
ANIMUS_MASTERY_MONSTERS_XP_MULTIPLIER,
ANIMUS_MASTERY_MONSTERS_TO_INCREASE_XP_MULTIPLIER,
AUGMENT_INCREASED_DAMAGE_PERCENT,
AUGMENT_POWERFUL_IMPACT_PERCENT,
AUGMENT_STRONG_IMPACT_PERCENT,
Expand Down
4 changes: 4 additions & 0 deletions src/config/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ bool ConfigManager::load() {
loadFloatConfig(L, TRANSCENDANCE_CHANCE_FORMULA_A, "transcendanceChanceFormulaA", 0.0127);
loadFloatConfig(L, TRANSCENDANCE_CHANCE_FORMULA_B, "transcendanceChanceFormulaB", 0.1070);
loadFloatConfig(L, TRANSCENDANCE_CHANCE_FORMULA_C, "transcendanceChanceFormulaC", 0.0073);
loadFloatConfig(L, ANIMUS_MASTERY_MAX_MONSTER_XP_MULTIPLIER, "animusMasteryMaxMonsterXpMultiplier", 4.0);
loadFloatConfig(L, ANIMUS_MASTERY_MONSTER_XP_MULTIPLIER, "animusMasteryMonsterXpMultiplier", 2.0);
loadFloatConfig(L, ANIMUS_MASTERY_MONSTERS_XP_MULTIPLIER, "animusMasteryMonstersXpMultiplier", 0.1);

loadIntConfig(L, ACTIONS_DELAY_INTERVAL, "timeBetweenActions", 200);
loadIntConfig(L, ADVENTURERSBLESSING_LEVEL, "adventurersBlessingLevel", 21);
Expand Down Expand Up @@ -345,6 +348,7 @@ bool ConfigManager::load() {
loadIntConfig(L, AUGMENT_INCREASED_DAMAGE_PERCENT, "augmentIncreasedDamagePercent", 5);
loadIntConfig(L, AUGMENT_POWERFUL_IMPACT_PERCENT, "augmentPowerfulImpactPercent", 10);
loadIntConfig(L, AUGMENT_STRONG_IMPACT_PERCENT, "augmentStrongImpactPercent", 7);
loadIntConfig(L, ANIMUS_MASTERY_MONSTERS_TO_INCREASE_XP_MULTIPLIER, "animusMasteryMonstersToIncreaseXpMultiplier", 10);

loadStringConfig(L, CORE_DIRECTORY, "coreDirectory", "data");
loadStringConfig(L, DATA_DIRECTORY, "dataPackDirectory", "data-otservbr-global");
Expand Down
1 change: 1 addition & 0 deletions src/creatures/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ target_sources(${PROJECT_NAME}_lib PRIVATE
npcs/npc.cpp
npcs/npcs.cpp
npcs/spawns/spawn_npc.cpp
players/animus_mastery/animus_mastery.cpp
players/grouping/familiars.cpp
players/grouping/groups.cpp
players/grouping/guild.cpp
Expand Down
7 changes: 6 additions & 1 deletion src/creatures/combat/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,10 @@ void Combat::CombatHealthFunc(const std::shared_ptr<Creature> &caster, const std
}
}

if (targetPlayer && damage.primary.type == COMBAT_HEALING) {
damage.primary.value *= targetPlayer->getBuff(BUFF_HEALINGRECEIVED) / 100.;
}

damage.damageMultiplier += attackerPlayer->wheel()->getMajorStatConditional("Divine Empowerment", WheelMajor_t::DAMAGE);
g_logger().trace("Wheel Divine Empowerment damage multiplier {}", damage.damageMultiplier);
}
Expand Down Expand Up @@ -2250,7 +2254,8 @@ void Combat::applyExtensions(const std::shared_ptr<Creature> &caster, const std:
}
}
} else if (monster) {
chance = monster->critChance() * 100;
chance = monster->getCriticalChance() * 100;
bonus = monster->getCriticalDamage() * 100;
}

bonus += damage.criticalDamage;
Expand Down
26 changes: 26 additions & 0 deletions src/creatures/combat/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ std::shared_ptr<Condition> Condition::createCondition(ConditionId_t id, Conditio
case CONDITION_SOUL:
return ObjectPool<ConditionSoul, 1024>::allocateShared(id, type, ticks, buff, subId);

case CONDITION_LESSERHEX:
case CONDITION_INTENSEHEX:
case CONDITION_GREATERHEX:
case CONDITION_ATTRIBUTES:
return ObjectPool<ConditionAttributes, 1024>::allocateShared(id, type, ticks, buff, subId);

Expand All @@ -261,6 +264,7 @@ std::shared_ptr<Condition> Condition::createCondition(ConditionId_t id, Conditio
case CONDITION_MUTED:
case CONDITION_CHANNELMUTEDTICKS:
case CONDITION_YELLTICKS:
case CONDITION_POWERLESS:
case CONDITION_PACIFIED:
return ObjectPool<ConditionGeneric, 1024>::allocateShared(id, type, ticks, buff, subId);

Expand Down Expand Up @@ -464,6 +468,23 @@ std::unordered_set<PlayerIcon> ConditionGeneric::getIcons() const {
case CONDITION_ROOTED:
icons.insert(PlayerIcon::Rooted);
break;

case CONDITION_LESSERHEX:
icons.insert(PlayerIcon::LesserHex);
break;

case CONDITION_INTENSEHEX:
icons.insert(PlayerIcon::IntenseHex);
break;

case CONDITION_GREATERHEX:
icons.insert(PlayerIcon::GreaterHex);
break;

case CONDITION_POWERLESS:
icons.insert(PlayerIcon::Powerless);
break;

case CONDITION_GOSHNARTAINT:
switch (subId) {
case 1:
Expand Down Expand Up @@ -1004,6 +1025,11 @@ bool ConditionAttributes::setParam(ConditionParam_t param, int32_t value) {
return true;
}

case CONDITION_PARAM_BUFF_HEALINGRECEIVED: {
buffsPercent[BUFF_HEALINGRECEIVED] = std::max<int32_t>(0, value);
return true;
}

case CONDITION_PARAM_BUFF_DAMAGEDEALT: {
buffsPercent[BUFF_DAMAGEDEALT] = std::max<int32_t>(0, value);
return true;
Expand Down
10 changes: 9 additions & 1 deletion src/creatures/combat/spells.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ void Spell::addVocMap(uint16_t vocationId, bool b) {
vocSpellMap[vocationId] = b;
}

SpellGroup_t Spell::getGroup() {
SpellGroup_t Spell::getGroup() const {
return group;
}

Expand Down Expand Up @@ -1058,6 +1058,10 @@ bool InstantSpell::playerCastInstant(const std::shared_ptr<Player> &player, std:
return false;
}

if (player->hasCondition(CONDITION_POWERLESS) && getGroup() == SPELLGROUP_ATTACK) {
return false;
}

LuaVariant var;
var.instantName = getName();
std::shared_ptr<Player> playerTarget = nullptr;
Expand Down Expand Up @@ -1379,6 +1383,10 @@ bool RuneSpell::executeUse(const std::shared_ptr<Player> &player, const std::sha
return false;
}

if (player->hasCondition(CONDITION_POWERLESS) && getGroup() == SPELLGROUP_ATTACK) {
return false;
}

LuaVariant var;
var.runeName = getName();

Expand Down
2 changes: 1 addition & 1 deletion src/creatures/combat/spells.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class Spell : public BaseSpell {
[[nodiscard]] const VocSpellMap &getVocMap() const;
void addVocMap(uint16_t vocationId, bool b);

SpellGroup_t getGroup();
SpellGroup_t getGroup() const;
void setGroup(SpellGroup_t g);
SpellGroup_t getSecondaryGroup();
void setSecondaryGroup(SpellGroup_t g);
Expand Down
57 changes: 34 additions & 23 deletions src/creatures/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,13 +498,17 @@ void Creature::onDeath() {
bool lastHitUnjustified = false;
bool mostDamageUnjustified = false;
const auto &lastHitCreature = g_game().getCreatureByID(lastHitCreatureId);
const auto &thisPlayer = getPlayer();
const auto &thisCreature = getCreature();
const auto &thisMaster = getMaster();
const auto &thisMonster = getMonster();
std::shared_ptr<Creature> lastHitCreatureMaster;
if (lastHitCreature && getPlayer()) {
if (lastHitCreature && thisPlayer) {
/**
* @deprecated -- This is here to trigger the deprecated onKill events in lua
*/
lastHitCreature->deprecatedOnKilledCreature(getCreature(), true);
lastHitUnjustified = lastHitCreature->onKilledPlayer(getPlayer(), true);
lastHitCreature->deprecatedOnKilledCreature(thisCreature, true);
lastHitUnjustified = lastHitCreature->onKilledPlayer(thisPlayer, true);
lastHitCreatureMaster = lastHitCreature->getMaster();
} else {
lastHitCreatureMaster = nullptr;
Expand All @@ -517,6 +521,7 @@ void Creature::onDeath() {
int32_t mostDamage = 0;
std::map<std::shared_ptr<Creature>, uint64_t> experienceMap;
std::unordered_set<std::shared_ptr<Player>> killers;

for (const auto &[creatureId, damageInfo] : damageMap) {
if (creatureId == 0) {
continue;
Expand All @@ -533,12 +538,10 @@ void Creature::onDeath() {
mostDamageCreature = attacker;
}

if (attacker != getCreature()) {
if (attacker != thisCreature) {
const uint64_t gainExp = getGainedExperience(attacker);
const auto &attackerMaster = attacker->getMaster() ? attacker->getMaster() : attacker;
if (auto attackerPlayer = attackerMaster->getPlayer()) {
attackerPlayer->removeAttacked(getPlayer());

if (const auto &attackerPlayer = attackerMaster->getPlayer()) {
const auto &party = attackerPlayer->getParty();
killers.insert(attackerPlayer);
if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) {
Expand All @@ -563,36 +566,44 @@ void Creature::onDeath() {
}

for (const auto &[creature, experience] : experienceMap) {
creature->onGainExperience(experience, getCreature());
creature->onGainExperience(experience, thisCreature);
}

mostDamageCreature = mostDamageCreature && mostDamageCreature->getMaster() ? mostDamageCreature->getMaster() : mostDamageCreature;
const auto &mostDamageCreatureMaster = mostDamageCreature ? mostDamageCreature->getMaster() : nullptr;
mostDamageCreature = mostDamageCreatureMaster ? mostDamageCreatureMaster : mostDamageCreature;

for (const auto &killer : killers) {
if (const auto &monster = getMonster()) {
killer->onKilledMonster(monster);
} else if (const auto &player = getPlayer(); player && mostDamageCreature != killer) {
killer->onKilledPlayer(player, false);
if (thisMonster) {
killer->onKilledMonster(thisMonster);
} else if (thisPlayer) {
bool isResponsible = mostDamageCreature == killer || (mostDamageCreatureMaster && mostDamageCreatureMaster == killer);
if (isResponsible) {
killer->onKilledPlayer(thisPlayer, false);
}

killer->removeAttacked(thisPlayer);
}
}

/**
* @deprecated -- This is here to trigger the deprecated onKill events in lua
*/
const auto &mostDamageCreatureMaster = mostDamageCreature ? mostDamageCreature->getMaster() : nullptr;
if (mostDamageCreature && (mostDamageCreature != lastHitCreature || getMonster()) && mostDamageCreature != lastHitCreatureMaster) {
if (mostDamageCreature && (mostDamageCreature != lastHitCreature || thisMonster) && mostDamageCreature != lastHitCreatureMaster) {
if (lastHitCreature != mostDamageCreatureMaster && (lastHitCreatureMaster == nullptr || mostDamageCreatureMaster != lastHitCreatureMaster)) {
mostDamageUnjustified = mostDamageCreature->deprecatedOnKilledCreature(getCreature(), false);
mostDamageUnjustified = mostDamageCreature->deprecatedOnKilledCreature(thisCreature, false);
}
}

bool killedByPlayer = (mostDamageCreature && mostDamageCreature->getPlayer()) || (mostDamageCreatureMaster && mostDamageCreatureMaster->getPlayer());
if (getPlayer()) {
const auto &mostDamagePlayer = mostDamageCreature ? mostDamageCreature->getPlayer() : nullptr;
const auto &mostMasterPlayer = mostDamageCreatureMaster ? mostDamageCreatureMaster->getPlayer() : nullptr;
bool killedByPlayer = mostDamagePlayer || mostMasterPlayer;
if (thisPlayer) {
g_metrics().addCounter(
"player_death",
1,
{
{ "name", getNameDescription() },
{ "level", std::to_string(getPlayer()->getLevel()) },
{ "level", std::to_string(thisPlayer->getLevel()) },
{ "most_damage_creature", mostDamageCreature ? mostDamageCreature->getName() : "(none)" },
{ "last_hit_creature", lastHitCreature ? lastHitCreature->getName() : "(none)" },
{ "most_damage_dealt", std::to_string(mostDamage) },
Expand All @@ -613,7 +624,7 @@ void Creature::onDeath() {
{
{ "name", getName() },
{ "killer", killerName },
{ "is_summon", std::to_string(getMaster() ? true : false) },
{ "is_summon", std::to_string(thisMaster ? true : false) },
{ "by_player", std::to_string(killedByPlayer) },
}
);
Expand All @@ -622,11 +633,11 @@ void Creature::onDeath() {
bool droppedCorpse = dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
death(lastHitCreature);

if (droppedCorpse && !getPlayer()) {
g_game().removeCreature(static_self_cast<Creature>(), false);
if (droppedCorpse && !thisPlayer) {
g_game().removeCreature(thisCreature, false);
}

if (getMaster()) {
if (thisMaster) {
removeMaster();
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/creatures/creatures_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ enum ConditionType_t : uint8_t {
CONDITION_GREATERHEX = 33,
CONDITION_BAKRAGORE = 34,
CONDITION_GOSHNARTAINT = 35,
CONDITION_POWERLESS = 36,

// Need the last ever
CONDITION_COUNT
Expand Down Expand Up @@ -222,6 +223,7 @@ enum ConditionParam_t {
CONDITION_PARAM_INCREASE_MANADRAINPERCENT = 80,
CONDITION_PARAM_INCREASE_DROWNPERCENT = 81,
CONDITION_PARAM_CHARM_CHANCE_MODIFIER = 82,
CONDITION_PARAM_BUFF_HEALINGRECEIVED = 83,
};

enum stats_t {
Expand Down Expand Up @@ -1332,6 +1334,7 @@ enum class CreatureIconModifications_t {
Influenced,
Fiendish,
ReducedHealth,
ReducedHealthExclamation,
};

enum class CreatureIconQuests_t {
Expand Down
Loading

0 comments on commit be1cc7e

Please sign in to comment.