Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 0 additions & 6 deletions scripts/actions/abilities/pets/chronoshift.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ abilityObject.onPetAbility = function(target, pet, petskill, summoner, action)
petskill:setMsg(xi.msg.basic.NO_EFFECT)
end

pet:timer(5000, function()
if summoner then
summoner:despawnPet()
end
end)

return effectCount
end

Expand Down
16 changes: 12 additions & 4 deletions scripts/actions/abilities/pets/zantetsuken.lua

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Damage to NMs caps at 9999 or 10-20% of their current HP, whichever is lower. However, percentage damage multipliers are applied after this calculation. This is why damage may exceed 9999."

Unless you checked it on retail, be sure to clamp the damage to 10% of the targets HP vs NMs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I didn't modify the damage portion but I can attempt to fix that too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow up question: Are there any relatively easy NMs to access on retail that we have accurate stats for? If I'm going to redo the damage equation, I'd like to have a baseline to work with ideally

Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@
local abilityObject = {}

abilityObject.onAbilityCheck = function(player, target, ability)
return xi.job_utils.summoner.canUseBloodPact(player, player:getPet(), target, ability)
return 0, 0
end

abilityObject.onPetAbility = function(target, pet, petskill, summoner, action)
if summoner == nil then
return 0
end

local returnParam = 0
local power = summoner:getMP() / utils.clamp(summoner:getMaxMP(), 1, 9999)

summoner:delStatusEffect(xi.effect.ASTRAL_FLOW)

if target:isNM() then
local params = {}

Expand All @@ -37,14 +43,16 @@ abilityObject.onPetAbility = function(target, pet, petskill, summoner, action)

returnParam = info.damage
else
-- Insta-kill: Highly innacurate against regular monsters.
local chance = 50 * power / utils.clamp(petskill:getTotalTargets(), 1, 50)
-- Zantetsuken chance to kill starts at MP/MaxMP so at full MP the kill chance is 100%
-- This is then divided by the number of targets. So with 4 targets, each one has a 25%
-- to die if the summoner has full MP. I am guessing at the 1% floor with 100 targets.
-- I have never tested this against more than 5-6 targets on retail.
local chance = 100 * power / utils.clamp(petskill:getTotalTargets(), 1, 100)

if
math.randomInt(1, 100) <= chance and
target:getAnimation() ~= 33
then
petskill:setMsg(xi.msg.basic.SKILL_ENFEEB_IS)
target:takeDamage(target:getHP(), pet, xi.attackType.MAGICAL, xi.damageType.DARK)

returnParam = xi.effect.KO
Expand Down
47 changes: 30 additions & 17 deletions scripts/globals/pets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,26 +116,39 @@ xi.pet.spawnPet = function(caster, petID, state, target)
end)
end
elseif petID == xi.petId.ODIN then
if target then
caster:petAttack(target)
--pet:timer(5000, function()
-- pet:usePetAbility(xi.jobAbility.ZANTETSUKEN, target)
--end)
local pet = caster:getPet()
if pet then
pet:timer(5000, function()
if target and target:isAlive() then
pet:usePetAbility(xi.jobAbility.ZANTETSUKEN, target)
end
end)
-- Retail Odin despawns 15 seconds after appearing even if he fails to use Zantetsuken
pet:timer(15000, function()
caster:despawnPet()
end)
end
elseif petID == xi.petId.ATOMOS then
if target then
-- Use Deconstruction on the target 3 seconds after spawning.
local pet = caster:getPet()
if pet then
-- Timed sequence after spawning, wait -> Deconstruction -> wait -> Chronoshift (despawn pet after complete)
pet:timer(3000, function()
local pet = caster:getPet()
if pet then
-- Timed sequence after spawning, wait -> Deconstruction -> wait -> Chronoshift -> despawn
-- Full cycle takes 5s -> 5s -> 5s from summon to despawn + charge times which ends up at about 17s
-- On retail the behavior appears to be that Atomos will always do Deconstruction if the target is in range
-- If the target moves out of range, Atomos still does Chronoshift as long as the summoner is within 30 yalms
-- If the target and the summoner are both out of range then Atomos just waits and despawns
pet:timer(5000, function()
if target and target:isAlive() then
pet:usePetAbility(xi.jobAbility.DECONSTRUCTION, target)
end)

pet:timer(10000, function()
pet:usePetAbility(xi.jobAbility.CHRONOSHIFT, pet)
end)
end
end
end)
-- 11 seconds here gives time for the animation to consistently line up to retail
pet:timer(11000, function()
pet:usePetAbility(xi.jobAbility.CHRONOSHIFT, pet)
end)
-- Ensure Atomos always despawns
pet:timer(17000, function()
caster:despawnPet()
end)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion sql/abilities.sql
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ INSERT INTO `abilities` VALUES (666,'pavor_nocturnus',15,98,4,60,174,0,0,94,2000
INSERT INTO `abilities` VALUES (667,'blindside',15,99,4,60,173,0,0,94,2000,0,6,10,0,0,1,60,0,0,'SOA');
INSERT INTO `abilities` VALUES (668,'deconstruction',15,75,4,0,0,0,0,0,0,0,6,20,0,0,0,0,0,0,NULL);
INSERT INTO `abilities` VALUES (669,'chronoshift',15,75,4,0,0,0,0,0,0,0,6,0,0,14,0,0,0,0,NULL);
-- INSERT INTO `abilities` VALUES (670,'zantetsuken',22,1,1,0,300,0,0,???,2000,0,6,10,0,10,450,900,0,0,NULL);
-- INSERT INTO `abilities` VALUES (670,'zantetsuken',22,1,1,0,300,0,0,151,2000,0,6,10,0,10,450,900,0,0,NULL);
INSERT INTO `abilities` VALUES (671,'perfect_defense',15,75,1,0,300,0,0,152,2000,0,6,0,0,10,0,0,0,2,NULL);
INSERT INTO `abilities` VALUES (672,'foot_kick',9,25,257,1,102,0,0,0,2000,0,6,3,0,0,1,60,0,0,NULL);
INSERT INTO `abilities` VALUES (673,'dust_cloud',9,25,257,1,102,0,0,0,2000,0,6,3,0,10,1,60,0,0,NULL);
Expand Down
2 changes: 1 addition & 1 deletion sql/pet_skills.sql
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ INSERT INTO `pet_skills` VALUES (666,0,155,'pavor_nocturnus',0,0,12,2000,1000,4,
INSERT INTO `pet_skills` VALUES (667,0,173,'blindside',0,0,10,2000,1000,4,317,@SKILLFLAG_BLOODPACT_RAGE,0,13,0,@SC_GRAVITATION,@SC_TRANSFIXION,0); -- No LUA yet
INSERT INTO `pet_skills` VALUES (668,0,171,'deconstruction',0,0,21,2000,1000,4,323,@SKILLFLAG_BLOODPACT_RAGE,0,13,0,0,0,0);
INSERT INTO `pet_skills` VALUES (669,0,172,'chronoshift',1,14,0,2000,1000,3,283,@SKILLFLAG_BLOODPACT_WARD,0,13,0,0,0,0);
-- 670: Zantetsuken 10y (Radius 10y)
INSERT INTO `pet_skills` VALUES (670,0,151,'zantetsuken',4,15,15.0,2000,1000,4,277,@SKILLFLAG_ASTRAL_FLOW | @SKILLFLAG_BLOODPACT_RAGE,0,13,0,0,0,0); -- Conal 15y, anim/msg from capture

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a capture proving this is 15y on both range and radius?

I can only prove 10y so far on both range and radius (the same values the DATs claim). Given it's a special type of move I'm willing to believe they may not be right.

Furthermore 15y isn't used by any other ability in the game (closest values would be 14 or 16).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stated it in the PR: "Forgot to mention I got the animation id from retail and I lined up a 5 mobs in a row then cast odin in a line to guesstimate the range. It's between 14-17 yalms based on which mobs got hit in my test, so I am guessing it's actually 15 yalms."

If all other abilities are 14 or 16, then I don't have enough evidence to prove it. It killed something at 14, it did not kill something at just over 17. It could be 16. I can check later. Radius doesn't make sense since this is a conal attack

INSERT INTO `pet_skills` VALUES (671,0,152,'perfect_defense',1,10,0,2000,1000,3,316,@SKILLFLAG_ASTRAL_FLOW | @SKILLFLAG_BLOODPACT_WARD,0,13,0,0,0,0);
-- Jug Pet Ready Moves
INSERT INTO `pet_skills` VALUES (672,3840,1,'foot_kick',0,0,3,2000,1500,4,185,@SKILLFLAG_NONE,0,11,0,@SC_REVERBERATION,0,0);
Expand Down
2 changes: 1 addition & 1 deletion src/map/ai/states/petskill_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ bool CPetSkillState::Update(timer::time_point tick)
PSummoner->StatusEffectContainer->GetStatusEffect(xi::StatusEffect::AvatarsFavor)->SetPower(power > 11 ? power : 11);
}

if (PTarget && m_PEntity->getPetType() == PET_TYPE::AVATAR && (m_PEntity->petID() != PETID_ALEXANDER && m_PEntity->petID() != PETID_ATOMOS))
if (PTarget && m_PEntity->getPetType() == PET_TYPE::AVATAR && (m_PEntity->petID() != PETID_ALEXANDER && m_PEntity->petID() != PETID_ATOMOS && m_PEntity->petID() != PETID_ODIN))
{
auto* PBattleTarget = dynamic_cast<CBattleEntity*>(PTarget);
if (PBattleTarget &&
Expand Down
Loading