Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pandemonium Warden: Full Rework #4538

Closed
wants to merge 1 commit into from
Closed

Pandemonium Warden: Full Rework #4538

wants to merge 1 commit into from

Conversation

MowFord
Copy link
Contributor

@MowFord MowFord commented Sep 22, 2023

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?

Port of Pandemonium Warden from WingsXI after countless hours of research/testing.

  • Odd-number phases to match retail as simply a short intermediate phase
  • Mob spell/skill list defined in mob's lua per phase for pet and PW
    • This removes need for most familyid conditionals in skill luas
  • Astral Flow given retail-accurate delay on spawn
  • Phase and pet change logic moved to functions
  • Added flavor text to PW spawn/death

Mobskill adjustments:

  • Cackle: wasn't coded
  • Brainjack: was DD instead of DoT
  • Diamondhide: AoE mobskill but was only ever applying stoneskin to self
  • Fossilizing breath: only used if target is in front

I do have one concern on the phase and pet functions: They don't function (har har) as local function since they call eachother. It works as global functions but I'm sure this isn't what is preferred Got it working with a local table of functions

Steps to test these changes

!pos 200 33 -140 68
Spawn by trading Pandemonium key: !additem 2572 or manually !spawnmob 17056168

Fight and bask in his greatness.

Outline of fight:

