Modding Help Status effect (minor Lua help needed)

Discussion in 'Starbound Modding' started by Viikoreaux, Oct 1, 2019.

  1. Viikoreaux

    Viikoreaux Space Spelunker

    I'm looking to prevent refreshing of a status effect timer.

    Here's what I have so far:

    A bleeding effect that behaves like reverse lava, dealing the most damage at the start and decreasing damage each tick. The only issue is that reapplying the effect only extends the timer. So, as each tick multiplies the previous tick's damage by 0.75, it works correctly up until about the 16th tick, where the number becomes about 1% of the original tick. Each tick afterwards becomes only more and more miniscule, and it's impossible to restart the effect without breaking damage and waiting for the entire timer to wear out.

    I initially thought to solve the problem by causing the damage to be reapplied when the timer was refresh. I have successfully done this, but since the first tick is about 10% of target's health, it's quite overpowered. The only way to fix this issue is to reduce the damage so that I might as well have simply used already existing bleed effects.

    Here is the code for that version (my latest):

    Lua: https://pastebin.com/pSYbA9Dc

    JSON: https://pastebin.com/zyqJp5Hq

    So, I am now trying to keep the timer from resetting when the effect is reapplied. I know this must be done either by disabling the ability for the timer to refresh, or by immunizing the target to the effect while the effect is present. I'm not sure which would work best or how to do either. In this way, the effect timer will not be extended despite repeated strikes, and the effect will be free to restart once the duration has ended.
     
  2. Zaakari

    Zaakari Sandwich Man

    So what you are looking for is this?
    Code:
    Player slashes enemy -> enemy bleeds for 10 damage.
                         -> enemy bleeds for 7.5 damage.
    Player slashes enemy -> enemy bleeds for 5.625 damage.
                         -> enemy bleeds for 4.22 damage.
    etc.
    And not this?
    Code:
    Player slashes enemy -> enemy bleeds for 10 damage.
                         -> enemy bleeds for 7.5 damage.
    Player slashes enemy -> enemy bleeds for 10 damage.
                         -> enemy bleeds for 7.5 damage.
    etc.
    Also, are you sure the effect's init function is not getting called on successive applications?
    If you wrote the init function like the following, would nothing change?
    (I'm not trying to be annoying or rude, I'm just curious.)
    Code:
    function init()
      animator.setParticleEmitterOffsetRegion("healing", mcontroller.boundBox())
      animator.setParticleEmitterEmissionRate("healing", config.getParameter("emissionRate", 3))
      animator.setParticleEmitterActive("healing", true)
      script.setUpdateDelta(5)
    
      if not self.tickTime then -- If tickTime has not been set yet
        self.tickDamagePercentage = 0.1 + config.getParameter("bleedAmount", 0)
        self.tickTime = 0.5
        self.tickTimer = self.tickTime
        self.damage = math.floor(status.resourceMax("health") * self.tickDamagePercentage) + 1
      else
        self.tickDamagePercentage = 100
        self.tickTime = 0.1
      end
      effect.duration()
    end
     
  3. Viikoreaux

    Viikoreaux Space Spelunker

    Having any tick deal "100" tickDamagePercentage would be an instakill. The tickDamagePercentage is a percentage of target HP.

    What I'm basically looking for is this:

    Code:
    Player slashes enemy -> enemy bleeds for 10 damage.
    Player discontinues attacks, and bleeding continues for 5.625, 4.219, 3.164, etc. until effect expires.
    Additionally,

    Code:
    Player slashes enemy -> enemy bleeds for 10 damage. Tick timer = 6
                         -> enemy bleeds for 7.5 damage. Tick timer = 5
    Player slashes enemy -> enemy bleeds for 5.625 damage. Tick timer = 4
                         -> enemy bleeds for 4.22 damage. Tick timer = 3
    layer slashes enemy -> enemy bleeds for 3.16 damage. Tick timer = 2
                         -> enemy bleeds for 2.37 damage. Tick timer = 1
    Player slashes enemy -> enemy bleeds for 1.78 damage. Timer expires.
    Player slashes enemy -> enemy bleeds for 10 damage. Timer restarts = 6
                         -> enemy bleeds for 7.5 damage. Tick timer = 5
    Player slashes enemy -> enemy bleeds for 5.625 damage. Tick timer = 4
                         -> enemy bleeds for 4.22 damage. Tick timer = 3, etc.
    Previously, it was such that the timer would behave like so:
    Code:
    Player slashes enemy -> enemy bleeds for 10 damage. Tick timer = 6
                         -> enemy bleeds for 7.5 damage. Tick timer = 5
    Player slashes enemy -> enemy bleeds for 5.625 damage. Tick timer = 6
                         -> enemy bleeds for 4.22 damage. Tick timer = 5
    layer slashes enemy -> enemy bleeds for 3.16 damage. Tick timer = 6
                         -> enemy bleeds for 2.37 damage. Tick timer = 5
    Player slashes enemy -> enemy bleeds for 1.78 damage. Tick timer = 6
                         -> enemy bleeds for 1.33 damage. Tick timer = 5
    Player slashes enemy -> enemy bleeds for 1.0 damage. Tick timer  = 6
                         -> enemy bleeds for 0.75 damage. Tick timer = 5
    Player slashes enemy -> enemy bleeds for 0.56 damage. Tick timer = 6
                         -> enemy bleeds for 0.42 damage. Tick timer = 6, etc.
    As such, the timer lasts as long as the player is applying the effect, but the effect never restarts. So, I came up with the above solution, where the effect fully restarts on each application, which is pretty overpowered when fighting higher HP opponents. For example, the attack may deal 5 damage against a punchy, but the bleed deals over 2k each time it is reapplied. Against bosses, you can see where this would be a problem. So, I'm looking for a way to prevent the effect from being reapplied until its duration has expired. In this way, the effect can be refreshed without being overpowered.
     
  4. Zaakari

    Zaakari Sandwich Man

    Yeah, that was just meant to be a noticeable way to test whether or not the init function could detect whether or not it had been called before. Turns out it cannot.

    Nevertheless, I believe I figured out how to do what you are wanting.
    I've attached a zip folder that contains an unpacked mod for demonstration (and it's what I was using to test my work).
    Just spawn the item "testblade" if you care to see how it functions.

    What I ended up doing was making two more status effects, and altering your original one.

    The status effect that the testblade applies is the "puncture_bleed_start". This one checks the status controller's persistent status effects' "bleeding" group for the effect "puncture_bleed_gate", if that is not present, then it adds it as a persistent status effect, as well as the effect "puncture_bleed" (the modified original) as an ephemeral effect (so that it has a duration, and will time out). Once the "puncture_bleed" effect times out, it removes the "bleeding" persistent effect group, which contains the "puncture_bleed_gate" effect, thereby allowing the "puncture_bleed_start" effect to reapply the "puncture_bleed" effect.

    Sounds complicated? I agree. Perhaps a diagram will help:
    Code:
    Player slashes enemy
      -> start effect applied
        -> start effect checks for gate effect
          -> if gate found
                -> do nothing
             else
                -> apply gate and bleed effects
    
    Bleed effect
      -> deals decreasing damage
      -> times out
        -> removes gate effect
    
    Gate effect
      -> does nothing (acts only as a flag)
    
    Please note:
    I commented out the animator sections in the "puncture_bleed" lua file only because I didn't code or copy an animation for the effect, so you can uncomment those lines.
    Also, I added some "sb.logInfo" commands in the "puncture_bleed" and "puncture_bleed_start" lua files, simply so that I could see what was going on. You can comment them out or remove them if you would like.
    Finally, the three ".statuseffect" files probably contain some code that they don't need (since I was just copying and editing the one you made) so feel free to clean those up as you see fit.

    P.S.
    I just remembered that I also modified the duration of the "puncture_bleed" effect to 5 seconds (easier to test), so you may want to change that back to 10.
     

    Attached Files:

Share This Page