Jump to content

ADD_CRE_EFFECT - Visual Effects


JediMindTrix

Recommended Posts

...were written by CamDawg, I believe, and added to Weidu about a year ago.

There's no need to believe, here's the whole documentation and yeah, they were added to the weidu.exe after last year.

I'll say that you probably would get lost during the programation phase of that if you look at the code a lots. 6 years before that, I strucked with maiking a portion of that and well, there was a reason why the iiSpellSystemAdjustment mod v5 was producing erronious content. ( The amount of code needed exceeded my failure detection cababilities. )

 

So it's a good thing that you have that code to rely on... still, I'll use my original code.

Link to comment

Yeah, really nothing against the old functions, they were amazingly useful in their time. It's just, things keep getting better, which is great.

 

(And not for nothing, the guy who wrote these functions now works for Beamdog, and afaik they are using this stuff in developing their new patches and games.)

Link to comment

ADD_SPELL_EFFECT and DELETE_SPELL_EFFECT are old, but they work fine and do exactly what they say.

 

Hrm, because I read somewhere that ADD_SPELL_EFFECT required all fields to be filled in order for it to function.

You don't need to specify every field if you are calling these as a function (LAUNCH_PATCH_FUNCTION), because it will use the default values (listed in the documentation) for anything that's not specified. These commands were originally available as macros (before functions were added to WeiDU), so you may have come across some old information.

 

How do I find the extended header of a spell effect using near infinity?

 

Specifically this part:

ADD_SPELL_EFFECT: adds an extended effect to a spell. All variables except probability1 and insert_point are 0 by default. This is a PATCH macro and function.

SET header to number of extended header (starting from 1) the effect should be added to (by default the effect is added to every header).

 

If you only want to add the effect to a specific header (and not any of the others), then you specify this value. Otherwise, just ignore it and "by default the effect is added to every header".

 

By looking at the screenshot of DEMOCHM.SPL, the file only has 1 extended header (NearInfinity calls it an ability), so you can leave that field out.

Link to comment

Is there a mod or tool that will convert an old mod's tp2 (and any other involved files like tpa,tpp) to a current weidu version? I know the actual exe will get auto-updated.

Meaning ?

All the old .tp2 actions still work in the newer weidu versions, that's why the program gets bigger from each update ! Well, ok all might not, but 99% should ... the 1% being the ones that were removed for no one was using them, or they just caused destruction, and you have to adapt to the newer functions.

 

Meaning: There's no need.

Link to comment

ADD_SPELL_EFFECT and DELETE_SPELL_EFFECT are old, but they work fine and do exactly what they say.

 

You don't need to specify every field if you are calling these as a function (LAUNCH_PATCH_FUNCTION), because it will use the default values

No disrespect intended! :) That was just my flip way of pointing him to another function with which I am more familiar.

 

Good to know that ADD_SPELL_EFFECT uses the default values the same way, though. Filed away for future use.

Link to comment

Been reading up on the CLONE/DELETE/ALTER_EFFECTS, and I believe it would benefit my understanding of how these functions and extensions (.spl, .itm, .eff) if someone could point me to a tutorial that explains how Extended Headers, Feature Blocks, Casting Feature Blocks, etc, all work. IESDP was a little difficult to search through.

Link to comment

Been reading up on the CLONE/DELETE/ALTER_EFFECTS, and I believe it would benefit my understanding of how these functions and extensions (.spl, .itm, .eff) if someone could point me to a tutorial that explains how Extended Headers, Feature Blocks, Casting Feature Blocks, etc, all work. IESDP was a little difficult to search through.

Well, it's actually said in the IESDP, you can read the Detailed Description for ITM and SPL files, for example if you just open the .SPL page, you can also see separation in this picture of a .SPL file

spl.gif

The explanation consists of the main Header(red), Extended Header(blue), the Feature Blocks(green, this one presumably has 2), and last Casting Feature Block if there is one which is not in the chart, the amount and lenght of those blocks are set in the Headers offsets 0x0064 - 0x0072, the file is always at least 0x0074 bits long, so the next is the feature block and so on.

 

As a .tp2 code, you need to know that the header offsets are the first offsets the file has, so it's a + zero to the sum, the first extended headers offsets have a + 0x0072 to the sum, and the next have a +0x0028 added to the previous until you run out of the extended headers(the amount of which of course is read and used in the function is located in the files offset 0x0068 ).

And the Feature blocks are after those...

So the .tp2 code reflects this structure, so using the old style functions for example you can use read's, patch_if's and loop's just to get started:

    COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ ~override~
    PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN 						// protects against invalid files
      READ_SHORT 0x1c "spl_type"
      READ_LONG  0x34 ~spell_level~
      READ_LONG  0x64 "abil_off"
      READ_SHORT 0x68 "abil_num"
      READ_LONG  0x6a "fx_off"
      READ_SHORT 0x70 "fx_num"
          SET ~loops~ = 0
          SET ~delta~ = 0
          WHILE (~loops~ < ~abil_num~) BEGIN
            READ_SHORT (abil_off + 0x1e + (0x28 * loops)) ~abil_fx_num~
            READ_SHORT (abil_off + 0x20 + (0x28 * loops)) ~abil_fx_idx~
            SET ~abil_fx_idx~ = (abil_fx_idx + delta)
            WRITE_SHORT (~abil_off~ + 0x20 + (0x28 * loops)) ~abil_fx_idx~

And then use those as the consistents, like in this, where we add an effect using opcode 261 that restores the spell after casting when the timers that were previously determined ends:

           INSERT_BYTES  (~fx_off~ +        ((~abil_fx_idx~) * 0x30)) 0x30		// New effect
              WRITE_SHORT (~fx_off~ +        ((~abil_fx_idx~) * 0x30)) 261		// Restore Lost Spell
              WRITE_BYTE (~fx_off~ + 0x02 + ((~abil_fx_idx~) * 0x30)) 1			// Target Self
              WRITE_LONG (~fx_off~ + 0x04 + ((~abil_fx_idx~) * 0x30)) ~spell_level~	// Parameter 1 (Restored Spell Level)
              WRITE_BYTE (~fx_off~ + 0x08 + ((~abil_fx_idx~) * 0x30)) 0 		// Parameter 2 (Wizard / Bard)
              WRITE_BYTE (~fx_off~ + 0x0c + ((~abil_fx_idx~) * 0x30)) 4			// Delayed
              PATCH_IF (~spell_level~ = 1) BEGIN
                WRITE_LONG (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer1 + 6) 	// User-defined values
              END
              PATCH_IF (~spell_level~ = 2) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer2 + 6)	// User-defined values
              END
              PATCH_IF (~spell_level~ = 3) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer3 + 6)	// User-defined values
              END
              PATCH_IF (~spell_level~ = 4) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer4 + 6)	// User-defined values
              END
              PATCH_IF (~spell_level~ = 5) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer5 + 6)	// User-defined values
              END
              PATCH_IF (~spell_level~ = 6) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer6 + 6)	// User-defined values
              END
              PATCH_IF (~spell_level~ = 7) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer7 + 6)	// User-defined values
              END
              PATCH_IF (~spell_level~ = 8) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer8 + 6)	// User-defined values
              END
              PATCH_IF (~spell_level~ = 9 OR ~spell_level~ = 10) BEGIN
                WRITE_LONG  (~fx_off~ + 0x0e + ((~abil_fx_idx~) * 0x30)) (timer9 + 6)	// User-defined values
              END
              WRITE_BYTE (fx_off + 0x12 + ((abil_fx_idx) * 0x30)) 100			// Probability
              WRITE_BYTE (fx_off + 0x0d + ((abil_fx_idx) * 0x30)) 3			// Dispel/Bypass
            SET ~delta1~ = 1
            SET ~delta~ = (delta + delta1)
            WRITE_SHORT (abil_off + 0x1e + (0x28 * loops)) (abil_fx_num + delta1)
            SET ~loops~ = (loops + 1)
          END
        END
      END

I used an old function here from the iiSpellSystemAdjustment mod, so I can't exactly say that it's air tight, but you should get the picture of what you are dealing with ...

 

Code which could easily be replaced with muh shorter:

COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ ~override~
    PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN 						// protects against invalid files
READ_ ...
LPF ADD_SPELL_EFFECT INT_VAR opcode = 261 ... END
Link to comment

I saw that in the IESDP. I'm looking for explanations on what an Extended Header and Feature Block's are. The IESDP basically just said 'Extended Headers have offsets that go into Feature Blocks'. Okay, cool, that still doesn't tell me what these are, just vaguely how they interact. Its not detailed at all. I know very little about hex, and for layman, being told that and being expected to connect the dots just leaves me with a pain in my forehead.

 

 

 

so it's a + zero to the sum

This doesn't make sense to me either. + 0 to a sum does absolutely nothing to that sum, because you're adding nothing to something.

Link to comment

OK, the extended header in a SPL file is what happens when a caster of the determined level casts the spell, in BG2:ToB game you have the spwi304.spl, it has 6 extended headers, 1 per each level from 5 to 10, they each contain at least 2 effects that cause different kinds of damage(as you can't make a save throw from the other kind), aka they each have at leasr 2 feature blocks(they can have more for other functions).

 

 

so it's a + zero to the sum

This doesn't make sense to me either. + 0 to a sum does absolutely nothing to that sum, because you're adding nothing to something.

 

That's an example of how to determine the offsets start.

Say you wish to know what the .spl file's second extended headers has at the offset 0x0000, it's not the spells offset zero, but the offset after the header(lenght of which is 0x072 bits) and the first extended header(lenght of which is 0x0028 bits) aka you are looking for the bit at offset 0x72+0x28, which is 0x9a or 154. But then, for what réver reason you wish to know what the headers has at offset 0x0000, then you are looking at files the offset zero.

Link to comment

The biggest confusion probably comes from the different names that these things are given in various areas.

The actual layout is pretty simple, and it's shared by both items and spells. I made a nice diagram to illustrate how everything relates to each other.

sLIobYM.png

Each item or spell contains exactly one header, but it may contain any number of abilities and effects. In ITM files, a single ability is 0x38 bytes long and an effect is 0x30 bytes long. In SPL files, a single ability is 0x28 bytes long and an effect is 0x30 bytes long.

Every item/spell may have 0 or more global effects (a.k.a. equipping features/casting features). These can be found by reading from offsets 0x6a, 0x6e, and 0x70 in the header.

Every item/spell may also have 0 or more abilities (a.k.a. extended headers). These can be found by reading from offsets 0x64 and 0x68 in the header. Now, each one of these abilities may also have 0 or more effects, which may be referred to as features or feature blocks. These can be found by reading from the relative offsets 0x1e and 0x20 in the associated ability.


In the above example, the item has 2 global effects and 3 abilities. The first ability has 1 effect, the second ability has 3 effects, and the third ability has 1 effect.


Now, what do these different things do?

For an item, the global effects are applied when the item is equipped. You put stuff like AC bonuses here. The abilities are used to define the ranged, melee, and spell attacks the item has. The features associated with an item ability are applied when that attack hits.

For a spell, the global effects are applied whenever the spell is cast. If a spell has multiple abilities, it's because the spell behaves differently at different levels. When a spell is cast, the ability with the highest minimum level requirement (0x10) that's below the level of the caster will be activated and the associated features will be applied. The other abilities will be ignored.


If you'd like to see how you can iterate through global effects, abilities, and features using WeiDU, I recently posted some code that does that. It can be found here.

Link to comment

Thank you Mike, that visual aid helped me a lot, as did Jarno's explanation of what he meant by +0 to the sum.

 

Last question, I think, for a while:

I need to remove all flags from a single .spl. I think I can use WRITE_SHORT 0x18 0 to do so, since without any bits/bytes set, 0 is what it should add up too.

My question is if I had to set flag 11 and flag 8 (the numbers are what they are called in NI, since these flags are presented as a byte/bit table in the IESDP I suspect they are identified differently.), what would I input in place of 0 in the code I wrote above? Is this another case of adding bytes and bits?

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...