Skip to content

[yaml] [sql] [lua] Implement Hydra Mechanics - #11302

Open
ThrisStraizo wants to merge 1 commit into
LandSandBoat:basefrom
ThrisStraizo:hydrafight
Open

[yaml] [sql] [lua] Implement Hydra Mechanics#11302
ThrisStraizo wants to merge 1 commit into
LandSandBoat:basefrom
ThrisStraizo:hydrafight

Conversation

@ThrisStraizo

Copy link
Copy Markdown
Contributor

I affirm:

  • I understand that if I do not agree to the following points by completing the checkboxes my PR will be ignored.
  • I understand I should leave resolving conversations to the LandSandBoat team so that reviewers won't miss what was said.
  • I have read and understood the Contributing Guide and the Code of Conduct.
  • I have tested my code and the things my code has changed since the last commit in the PR and will test after any later commits.

What does this pull request do?

This PR implements all the mechanics for Hydra, including the the Hydra mixin, which governs how heads are broken and regenerate. From my limited time interacting with Hydra in Nyzul, its very likely they all work the same, using decreased head respawn rates that actively reduce the timer as the Hydra loses HP.

TY @siknoz for these extensive tests.

image

Using a modified version of the break mixin by @Nobutadas, I was able to get a very accurate looking version of head break and regenerate behavior.

The mixin also provides a 3k tp injection on head regeneration, which I've confirmed is used by other hydras.
Hydra in Wajoam also uses a tp ability every time he draws in.

All resistances and immunities double checked in my own caps.

https://youtu.be/6sxZ64itp7I
https://youtu.be/lHxfvDWQJa0

Steps to test these changes

Fight the 3 headed horror.

end

return skillList[math.randomInt(1, #skillList)]
end

@Xaver-DaRed Xaver-DaRed Aug 30, 2026

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.

proposal

entity.onMobMobskillChoose = function(mob, target, skillId)
    local skillList = {}
    local skillInfo =
    {
        [1] = { xi.mobSkill.TREMBLING,       100, -1, true,  true  },
        [2] = { xi.mobSkill.SERPENTINE_TAIL, 100, -1, true,  false },
        [3] = { xi.mobSkill.BAROFIELD,       100, -1, false, true  },
        [4] = { xi.mobSkill.NERVE_GAS,        30,  0, true,  true  },
        [5] = { xi.mobSkill.PYRIC_BULWARK,   100,  0, true,  true  },
        [6] = { xi.mobSkill.PYRIC_BLAST,     100,  0, false, true  },
        [7] = { xi.mobSkill.POLAR_BULWARK,   100,  1, true,  true  },
        [8] = { xi.mobSkill.POLAR_BLAST,     100,  1, false, true  },
    }

    local hpp         = mob:getHPP()
    local brokenHeads = mob:getAnimationSub()
    local isInFront   = target:isInfront(mob, 128)
    local isBehind    = target:isBehind(mob, 128)

    for i = 1, #skillInfo do
        if
            hpp <= skillInfo[i][2] and
            brokenHeads <= skillInfo[i][3] and
            (skillInfo[i][4] or isInFront) and
            (skillInfo[i][5] or isBehind)
        then
            table.insert(skillList, skillInfo[i][1])
        end
    end

    return skillList[math.randomInt(1, #skillList)]
end

end

return skillList[math.randomInt(1, #skillList)]
end

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.

I would suggest something similar here. This is hard to follow

end

return skillList[math.randomInt(1, #skillList)]
end

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.

and here aswell

end

return skillList[math.randomInt(1, #skillList)]
end

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.

guess

@ThrisStraizo
ThrisStraizo force-pushed the hydrafight branch 2 times, most recently from 9dfe1ed to 308e4cc Compare August 31, 2026 04:18
Comment on lines +69 to +81
mob:setMod(xi.mod.FIRE_RES_RANK, 9)
mob:setMod(xi.mod.ICE_RES_RANK, 9)
mob:setMod(xi.mod.WIND_RES_RANK, 9)
mob:setMod(xi.mod.EARTH_RES_RANK, 6)
mob:setMod(xi.mod.THUNDER_RES_RANK, 6)
mob:setMod(xi.mod.WATER_RES_RANK, 6)
mob:setMod(xi.mod.LIGHT_RES_RANK, 6)
mob:setMod(xi.mod.DARK_RES_RANK, 6)

mob:setMod(xi.mod.BLIND_RES_RANK, 6)
mob:setMod(xi.mod.POISON_RES_RANK, 6)
mob:setMod(xi.mod.SILENCE_RES_RANK, 9)
mob:setMod(xi.mod.SLOW_RES_RANK, 6)

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.

Can you move these to onMobInitialize and delete the res ranks from the mobs.yaml


params.baseDamage = mob:getWeaponDmg()
params.numHits = 1
params.fTP = { 4.25, 4.25, 4.25 } -- TODO: Capture fTPs

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.

If these were captured can we remove the TODO


params.baseDamage = mob:getWeaponDmg()
params.numHits = 1
params.fTP = { 4.0, 4.0, 4.0 } -- TODO: Capture fTPs

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.

same, if these were captured can we remove the TODO

Comment on lines +99 to +111
local brokenHeads = mob:getAnimationSub()

if brokenHeads == 0 then
mob:setMod(xi.mod.REGEN, 150)
end

if brokenHeads == 1 then
mob:setMod(xi.mod.REGEN, 70)
end

if brokenHeads == 2 then
mob:setMod(xi.mod.REGEN, 10)
end

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.

So since you are checking the regen on every tick I would suggest something like this:

This on top (out of mobFight)

local regenPerHead =
{
    [0] = 150,
    [1] = 70,
    [2] = 10,
}

Then you only need a single line:

    mob:setMod(xi.mod.REGEN, regenPerHead[mob:getAnimationSub()])

Comment thread scripts/mixins/families/hydra.lua Outdated

-- 0 -> 1 = 3 to 2 heads
-- 1 -> 2 = 2 to 1 heads
local handleBreak = function(mob)

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.

To keep it consistent with the rest of the definitions:

local function handleBreak(mob)

@ThrisStraizo
ThrisStraizo force-pushed the hydrafight branch 2 times, most recently from 548dc67 to 3c6589c Compare September 1, 2026 02:24
This PR implements all the mechanics for Hydra.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants