elanthia-online / illthorn

Electron-based FE
18 stars 10 forks source link

Cooldown Timers #129

Closed BryanSchuetz closed 3 years ago

BryanSchuetz commented 3 years ago

I was adding a cool-down timer to spell-list.xml in Lich—to keep track of the cooldown for my new mech crossbow:

<spell availability='self-cast' name='Crossbow Cooldown' number='9078' type='timer'>
      <duration>30</duration>
      <message type='start'>As the last shot fires, the gears clunk to a stop with a small whine\.</message>
</spell>

...and was thinking, it would be sweet if we could visualize these cooldowns like we do with active spells. Basically, another panel that lists the cooldowns and their durations. There's already a lot of cooldown definitions in spells.json because I seeded that list from the spells-list.xml when I started it.

I'm sure this is a non-trivial feature to add—and I get that this would make Lich even more of a dependency, and that alone may be more than enough reason not to do it...but, it would be cool nevertheless. I would assume it's technically possible—but I don't really have any idea of how electron is sharing info with/through Lich.

Anyway, just thought I'd mention it.

ondreian commented 3 years ago

This can be done in Lich via a DownstreamHook

BryanSchuetz commented 3 years ago

I'm not sure what you mean...

BryanSchuetz commented 3 years ago

I do see other timers from spell-list.xml there:

Screen Shot 2020-08-25 at 4 26 38 AM

But for some reason the timer I setup above never makes it. I do see it in ;magic and ;inactivespells along with other timers, and I can see it with Spell['9078'].active. I guess I'm just missing something...

ondreian commented 3 years ago

So, those other spells are present on the <dialogdata> element in the stream, someone would need to use a DownstreamHook to modify the stream on the fly and add the things that Lich knows about that are missing from the xml element.

BryanSchuetz commented 3 years ago

I think I get it? So I'd just add and remove based on the spell being active. Not totally sure what dialogData looks like, do I have to keep updating to refresh the timer? or given a starting value will that just "happen"

ondreian commented 3 years ago

I'll try to write a basic demo sometime this weekend, but basically you need a lich script that modifies the <dialogData> element for active spells to add whatever cooldown you want, then the FE can just transparently support it.

BryanSchuetz commented 3 years ago

That would be awesome! Thanks. I did take a look at some downstreamHook examples in lich—but wasn't sure if I needed to update the timer continuously, or jus set the duration or what. Also wasn't sure what dialogData looked like in the XML. If you can write a demo I could add a bunch of the other timers present in spells.json.

BryanSchuetz commented 3 years ago

Hey! Still wishing I could have custom cool-down timers show up in the active spells panel. Any chance you could demo how this would work? I asked around on Discord and didn't find much help there.

ondreian commented 3 years ago

Oh yes, ping me on Discord and we can have a quicker conversation there maybe Ondreian#3875

On Wed, Oct 28, 2020 at 1:41 PM Bryan Schuetz notifications@github.com wrote:

Hey! Still wishing I could have custom cool-down timers show up in the active spells panel. Any chance you could demo how this would work? I asked around on Discord and didn't find much help there.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/elanthia-online/illthorn/issues/129#issuecomment-718165908, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIKHAU7A6XV3QFHBIQXGDTSNBXXPANCNFSM4QJ4DUVA .

ondreian commented 3 years ago

custom-spell-example

This is an example lich script to do this:

