Skip to content

Commit

Permalink
[core] [lua] Implement TH procs
Browse files Browse the repository at this point in the history
  • Loading branch information
WinterSolstice8 committed Jan 22, 2025
1 parent 75c76e2 commit a89c374
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 10 deletions.
4 changes: 2 additions & 2 deletions scripts/enum/mod.lua
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ xi.mod =
TRIPLE_ATTACK = 302,
TRIPLE_ATTACK_DMG = 1039, -- Increases "Triple Attack" damage/"Triple Attack" damage + (in percents, e.g. +20 = +20% damage)
TREASURE_HUNTER = 303,
TREASURE_HUNTER_PROC = 1048, -- TODO: Increases Treasure Hunter proc rate (percent)
TREASURE_HUNTER_CAP = 1049, -- TODO: Increases the Treasure Hunter Cap (e.g. THF JP Gift)
TREASURE_HUNTER_PROC = 1048, -- Increases Treasure Hunter proc rate (percent)
TREASURE_HUNTER_CAP = 1049, -- Increases the Treasure Hunter Cap (e.g. THF JP Gift)
TAME = 304,
RECYCLE = 305,
ZANSHIN = 306,
Expand Down
3 changes: 2 additions & 1 deletion scripts/globals/job_utils/thief.lua
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ end
xi.job_utils.thief.useFeint = function(player, target, ability)
local bonus = player:getMod(xi.mod.AUGMENTS_FEINT) * player:getMerit(xi.merit.FEINT) / 25 -- Divide by the merit value (feint is 25) to get the number of merit points

player:addStatusEffect(xi.effect.FEINT, 150 + bonus, 0, 60) -- -150 Evasion base
-- Subpower is the proc rate bonus for TH procs
player:addStatusEffect(xi.effect.FEINT, 150 + bonus, 0, 60, 0, player:getMerit(xi.merit.FEINT) - 25) -- -150 Evasion base, 0% base TREASURE_HUNTER_PROC, every merit past 1 gives 25%
end

xi.job_utils.thief.useFlee = function(player, target, ability)
Expand Down
15 changes: 13 additions & 2 deletions src/map/enmity_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,20 @@ void CEnmityContainer::UpdateEnmity(CBattleEntity* PEntity, int32 CE, int32 VE,
}

// Apply TH only if this was a direct action
if (directAction && PEntity->getMod(Mod::TREASURE_HUNTER) > m_EnmityHolder->m_THLvl)
if (directAction)
{
m_EnmityHolder->m_THLvl = PEntity->getMod(Mod::TREASURE_HUNTER);
int16 THlevel = std::min<int16>(8, PEntity->getMod(Mod::TREASURE_HUNTER));

// Enforce TH8 as max for THF main and TH4 as non-THF main
if (PEntity->GetMJob() != JOB_THF)
{
THlevel = std::min<int16>(4, PEntity->getMod(Mod::TREASURE_HUNTER));
}

if (m_EnmityHolder->m_THLvl < THlevel)
{
m_EnmityHolder->m_THLvl = THlevel;
}
}

auto enmity_obj = m_EnmityList.find(PEntity->id);
Expand Down
10 changes: 8 additions & 2 deletions src/map/entities/battleentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2479,8 +2479,14 @@ bool CBattleEntity::OnAttack(CAttackState& state, action_t& action)
// Apply Feint
if (CStatusEffect* PFeintEffect = StatusEffectContainer->GetStatusEffect(EFFECT_FEINT))
{
PTarget->StatusEffectContainer->AddStatusEffect(
new CStatusEffect(EFFECT_EVASION_DOWN, EFFECT_EVASION_DOWN, PFeintEffect->GetPower(), 3, 30));
if (PTarget->StatusEffectContainer->AddStatusEffect(new CStatusEffect(EFFECT_EVASION_DOWN, EFFECT_EVASION_DOWN, PFeintEffect->GetPower(), 3, 30)))
{
auto PEffect = PTarget->StatusEffectContainer->GetStatusEffect(EFFECT_EVASION_DOWN);

// When Feint's evasion down effect is on, the target can get "debuffed" with TREASURE_HUNTER_PROC +25% * level above first on Feint
PEffect->addMod(Mod::TREASURE_HUNTER_PROC, PFeintEffect->GetSubPower()); // Remove TREASURE_HUNTER_PROC debuff on effect wearing off. This isnt added to the mob directly.
PTarget->addModifier(Mod::TREASURE_HUNTER_PROC, PFeintEffect->GetSubPower()); // Add TREASURE_HUNTER_PROC debuff immediately to mob
}
StatusEffectContainer->DelStatusEffect(EFFECT_FEINT);
}

