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

Flag Dream Block Support #849

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from

Conversation

wuke32767
Copy link

@wuke32767 wuke32767 commented Nov 16, 2024

This PR aims to add flag support to the dream block.
In this case, activated and deactivated dream block can appears at the same time,
which vanilla Celeste, Everest and some of mods do not support.
What did vanilla do:

  • Dream block has playerHasDreamDash for only visual.
  • The actual activation state is Session.Inventory.DreamDash which is global.
  • When it's changed (only in 2A dream mirror), activate all dream block manually.
  • In most cases, check Inventory.DreamDash and assume all dream block is activated, then happily read Tracker[DreamBlock] (mainly used in Collide method series).

To change this:

  • Add DreamBlock.Activated to represent the dream block's actual state (actually a property to read Inventory.DreamDash directly)
  • Change Player.DreamDashCheck Player.DashCoroutine Player.DreamDashUpdate to use that property.
    • Replace Collide method with ours and hope that it can work with all mods.
      • the most dangerous part.
    • Remove any Inventory.DreamDash.

What did Everest and mods do:

  • Most of custom dream block inherit from dream block so most of them should work.
    • The rest don't inherit from dream block.
    • Some use dream block dummy so can work.
    • The others reads Inventory.DreamDash so they can't get flag support automatically. (can work as before)
  • If a mod changes Inventory.DreamDash, it should work, as DreamBlock.Activated is a property that can read it.
  • If it then call DreamBlock.Activate series, it can in wrong visual state.

To change this:

  • Announce that DreamBlock.Activate series is Obsolete.
  • Make a new series that call Activate or Deactivate according to DreamBlock.Activated.
  • Require these modders to migrate.
  • DreamBlock.Activate series still works fine in old map, so we don't need to migrate them all/quickly.

Finally, we are prepared to add flag support.

  • Add DreamBlock.Flag.
  • Add flag controls to DreamBlock.Activated.
  • Make it NoInlining for hooks.
  • Notice that sometimes DreamBlock.Activated can be different from flag, so we need flagState to save current flag state. only when flagState is changed, we can try to update visuals to match state.
  • don't forget to check it every frame in Update.
  • Add ActivatedPlus for extensibility. It's designed for non-visual state.

For performance reason, add Level.HasNewDreamBlock.

  • If a dream block is flag-controlled, counter++.
  • If it's not controlled by flag, or is removed, counter--.
  • Restore removed Inventory.DreamDash. Ignore them only when there's flag dream block.

Add DreamBlockPatch to indicate if this patch has been applied.

Info

  1. It's migrated from Reverse Helper. If you have questions to any part of it,
    • it's actually what Reverse Helper did.
    • It's designed for the extensibility.
    • It's because of the compatibility.
    • This part can be improved. Thanks for your suggestion.
      feel free to ask me.
  2. As the branch name suggests, this patch does not have trackers.
    it's impossible to track if an field is changed.
    • the solution can be convert it to property somehow,
      • is it even possible?
    • or require everyone to broadcast the event.
      • this would break mod backward compatibility, and I'm not sure if it can improve performance, compared to Level.HasNewDreamBlock.

What should we do

  • Discussion
  • Checking Backward Compatibility
    Tested CelesteTAS 100%.tas
    Checked 2A Cutscene and it looks good
    wrote a test map and it looks good
  • Checking Mod Compatibility
    Tested Mod List is the same as Ja's IL Hook Viewer
    - Communal Helper - crashed
    - Reverse Helper - didn't work (apparently)
    - More Lock Block - didn't work (apparently)

Main IL Changes And Mod Compatibility

  • DreamBlock.Added
    Added new method call after Inventory.DreamDash to replace it with correct state
    should be good in 95% cases

    it's not clean tbh

  • DreamBlock.Update
    Update flag state every frame
    should be good in 99.9% cases

  • Player.DreamDashCheck
    Replace all Collides with custom one
    Remove Inventory.DreamDash conditionally

    Should be good, because nobody loves to hook it.
    More Lock Block was broken.
    Tera Helper is not broken, but they should change their hook.

  • Player.DashCoroutine
    Replace one Collides with custom one
    Remove Inventory.DreamDash conditionally

    Communalhelper was broken.

  • Player.DreamDashUpdate
    Replace one Collides with custom one

    There's no Inventory.DreamDash

    No mods was broken.

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.

1 participant