Jump to content


Photo

Repeating EFF for durations


  • Please log in to reply
11 replies to this topic

#1 temnix

temnix
  • Member
  • 983 posts

Posted 27 August 2016 - 04:38 AM

When a spell scales well, it has many Spell Abilities, and then, especially if there are many timed effects in each Ability, it can take very long to type in every effect's duration by hand. Instead I use a repeating EFF that calls on a list of 6-second effects every round. Then I can just specify in each Ability for how long I want the EFF to be applied - for 60 seconds if duration for that caster level is 10 rounds, for 66 seconds if it is 11 rounds and so on. Are there any disadvantages to this method, is it reliable?



#2 Mike1072

Mike1072
  • Modder
  • 539 posts

Posted 27 August 2016 - 05:56 AM

A better approach to save you time would be to add the effects to your spells using WeiDU code. You can easily add multiple effects with durations that are dependent on the level of the caster if you throw in some loops.


The repeating effect opcode (272) is quite unreliable in the original engine. However, it was fixed by ToBEx. The bug was reported to the EE team but I don't know if it's fixed there.

 

Current Behaviour:


Effects #78 “Disease”, #25 “Poison”, #235 “Wing Buffet”, #98 “Regeneration”, #272 “Repeating Effect”: multiple instances of these opcodes causes only the highest frequency instance to apply when using parameter 2 values of 0-3

Expected Behaviour:


Effects #78 “Disease”, #25 “Poison”, #235 “Wing Buffet”, #98 “Regeneration”, #272 “Repeating Effect”: multiple instances of these opcodes apply the instances at frequencies independently of each other when using parameter 2 values of 0-3

 

In addition to the buggy behaviour, it may be unsuitable simply because it's affected by haste and slow, which double and halve the rate effects are applied.



#3 temnix

temnix
  • Member
  • 983 posts

Posted 27 August 2016 - 07:07 AM

Okay, this is good information. I'm going to add immunity to haste and slow when it's appropriate, and I'll watch out for those values, although I use two overlapping Wing Buffets right now and they both work.


Edited by temnix, 27 August 2016 - 07:12 AM.


#4 temnix

temnix
  • Member
  • 983 posts

Posted 27 August 2016 - 01:19 PM

Mike, is it possible to patch an existing spell ability's effects, changing only durations? The repeating EFF didn't work, I will do straight durations, but there is a huge number of effects in the list even for the first one. If I could make Weidu run through that and just extend the time of everything...



#5 The Imp

The Imp

    Not good, see EVIL is better. You'll LIVE.

  • Member
  • 5150 posts

Posted 27 August 2016 - 02:10 PM

Mike, is it possible to patch an existing spell ability's effects ... ?

Yes, you just need to use the LPF ~ALTER_SPELL_EFFECT~ macro... it's already in the weidu.exe, so you don't need to define it, but here's how it's originally coded in weidu, so you can use it as a reference. It might help.


Edited by The Imp, 27 August 2016 - 02:15 PM.

Yep, Jarno Mikkola. my Mega Mod FAQ. Use of the BWS, and how to use it(scroll down that post a bit). 
OK, desert dweller, welcome to the sanity, you are free to search for the limit, it's out there, we drew it in the sand. Ouh, actually it was still snow then.. but anyways.


#6 Mike1072

Mike1072
  • Modder
  • 539 posts

Posted 27 August 2016 - 07:31 PM

Mike, is it possible to patch an existing spell ability's effects, changing only durations? The repeating EFF didn't work, I will do straight durations, but there is a huge number of effects in the list even for the first one. If I could make Weidu run through that and just extend the time of everything...
 
COPY_EXISTING ~spwi214.spl~ ~override~
  PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
    READ_LONG  0x34 spell_level
    READ_LONG  0x64 abilities_off
    READ_SHORT 0x68 num_abilities
    READ_LONG  0x6a effects_off
    FOR (i = 0; i < num_abilities; i += 1) BEGIN
      // determine caster level for this ability
      READ_SHORT (abilities_off + 0x28*i + 0x10) caster_level
      PATCH_IF (caster_level == 1) BEGIN
        SET caster_level = spell_level * 2 - 1
      END
      READ_SHORT (abilities_off + 0x28*i + 0x1e) num_features
      READ_SHORT (abilities_off + 0x28*i + 0x20) features_ind
      FOR (j = 0; j < num_features; j += 1) BEGIN
        READ_LONG (effects_off + 0x30*(features_ind + j) + 0x0e) duration
        PATCH_IF (duration == (caster_level * 10 * 6)) BEGIN // only modify effects that have a duration of 1 turn/level
          // change the duration to 2 rounds/level
          WRITE_LONG (effects_off + 0x30*(features_ind + j) + 0x0e) (caster_level * 2 * 6)
        END
      END
    END
  END
  BUT_ONLY