=begin
  # this is what the game feed object that triggers spells in the HUD looks like
  <dialogData id='ActiveSpells' clear='t'></dialogData>
  <dialogData id='ActiveSpells'>
        <progressBar id="Spirit Warding I" value='89' text="Spirit Warding I" left='22%' top='5' width='75%' height='15'/>
        <label id="lblSpirit Warding I" value=' 3:43 ' top='5' left='0' justify='4' anchor_right="Spirit Warding I"/>
        <progressBar id="Spirit Defense" value='25' text="Spirit Defense" left='22%' top='21' width='75%' height='15'/>
        <label id="lblSpirit Defense" value=' 1:03 ' top='21' left='0' justify='4' anchor_right="Spirit Defense"/>
        <progressBar id="Spirit Warding II" value='89' text="Spirit Warding II" left='22%' top='37' width='75%' height='15'/>
        <label id="lblSpirit Warding II" value=' 3:43 ' top='37' left='0' justify='4' anchor_right="Spirit Warding II"/>
        <progressBar id="Spirit Shield" value='24' text="Spirit Shield" left='22%' top='53' width='75%' height='15'/>
        <label id="lblSpirit Shield" value=' 1:00 ' top='53' left='0' justify='4' anchor_right="Spirit Shield"/>
        <progressBar id="Elemental Defense I" value='89' text="Elemental Defense I" left='22%' top='69' width='75%' height='15'/>
        <label id="lblElemental Defense I" value=' 3:43 ' top='69' left='0' justify='4' anchor_right="Elemental Defense I"/>
        <progressBar id="Lock Pick Enhancement" value='0' text="Lock Pick Enhancement" left='22%' top='85' width='75%' height='15'/>
        <label id="lblLock Pick Enhancement" value=' 0:00 ' top='85' left='0' justify='4' anchor_right="Lock Pick Enhancement"/>
        <progressBar id="Elemental Defense II" value='89' text="Elemental Defense II" left='22%' top='101' width='75%' height='15'/>
        <label id="lblElemental Defense II" value=' 3:43 ' top='101' left='0' justify='4' anchor_right="Elemental Defense II"/>
        <progressBar id="Elemental Defense III" value='89' text="Elemental Defense III" left='22%' top='117' width='75%' height='15'/>
        <label id="lblElemental Defense III" value=' 3:43 ' top='117' left='0' justify='4' anchor_right="Elemental Defense III"/>
        <progressBar id="Thurfel's Ward" value='89' text="Thurfel's Ward" left='22%' top='133' width='75%' height='15'/>
        <label id="lblThurfel's Ward" value=' 3:43 ' top='133' left='0' justify='4' anchor_right="Thurfel's Ward"/>
        <progressBar id="Strength" value='89' text="Strength" left='22%' top='149' width='75%' height='15'/>
        <label id="lblStrength" value=' 3:43 ' top='149' left='0' justify='4' anchor_right="Strength"/>
        <progressBar id="Mass Blur" value='31' text="Mass Blur" left='22%' top='165' width='75%' height='15'/>
        <label id="lblMass Blur" value=' 1:18 ' top='165' left='0' justify='4' anchor_right="Mass Blur"/>
  </dialogData>
=end

module CustomSpells
  # we are going to insert our custom spells before the close of the dialogData object
  CLOSE_DIALOG_DATA = %[</dialogData>]
  # helper to create a <label>, in SF the top/left/justify stuff is important, but Illthorn doesn't care
  def self.label(name, value)
    %[<label id="lbl#{name}" value=' #{value} ' top='165' left='0' justify='4' anchor_right="#{name}"/>]
  end
  # the function that does the work
  def self.add_custom_spells(incoming)
    incoming.gsub(CLOSE_DIALOG_DATA) {
      label("Example - Custom Spell", "2:00") + CLOSE_DIALOG_DATA
    }
  end
  # attach our DownstreamHook and modifier to the stream
  def self.attach()
    DownstreamHook.add(self.name, -> ss {
      begin
        return ss unless ss.include?(CLOSE_DIALOG_DATA)
        return add_custom_spells(ss)
      rescue => exception
        respond exception
        return ss
      end
    })

    before_dying {DownstreamHook.remove(self.name)}
    sleep
  end

  attach()
end

I would probably add some API, that other scripts can use like CustomSpells.add(label, duration) and then it keeps track of the active ones and writes them to the game feed as necessary.