Each phase has a starting HP amount. The even-numbered phases start low enough that low-hp mobskills are immediately available and less TP is required to use a mobskill
Odd-numbered phases are dverger form, and are hard-coded to use cackle, then hellsnap, then change phase. No damage can be inflicted. And pets do not cast spells
Each phase, PW has the job's respective 2-hour ability at 50% of the starting HP
Final phase is the "true form" and every 25% uses astral flow, which resummons all pets as well as 8 avatars.
Everyone except tank should be prepared to get away when this happens, though there's plenty of time to run away unless you get stun locked by pet spells
"All avatars are summoned at once, and with them plus the lamps up, its hard to move your character."
"You will probably get locked in place and die from game mechanics alone."
During phase change:
PW is stunned to interrupt any current action (since it's not dying, just disappearing)
PL are despawned
PW/PL are disappeared and model/animation sub are adjusted
PW reappears and stun is removed
PL are respawned
All PW buffs are wiped
All mobskill LUA were mostly cleared of family-specific restrictions to let this single PW LUA handle everything
phase change sets skill and spell list for PW and PL
If full wipe happens, DoT will keep PW from regen, which will keep him in current form. If he regens past his phase HP, he resets to phase 1
In each even phase, he has access to the respective mobskills of that mob model:

  • Chariots
    • Phases 2, 4, 6, 8
  • 10k HP each
  • Pets: Archaic Gears
  • Gulool Ja Ja
    • Phase 10
  • 15000 HP
  • Pets: Mamool Ja
  • Medusa
    • Phase 12
  • 15000 HP
  • Pets: Lamiae
  • Gurfurlur the Menacing
    • Phase 14
  • 15000 HP
  • Pets: Trolls
  • Khimaira
    • Phase 16
  • 20000 HP
  • Pets: Puks
  • Hydra
    • Phase 18
  • 20000 HP
  • Pets: Dahaks
  • Cerberus
    • Phase 20
  • 20000 HP
  • Pets: Bombs
  • Dvergr
    • Phase 21
  • 147000 HP
  • Pets: Miniature Dvergr

end

return returnEffect
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we setting and checking a local var on the mob?
Why not just...

local typeEffect = typeEffects[math.random(1, #typeEffects)]

And then we just don't set local variables on the mob nor check them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because that would be a different effect for each player

Copy link
Contributor Author

Choose a reason for hiding this comment

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

image

@zach2good zach2good changed the title PW: Full Rework Pandemonium Warden: Full Rework Sep 22, 2023
Comment on lines -13 to -22
if mob:getFamily() == 91 then
local mobSkin = mob:getModelId()

if mobSkin == 1746 then
return 0
else
return 1
end
end

Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't looked at the rest, but love all of these exceptions being removed 🙏

@Xaver-DaRed
Copy link
Contributor

Xaver-DaRed commented Sep 22, 2023

Ok, so about Brainjack...

The number of status effects is limited. Unlike with modifiers, we have a limit on available slots for them.
So whenever possible, we should avoid creating new status effects when it isnt absolutely necesary.

In this case, I think we could avoid creating brainjack altogether.
For instance, we could use Charm's effect subpower to set the power of the DoT. Like so...

Brainjack skill script

mobskillObject.onMobWeaponSkill = function(target, mob, skill)
    local duration   = 90
    local typeEffect = xi.effect.CHARM_I

    if not target:isPC() then
        skill:setMsg(xi.msg.basic.SKILL_MISS)
        return typeEffect
    elseif mob:getFamily() == 316 then -- Pandemonium Warden
        duration = 30
    end


    local msg = xi.mobskills.mobPhysicalStatusEffectMove(mob, target, skill, typeEffect, 0, 0, duration)
    if msg == xi.msg.basic.SKILL_ENFEEB_IS then
        target:addStatusEffectEx(typeEffect, 0, 0, 0, duration, 0, 25)
        mob:charm(target)
        mob:resetEnmity(target)
    end

    skill:setMsg(msg)

    return typeEffect
end

Charm effect script

effectObject.onEffectGain = function(target, effect)
    local DoT = effect:getSubPower()
    
    if DoT > 0 then
        target:addMod(xi.mod.REGEN_DOWN, DoT)
    end
end

effectObject.onEffectTick = function(target, effect)
end

effectObject.onEffectLose = function(target, effect)
    local DoT = effect:getSubPower()

    target:setTP(0)
    target:uncharm()

    -- remove brainjack if present

    if DoT > 0 then
        target:delMod(xi.mod.REGEN_DOWN, DoT)
    end
end

DISCLAIMER: I made this inpromptu. Would need testing. However, the real point here is that we should really try not to create new status effects whenever possible if it isn't absolutely necesary.

Comment on lines 23 to 24
PW_WHO_DARES = 7964, -- Pandemonium Warden: Who dares disturb these gates...
PW_END_OF_NOTHING = 7965, -- Pandemonium Warden: This is the end...of nothing...
Copy link
Contributor

Choose a reason for hiding this comment

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

The comments following text IDs need to match exactly what we have listed in our extracts in UpdateExtractor: https://github.com/LandSandBoat/UpdateExtractor/blob/main/out/scripts/zones/Aydeewa_Subterrane/Text.lua.raw.txt#L7870-L7871

Otherwise, when/if there are ID shifts during version updates our automatic tooling will fail

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wow good info, thanks!

@MowFord
Copy link
Contributor Author

MowFord commented Sep 22, 2023

I've got Xaver's idea working in theory, and lua prints confirm it's applying the DoT... but it reliably crashes my game when applying the effect with subid 0 (my guess on the culprit). I'll have to play around with it later unless someone knows what the dealio is

Edit: actually any reason not to just use the main charm effect power to signal brainjack?

Comment on lines 482 to 495
entity.onMobDeath = function(mob, player, isKiller)
if player ~= nil then
player:addTitle(xi.title.PANDEMONIUM_QUELLER)
mob:showText(mob, ID.text.PW_END_OF_NOTHING)
end

pwFuncs.despawnPets()
end
Copy link
Contributor

Choose a reason for hiding this comment

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

onMobDeath was changed to pass a table of options instead of isKiller. You want the death text behind that so it doesn't get spammed for each player in the party, noKiller is if it dies while unclaimed like from a DoT or something.

entity.onMobDeath = function(mob, player, optParams)
    if optParams.isKiller or optParams.noKiller then
        mob:showText(mob, ID.text.PW_END_OF_NOTHING)
    end

    if player ~= nil then
        player:addTitle(xi.title.PANDEMONIUM_QUELLER)
    end

    pwFuncs.despawnPets()
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice. I remember reading about those changes but this is my first time using the new properties.

Also on wings i wasn't using mob:showText so i was able to run it for every player. Good catch there.

@MowFord
Copy link
Contributor Author

MowFord commented Sep 23, 2023

Well I'm ashamed to admit I can't figure out why my adjustments to mobskills/brainjack.lua would reliably crash my game shortly after the charm, but I've adjusted things and applied the dot to the mod stack of the charm effect and it works well:

        target:addMod(xi.mod.REGEN_DOWN, 25)
        -- apply regen_down on the target, and stack DoT on the effect so it gets removed when charm is removed
        local effect = target:getStatusEffect(typeEffect)
        effect:addMod(xi.mod.REGEN_DOWN, 25)

image

TL;DR - something about manually setting the skill message instead of using xi.mobskills.mobPhysicalStatusEffectMove to apply the charm effect was crashing the client, but it's fixed now.

@MowFord
Copy link
Contributor Author

MowFord commented Sep 23, 2023

image

left PW with regen_down 1000 and it ran through all the phases no problem

@MowFord
Copy link
Contributor Author

MowFord commented Sep 24, 2023

Was reminded that the 4 chariot phases weren't using the different model IDs that they should, which then also alerted me to the fact that homing missile wasn't triggering in phase 8.

Both are resolved in this newest force push

- Odd-number phases to match retail as simply a short intermediate phase
- Mob spell/skill list defined in mob's lua per phase for pet and PW
  - This removes need for most familyid conditionals in skill luas
- Astral Flow given retail-accurate delay on spawn
- Phase and pet change logic moved to functions
- Coded skills: cackle, brainjack
- Added flavor text to PW spawn/death
@MowFord
Copy link
Contributor Author

MowFord commented Nov 7, 2023

went ahead and broke up this PR into the required sql changes here: #4706

@MowFord MowFord closed this by deleting the head repository Dec 15, 2023
@MowFord MowFord mentioned this pull request Dec 15, 2023
4 tasks
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.

4 participants