To clarify what's going on when caster_level == 1, here's an explanation.

For spells that scale based on caster level, they need multiple abilities with different minimum level requirements (offset 0x10 in the ability). A level 1 spell would need different abilities for each level the spell can be cast at (one for for level 1, another for level 2, etc. - all the way up to level 20). A level 2 spell would need the same, but you generally can't cast any level 2 spells until you reach caster level 3. So, you'd think it would only need an ability for level 3, level 4, etc. up to 20. However, without an ability with a minimum level of 1, the spell wouldn't work properly when cast by a creature without spellcasting levels (e.g. a monster). So, the first ability for that level 2 spell has its minimum level set to 1 instead of 3. It doesn't need abilities for minimum level 2, nor does it need a separate ability for minimum level 3 (since that is now handled by the first ability), so its next ability has a minimum level of 4.

In the above code, for each ability, the caster_level variable is set to the minimum level specified by the ability, except when the minimum level is 1; in that case it, the caster_level is instead set to the first level at which casters gain access to spells of that level. This ensures that the code can set durations based on caster level that are accurate for all of the spell's abilities, even though this second-level spell appears to have an ability for level 1 casters but not level 2 or level 3.  In reality, the spell has one ability for each caster level between 3 and 20.

Edited by Mike1072, 29 August 2016 - 07:26 PM.


#7 temnix

temnix
  • Member
  • 983 posts

Posted 28 August 2016 - 11:52 AM

I thank you very much, Mike for the effort you put in this impressive code. I don't understand it, so I can't really use it, but I appreciate it. :)



#8 Mike1072

Mike1072
  • Modder
  • 539 posts

Posted 28 August 2016 - 04:20 PM

If it works as intended (not at my computer to test right now), it should copy the Strength spell (spwi214.spl) and modify the duration of every effect that's part of an ability. There is one ability for each caster level. The effects in each ability will mostly be the same, except they will have different durations.

This code loops over each ability and determines the caster level of the ability. It then loops over all the effects associated with that ability and gives them a new duration, using the formula of 2 rounds/level.  It only modifies effects that match the spell's stated duration of 1 turn/level.


Edited by Mike1072, 29 August 2016 - 07:25 PM.


#9 Gwendolyne

Gwendolyne
  • Administrator
  • 1016 posts

Posted 29 August 2016 - 12:47 PM

Here are a few pieces of coding that work pretty well (tested and installed) :shifty:

 

 

COPY ~Diamant_Eternel/Kits/GWPA211.spl~    ~override/GWPA211.spl~
     FOR (i = 1 ; i <= 50 ; ++i) BEGIN
         LPF ALTER_SPELL_EFFECT INT_VAR header = i duration_high = (12 * i) END    // 2 rounds / level
     END
BUT_ONLY


COPY ~Diamant_Eternel/Kits/GWPA403.spl~    ~override/GWPA403.spl~
     FOR (i = 1 ; i <= 50 ; ++i) BEGIN
         LPF ALTER_SPELL_EFFECT INT_VAR header = i duration_high = (60 + 6 * i) END    // 1 turn + 1 round / level
     END
BUT_ONLY


COPY_EXISTING ~GWPtnMGp.spl~    ~override/GWLicPMG.spl~
     LPF ALTER_SPELL_EFFECT INT_VAR duration_high = 126 END   // flat duration = 126 
BUT_ONLY

Edited by Gwendolyne, 29 August 2016 - 12:49 PM.

CARPE DIEM ....
 

In progress : Menace sur le Royaume de Diamant Éternel there.


#10 temnix

temnix
  • Member
  • 983 posts

Posted 29 August 2016 - 02:56 PM

Ah well, back to monkey work.



#11 Mike1072

Mike1072
  • Modder
  • 539 posts

Posted 29 August 2016 - 07:53 PM

I can't tell if you've figured out how to do what you want or not.
 
I tested my code and made some adjustments.  It's now modifying the Strength spell and it makes sure to only alter effects whose durations match what is expected (so it avoids erroneously changing things that are supposed to have a static duration).

Here are screenshots from Near Infinity looking at the original and changed versions of the spell (before and after the code was run). There are comparisons for both the first ability and the last ability. http://imgur.com/a/m5zkn

#12 temnix

temnix
  • Member
  • 983 posts

Posted 30 August 2016 - 07:10 AM

I'm sure those who are more experienced with Weidu code will find them very helpful.