Expand Down
4 changes: 2 additions & 2 deletions src/map/modifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,8 @@ enum class Mod
TRIPLE_ATTACK = 302, // Percent chance
TRIPLE_ATTACK_DMG = 1039, // Increases "Triple Attack" damage/"Triple Attack" damage + (in percents, e.g. +20 = +20% damage)
TREASURE_HUNTER = 303, // Percent chance
TREASURE_HUNTER_PROC = 1048, // TODO: Increases Treasure Hunter proc rate (percent)
TREASURE_HUNTER_CAP = 1049, // TODO: Increases the Treasure Hunter Cap (e.g. THF JP Gift)
TREASURE_HUNTER_PROC = 1048, // Increases Treasure Hunter proc rate (percent)
TREASURE_HUNTER_CAP = 1049, // Increases the Treasure Hunter Cap (e.g. THF JP Gift)
SNEAK_ATK_DEX = 830, // % DEX boost to Sneak Attack (if gear mod, needs to be equipped on hit)
TRICK_ATK_AGI = 520, // % AGI boost to Trick Attack (if gear mod, needs to be equipped on hit)
MUG_EFFECT = 835, // Mug effect as multiplier
Expand Down
1 change: 1 addition & 0 deletions src/map/packets/message_standard.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ enum class MsgStd
LevelSyncRemoveLowLevel = 554, // Level sync will be deactivated in 30 seconds. The Level Sync designee has fallen below level 10.
LevelSyncRemoveJobChange = 555, // Level sync will be deactivated in 30 seconds. A party member has undergone a job change.
LevelSyncRemoveIneligibleExp = 556, // Level sync will be deactivated in 30 seconds. The Level Sync designee is incapable of receiving experience points.
TreasureHunterProc = 603, // Additional effect: Treasure Hunter effectiveness against <Target> increases to <number>
};

class CCharEntity;
Expand Down
51 changes: 50 additions & 1 deletion src/map/utils/battleutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,56 @@ namespace battleutils

if (PAttacker->objtype == TYPE_PC)
{
PChar = (CCharEntity*)PAttacker;
PChar = dynamic_cast<CCharEntity*>(PAttacker);

// TODO: cleanup lua further so we can handle all this add effect stuff somewhere else
// Treasure hunter takes priority over enspells
if
(PChar &&
finaldamage > 0 &&
isFirstSwing &&
PDefender->objtype == TYPE_MOB &&
PChar->GetMJob() == JOB_THF &&
PChar->hasTrait(TRAITTYPE::TRAIT_TREASURE_HUNTER)) // TH trait as a requirement is assumed, but likely. Could this just be a level 15 check instead?
{
auto PMob = dynamic_cast<CMobEntity*>(PDefender);
if (PMob && PMob->m_THLvl < (12 + PChar->getMod(Mod::TREASURE_HUNTER_CAP))) // TH proc cap is 12 + job gifts
{
int16 playerTH = PChar->getMod(Mod::TREASURE_HUNTER);

int16 THdiff = PMob->m_THLvl - playerTH;

// Auto upgrade TH to mod level up to TH8
if (THdiff < 0 && PMob->m_THLvl < 8)
{
PMob->m_THLvl = std::min<int16>(8, playerTH);

// Recalculate diff
THdiff = PMob->m_THLvl - playerTH;
}

float procRate = 0.04f / std::pow<float>(2.f, std::max<int16>(0, THdiff)); // Numbers below diff of -1 (i.e. TH 10 vs mobs TH8 level) are not known. Assume no extra bonus for now.

// Impossible to tell if SA or TA was used currently. Allegedly it gives a 10x(!) multiplicative bonus.
// TODO: fix that
// Not known if Feint and Gifts are multiplicative or additive. Currently assuming additive
// The mob has an evasion down from feint that applies this mod.
// The player has job point gifts that apply thsi mod.
float procRateBonus = 1.f + (PChar->getMod(Mod::TREASURE_HUNTER_PROC) + PMob->getMod(Mod::TREASURE_HUNTER_PROC)) / 100.f;

procRate *= procRateBonus;

if (xirand::GetRandomNumber<float>(0.f, 1.f) <= procRate)
{
PMob->m_THLvl++;

Action->additionalEffect = SUBEFFECT_LIGHT_DAMAGE; // Looks like enlight, and is reflected in the capture
Action->addEffectMessage = static_cast<uint16>(MsgStd::TreasureHunterProc);
Action->addEffectParam = PMob->m_THLvl;
return;
}
}
}
}

Action->additionalEffect = SUBEFFECT_NONE;
Expand Down

0 comments on commit a89c374

Please sign in to comment.