Skip to content

Conversation

@dallano
Copy link
Contributor

@dallano dallano commented Sep 5, 2025

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.

Assault Framework + Containerization

This PR aims to allow Assaults to utilize the container framework to create globalized, isolated, and more accessible information. This proceeds to do the following:

  • Better utilization of dynamic ID lookups as assaults use unconventional ID patterns and create awkward scenarios case-by-case
  • All relevant assault information can be stored into 1 file. This information will include mob and npc data, loot tables (to come in a future PR), experimental flags, and other general information about the assault.
  • Overwritable functions to allow custom behaviors from assault to assault.

Overall this should drastically cut down on file sizes and scattering of info detailing a single assault.

This framework, as is, does not effect any other existing assaults or instances, but it does require entire zones to be converted all at once. Luckily as it stands each zone only has 1 assault implemented, so conversion will be simple.

Once conversion of assaults is complete, loot and appraisal can be more easily localized to their relevant assault file, and will require a slight rework to handle the use of globalized containers.

Note

  • This framework doesn't effect the base instance behavior, and all related content continue work identically as before. However it does add the ability to pass in information directly into instance funcs, allowing for better utilization of future instance containers (salvage, campaign ops, quests, etc.).
  • With a brief review of Nyzul Isle behavior, it should slot nicely into this framework.
  • NPC pos changes made to extermination based from the linked capture: https://www.youtube.com/watch?v=w2YNiNyWT2M&ab_channel=RainbowChaser

Steps to test these changes

  • Add all merc badges (key items 780, 783, 784 will cover it)
  • Add an ID assault tag (key item 787)
  • Speak to any mission giver and accept the first mission available (Only these are implemented). However the conversion done for Extermination is the third option offered by Bhoyupplo. So make sure to grab that one when testing the new container framework
  • Head to the relevant staging point
  • Give yourself an assault arm band
  • Click on runic portal and enter assault
  • To quickly complete any assault, use !exec player:getInstance():setProgress(100)
  • Interact with Armory crate + Rune of Release
  • Return to Rytaal to update your assault mission status
  • Repeat

@dallano dallano changed the title Assault Containerization + Framework [Lua] Assault Containerization + Framework Sep 5, 2025
Copy link
Contributor

@MowFord MowFord left a comment

Choose a reason for hiding this comment

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

Very cool. Don't take this as anything more than small suggestions based on my initial impression

-- 'Default' behavior. It's up to each instance whether or not they want to use this logic
xi.instance.onInstanceCreatedCallback = function(player, instance)
local zoneLookup = xi.instance.lookup[instance:getZone():getID()]
-- Can pass instance custcene information directly if accessible from container, otherwise will try and find it from the player's instance
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
-- Can pass instance custcene information directly if accessible from container, otherwise will try and find it from the player's instance
-- Can pass instance cutscene information directly if accessible from container, otherwise will try and find it from the player's instance

local zoneLookup = xi.instance.lookup[instanceZoneId]
local csidEntry, optionEntry = unpack(zoneLookup[1][3])
if instanceInfo == nil then
instanceInfo = xi.instance.lookup[instance:getZone():getID()][1][3]
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we should make a getZoneID binding like other entities have

instanceObject.onInstanceFailure = function(instance)
local chars = instance:getChars()
content.loot =
{
Copy link
Contributor

@MowFord MowFord Sep 5, 2025

Choose a reason for hiding this comment

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

Bcnm have loot defined even for experimental battles. The experimental flag makes the mobs super strong also I think makes no loot drop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm hoping to incorporate loot in a next PR. Perhaps we can look into doing the same thing with assaults.

end

local toadMob = GetMobByID(ID.mob.UNDEAD_TOAD, instance)
local toadMob = GetMobByID(ID.CARRION_CRAB + 23, instance)
Copy link
Contributor

Choose a reason for hiding this comment

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

Kinda personal preference, but I wonder if it would be more readable/future proof to make CARRION_CRAB the result of GetTableOfIDs and using smaller offsets for these three undead mobs. I.e. this would then become: id.carrion_crabs[#id.carrion_crabs] + 3

And defining the instance would define the offsets more dynamically using the size of the table

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. It's quite a huge + unintelligible offset. an undead mob offset would be proper.


if content.wallNPCs then
for _, npc in pairs(content.wallNPCs) do
GetNPCByID(npc, instance):setAnimation(xi.animation.OPEN_DOOR)
Copy link
Contributor

Choose a reason for hiding this comment

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

Feel like there's going to be edge cases for this, but for now that's fine

Copy link
Contributor Author

@dallano dallano Sep 6, 2025

Choose a reason for hiding this comment

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

I agree. I noticed there's a big mix of these wall NPCs in npc_list set to either open or closed based on varying capture data. I think it proper to set them all to be closed, and if a capture reports it as open, then that assault individually will open its instance's door... if that made sense.

I think we should set all doors as closed - if a capture reports a door being open in say excavation duty, then excavation duty will handle the opening of that door for its instance.

But Nyzul isle might be weird here. I'm not sure how the floors are generated to be honest. Although it could simply just not define any wall NPCs and overwite onInstanceCreated to change doors as needed.

@WinterSolstice8
Copy link
Contributor

I think I missed it, is the whole party checked for orders? Though maybe that's not in your changes

@dallano
Copy link
Contributor Author

dallano commented Sep 6, 2025

I think I missed it, is the whole party checked for orders? Though maybe that's not in your changes

Yes, all members are checked for orders / same qualifications as the registering members. Save the assault armband. only the initiating member is checked for that.

@dallano dallano force-pushed the assault_rework branch 3 times, most recently from dfdb0ae to 43a5c40 Compare September 6, 2025 02:28
Updates Assaults to use the Container framework to allow for global lookups.
All existing assaults will continue to perform as expected. This framework will not effect their performance.
This commit also aims to simplify the creation and maintenance of assaults by moving all relevant information into 1 instance file, moreover it allows assaults to more easily make use of the dynamic ID system and move away from the need of hardcoded ID definitions.
Builds a scalable framework that would allow for easy customization where needed by creating overwritable functions in the container constructor itself.
Updates assault Extermination to use the framework as an example
Implemented missing framework to Ilrusi Atoll
Globalized assault mission giver behavior (save nyzul isle)
Added an experimental tag that can be toggled

Sanity checks + PR change requests

Attempt to fix sanity checks by turning instanceAssault into a local and passed through xi.assault

Fixed PR requests
- Use zoneID binding instead of getZone():getID()
- Typo
- Better ID lookups for undead mob spawning

Sanity Fixes

More Sanity fixes with bad lua styling

Move function overrides

Move function overrides into the InstanceAssault container itself
@github-actions
Copy link

This PR has been automatically marked as stale because
it has not had recent activity. It will be closed if no
further activity occurs.

@github-actions github-actions bot added the stale label Sep 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants