Jump to content


Photo

That 326 effect, Apply Effects List


  • Please log in to reply
26 replies to this topic

#1 temnix

temnix
  • Member
  • 983 posts

Posted 18 February 2018 - 07:34 PM

Is it good for anything at all? I've stopped using it completely because it is so broken. But now, when I was hoping it would serve as a spell-state-based filter for another spell, it doesn't recognize it. My Heat Metal and Chill Metal negate each other; they set spell state to custom values. I've done this sort of thing before and scripts see spell states chosen this way. But this time I had to do it through effects: Heat Metal was supposed to include A.E.L. on top, oriented at CHILL_METAL and sending through a spell to undo the chilling. And vice versa. Well, it's not happening. Does anybody know another way to filter a spell by spell state on the target? I could just make the spells remove each others' effects, it's true, but they need to negate each other exactly - that is, not do anything else above this. And that involves recognition of the state of the target before self-blocking.


Edited by temnix, 18 February 2018 - 07:39 PM.


#2 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 19 February 2018 - 09:03 AM

iwdee uses this opcode extensively. Do you mean all those spells are buggy?


Avenger

#3 subtledoctor

subtledoctor
  • Modder
  • 656 posts

Posted 19 February 2018 - 02:04 PM

My $20 is on "using an inoperable spellstate above 255."



#4 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 19 February 2018 - 02:25 PM

This works fine - casting level 1 Pro Evil onto Blessed target autocasts Pro Evil 10'.

 

 

 

//////////////////////////////////////////////////////////////////////////////////////


DEFINE_ACTION_FUNCTION ds_resolve_stat INT_VAR ids=2 index=0 delete=0 RET stat_ind BEGIN


OUTER_SPRINT ids_file stats OUTER_SET min_new=401


ACTION_IF ids=0 BEGIN OUTER_SPRINT ids_file extstate OUTER_SET min_new=0 END
ACTION_IF ids=1 BEGIN OUTER_SPRINT ids_file splstate OUTER_SET min_new=0 END


COPY_EXISTING ~%ids_file%.ids~ override
  stat_ind=0
  found=0


  READ_2DA_ENTRIES_NOW stats 2
  FOR (row=0;row<stats;row+=1) BEGIN
    READ_2DA_ENTRY_FORMER stats row 0 ind
    READ_2DA_ENTRY_FORMER stats row 1 str
    SET $stat("%row%") = ind
    PATCH_IF index BEGIN
      PATCH_IF ind=index BEGIN
        REMOVE_2DA_ROW row 2
        found=1
        PATCH_IF delete=0 BEGIN
          INSERT_2DA_ROW row 2 ~%index% %id%~
        END
        row=stats
      END
    END ELSE BEGIN
      PATCH_IF ~%str%~ STRING_EQUAL_CASE ~%id%~ BEGIN
        stat_ind=ind
        found=1
     /* row=stats */ // don't stop looking, the same ID may be assigned to a greater index, which takes priority when compiling
      END
    END
  END


  PATCH_IF found=0 BEGIN
    stat_ind=min_new
    PHP_EACH stat AS row => ind BEGIN
      PATCH_IF found=0 && (row+1 < stats) BEGIN // not at the end of file
        next_row = row+1
        next_ind = EVAL $stat("%next_row%")
        PATCH_IF index BEGIN
          PATCH_IF index<next_ind && index>ind BEGIN
            INSERT_2DA_ROW next_row 2 ~%index% %id%~
            found=1
          END
        END ELSE BEGIN
          PATCH_IF stat_ind<next_ind BEGIN
            PATCH_IF ind<stat_ind BEGIN
              INSERT_2DA_ROW next_row 2 ~%stat_ind% %id%~
              found=1
            END ELSE BEGIN
              stat_ind+=1
              PATCH_IF stat_ind<next_ind BEGIN
                INSERT_2DA_ROW next_row 2 ~%stat_ind% %id%~
                found=1
              END
            END
          END
        END
      END ELSE BEGIN // at the end of file
        PATCH_IF found=0 BEGIN
          PATCH_IF index BEGIN
            INSERT_2DA_ROW stats 2 ~%index% %id%~
          END ELSE BEGIN
            PATCH_IF stat_ind>ind BEGIN
              INSERT_2DA_ROW stats 2 ~%stat_ind% %id%~
            END ELSE BEGIN
              stat_ind+=1
              INSERT_2DA_ROW stats 2 ~%stat_ind% %id%~
            END
          END
        END
      END
    END // PHP_EACH
  END


END




LAF ds_resolve_stat INT_VAR ids=1 STR_VAR id=AG_BLESS RET bless_state=stat_ind END


COPY_EXISTING sppr101.spl override
  LPF ADD_SPELL_EFFECT INT_VAR opcode=328 target=2 duration=36 parameter2=bless_state special=1 END


COPY_EXISTING sppr107.spl override
  LPF ADD_SPELL_EFFECT INT_VAR opcode=326 target=2 timing=1 parameter1=bless_state parameter2=110 STR_VAR resource=sppr408 special=1 END

 


Retired from modding.


#5 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 19 February 2018 - 02:33 PM

My $20 is on "using an inoperable spellstate above 255."

Seems you're right. Forcing new state to 300 resulted in failure.


Retired from modding.


#6 temnix

temnix
  • Member
  • 983 posts

Posted 19 February 2018 - 07:21 PM

Yes, it was a high spell state. I am now using a switch of SPECIFIC instead, and a value below the maximum there - 250. That's not being seen, though. What is the maximum for SPECIFIC? Is there anything unusual about it?



#7 subtledoctor

subtledoctor
  • Modder
  • 656 posts

Posted 19 February 2018 - 08:39 PM

SPECIFIC values are used by any number of games and mods, and will cause problems if you duplicate one already in use.  And cannot exceed some maximum number, probably 255.  Maybe 127?

 

In other words, exactly the same as spellstates.  Except actually much worse: a character can have multiple spellstates simultaneously, but can only have one SPECIFIC value, so if you change it via your mod you will likely screw up some existing process.

 

In either case, the answer is to simply run an algorithm to check for the next available (spellstate/specific) and put it in a variable, and then use that variable to plug the value into your spells or items or whatever.  The particular value might be different for every player depending on their setup, but it will work regardless.  Why again is that perfectly viable solution is not acceptable?


Edited by subtledoctor, 19 February 2018 - 08:40 PM.


#8 The Imp

The Imp

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

  • Member
  • 5150 posts

Posted 19 February 2018 - 10:16 PM

..

In either case, the answer is to simply run an algorithm to check for the next available (spellstate/specific) and put it in a variable, and then use that variable to plug the value into your spells or items or whatever.  The particular value might be different for every player depending on their setup, but it will work regardless.  Why again is that perfectly viable solution is not acceptable?

This might help more, if you gave a live example of your code. Anyone ?


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.


#9 Creepin

Creepin
  • Administrator
  • 1676 posts

Posted 20 February 2018 - 12:22 AM

SPECIFIC values are used by any number of games and mods, and will cause problems if you duplicate one already in use.

I have asked many years ago what mods, if any, actually uses SPECIFICS, but got no response. I also has never seen any bugreport pertaining to two mods clashes about SPECIFICS of a certain creature. If you could share any data to prove the contrary I would be grateful because I am considering to use it as well.


Edited by Creepin, 20 February 2018 - 01:46 AM.

The Old Gold - v0.2 WIP (mod for BGT/BWP/BWS)


#10 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 20 February 2018 - 03:47 AM

SoD's AI system relies on specifics to distinguish friendly and hostile factions and subgroups within them (see InMyGroup() trigger). Feel free to throw rotten eggs and tomatoes at me for usurping that field :P

 

In any case, specifics is a scripting function. You may be able to re-purpose it for spell needs, but it doesn't change the fact you're doing something forbidden.


Edited by GeN1e, 20 February 2018 - 03:50 AM.

Retired from modding.


#11 temnix

temnix
  • Member
  • 983 posts

Posted 20 February 2018 - 03:57 AM

Taking someone's pants off is forbidden, the minister said. And subtledoctor is stuck in his loop. So nobody knows what the upper limit of SPECIFIC is? The value I picked under 250 probably works, I haven't tested yet. The files just weren't set up to point to the right line. Still, I'd rather go with a value more definitely not used by anyone.



#12 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 20 February 2018 - 05:38 AM

If you checked the IESDP, you'd see this in CRE file structure:

0x0274 1 (byte) Specific (SPECIFIC.IDS) 0x0275 1 (byte) Gender (GENDER.IDS). Dictates the casting voice, and checked for the summoning cap.

i.e. one byte aka 255 only.
 

Taking someone's pants off is forbidden, the minister said

It's irrelevant what value you use, as long as the actor has been assigned one. The mere fact of changing it will already remove them from their faction group.

 

But by all means, it's not my foot that you're pointing the shotgun at ;)


Edited by GeN1e, 20 February 2018 - 05:42 AM.

Retired from modding.


#13 The Imp

The Imp

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

  • Member
  • 5150 posts

Posted 20 February 2018 - 06:14 AM

SPECIFIC values are used by any number of games and mods, and will cause problems if you duplicate one already in use.

I have asked many years ago what mods, if any, actually uses SPECIFICS, but got no response. I also has never seen any bugreport pertaining to two mods clashes about SPECIFICS of a certain creature. If you could share any data to prove the contrary I would be grateful because I am considering to use it as well.

And I believe I have answered this a few times already, the kit mods that change not only the kit, but some that change the player chars class. Example, Switch Bard. Well, at least it did, at some point. Not that it had things to do with the opcode 326, as it didn't exist at the time.

And by the by, the specific ids is only 1 byte long, so you can't actually use it for multiple things as you can't realistically check it via bit vise and update. As you would need a script option for each and you could still only record 7 binary values.


Edited by The Imp, 20 February 2018 - 06:16 AM.

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.


#14 subtledoctor

subtledoctor
  • Modder
  • 656 posts

Posted 20 February 2018 - 07:54 AM

And subtledoctor is stuck in his loop.
A.k.a. you just don't have enough comprehension to understand the point? :P
So nobody knows what the upper limit of SPECIFIC is? The value I picked under 250 probably works, I haven't tested yet. ... Still, I'd rather go with a value more definitely not used by anyone.
Lots of things add values to SPECIFIC.ids, and some of thems eem to do so programmatically. I'm not sure it's possible to say "this value is definitely not used by anyone." It would be necessary to check for an unused value in your mod installation Weidu script.

Of course that's just problem #1. Problem #2 is that assigning a new specifics value to a creature will bump its existing value, which will break whatever it was doing; and the next mod to come along and use them will bump your value, which will break your mod.
never seen any bugreport pertaining to two mods clashes about SPECIFICS of a certain creature. If you could share any data to prove the contrary I would be grateful because I am considering to use it as well.
I don't know what and how the bugs might be seen, all I know is that the .CRE file structure only allows you to have a single value for "specifics" (0x274, 1 byte), so the SPECIFIC value can only ever do one thing for a creature. Whereas, a .CRE can be assigned hundreds or thousands of spellstates simultaneously and they will all work fine. For this reason, put together with the concern mentioned above, spellstates are strictly superior for this application. There is literally zero benefit to using specifics - in this case.

Here is a shot of SPECIFIC.ids in an unmodified BGEE install:
Screen Shot 2018-02-20 at 10.43.06 AM.png

And here is a shot in a basic EET install:
Screen Shot 2018-02-20 at 10.28.37 AM.png

I don't know what added all those entries, or how. And note, this is a bare EET install - no actual mods have been installed onto it. So all sorts of other things might add more values there.
I have asked many years ago what mods, if any, actually uses SPECIFICS, but got no response.
My feat system and the newest version of Refinements uses a SPECIFIC value for player-character thieves. In my defense, it did not exist many years ago :) I only made it a couple months ago. It does not conflict with SoD or any other mods from what I can tell, it only affects thieves who are one of your six party members. Even then I really wanted to avoid it, except there is literally no other way to achieve what the mod does, and my feature requests with Beamdog have so far fallen on deaf ears. :(

EDIT - the recent "Shadow Magic" mod also uses specifics for party members, but only for a few kits (mage/sorcerer/monk, I think), and in ways that do not conflict with my usage for thieves.

My sense of this is that it's a minefield for compatibility... happily, there are other systems that are strictly superior to using specifics for just about anything a modder might want to do. And hopefully with the new patch, the number of those other superior systems will be even greater.
This might help more, if you gave a live example of your code. Anyone ?
He seems to really not want that. Why would I take the time to collect and post something that nobody actually wants?

Anyway I didn't write it myself, I think actually GeN1e gave it to me... also, although I used it a couple months ago, I don't actually remember what I used it for :lol: There is a lot of code on my github page, and I'm not sure where to look for this bit.

Edited by subtledoctor, 20 February 2018 - 08:04 AM.


#15 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 20 February 2018 - 08:55 AM

In BG2EE we used specific a lot for factions. This leaves little room for spell states as you would overwrite the faction value.  

 

Btw, it is perfectly legit to use specifics with effects, except you must be aware their current use in AI scripting.

You should still add your new values to specific.ids so others know you have allocated them.
 
And, if you use values over 255 when you've been told not to, it is your fault.
 

Edited by Avenger_teambg, 20 February 2018 - 08:56 AM.

Avenger

#16 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 20 February 2018 - 09:40 AM

Btw, it is perfectly legit to use specifics with effects

Not really, unless you're talking about adding new type of actors (e.g. subrace or something) and 177/326-targeting them with custom effects.

If you go about changing the already existing value, it's no different from changing the race, class or allegiance - yes, you *can* technically do that, but unless you're working on new content you don't have enough control over environment to ensure stability. As long as the latter is high on your list of priorities, that is.


Edited by GeN1e, 20 February 2018 - 09:43 AM.

Retired from modding.


#17 subtledoctor

subtledoctor
  • Modder
  • 656 posts

Posted 20 February 2018 - 11:50 AM

Found the code:
[spoiler]
DEFINE_ACTION_FUNCTION d5_resolve_state INT_VAR index=0 delete=0 STR_VAR new_state_id = ~blah~ RET new_state_ind BEGIN
 OUTER_SET min_new=118
 COPY_EXISTING ~splstate.ids~ override
  new_state_ind=0
  found=0
  READ_2DA_ENTRIES_NOW stats 2
  FOR (row=0;row<stats;row+=1) BEGIN
    READ_2DA_ENTRY_FORMER stats row 0 ind
    READ_2DA_ENTRY_FORMER stats row 1 str
    SET $stat("%row%") = ind
    PATCH_IF index BEGIN
      PATCH_IF ind=index BEGIN
        REMOVE_2DA_ROW row 2
        found=1
        PATCH_IF delete=0 BEGIN
          INSERT_2DA_ROW row 2 ~%index% %new_state_id%~
        END
        row=stats
      END
    END ELSE BEGIN
      PATCH_IF ~%str%~ STRING_EQUAL_CASE ~%new_state_id%~ BEGIN
        new_state_ind=ind
        found=1
      END
    END
  END
 PATCH_IF found=0 BEGIN
    new_state_ind=min_new
    PHP_EACH stat AS row => ind BEGIN
      PATCH_IF found=0 && (row+1 < stats) BEGIN
        next_row = row+1
        next_ind = EVAL $stat("%next_row%")
        PATCH_IF index BEGIN
          PATCH_IF index<next_ind && index>ind BEGIN
            INSERT_2DA_ROW next_row 2 ~%index% %new_state_id%~
            found=1
          END
        END ELSE BEGIN
          PATCH_IF new_state_ind<next_ind BEGIN
            PATCH_IF ind<new_state_ind BEGIN
              INSERT_2DA_ROW next_row 2 ~%new_state_ind% %new_state_id%~
              found=1
            END ELSE BEGIN
              new_state_ind+=1
              PATCH_IF new_state_ind<next_ind BEGIN
                INSERT_2DA_ROW next_row 2 ~%new_state_ind% %new_state_id%~
                found=1
              END
            END
          END
        END
      END ELSE BEGIN 
        PATCH_IF found=0 BEGIN
          PATCH_IF index BEGIN
            INSERT_2DA_ROW stats 2 ~%index% %new_state_id%~
          END ELSE BEGIN
            PATCH_IF new_state_ind>ind BEGIN
              INSERT_2DA_ROW stats 2 ~%new_state_ind% %new_state_id%~
            END ELSE BEGIN
              new_state_ind+=1
              INSERT_2DA_ROW stats 2 ~%new_state_ind% %new_state_id%~
            END
          END
        END
      END
    END 
  END
END

LAF d5_resolve_state STR_VAR new_state_id = ~NEW_PROFICIENCIES~ RET new_state_ind END

OUTER_SET new_profs_state = %new_state_ind%

APPEND ~splprot.2da~ ~D5_PROFS_STATE%TAB%0x112%TAB%%new_profs_state%%TAB%1~

COPY_EXISTING ~splprot.2da~ ~override~
	COUNT_2DA_COLS cols // amount of columns
	READ_2DA_ENTRIES_NOW rows cols 
	FOR (row = 1; row < rows; ++row) BEGIN 
	  READ_2DA_ENTRY_FORMER rows row 0 ~stat~
	  PATCH_IF ~%stat%~ STRING_EQUAL_CASE ~D5_PROFS_STATE~ BEGIN
	    SET profs_state = %row%
	  END
	END
BUT_ONLY
[spoiler]

Should be able to paste the entirety straight into your mod, change some function and variable names away from my prefix, and add that %profs_state% varuable (or whatever you rename it to) into 324/326 effects via ALTER_EFFECT or ADD_SPELL_EFFECT or what have you.

#18 temnix

temnix
  • Member
  • 983 posts

Posted 20 February 2018 - 06:03 PM

For my purposes a simple change should suffice. It's temporary, too.



#19 Creepin

Creepin
  • Administrator
  • 1676 posts

Posted 21 February 2018 - 05:05 AM

I don't know what and how the bugs might be seen, all I know is that the .CRE file structure only allows you to have a single value for "specifics" (0x274, 1 byte), so the SPECIFIC value can only ever do one thing for a creature. Whereas, a .CRE can be assigned hundreds or thousands of spellstates simultaneously and they will all work fine.
Let's say I need to mark the creature as a target for the scripted attack.
With SPECIFICS I could use opcode #72 and then proper targeting will be done as simple as Attack(Nearest([0.0.0.0.222])) (the number used as an example). Is it possible to get anything remotely as simple and as reliable as this by swapping SPECIFICS approach to spellstates approach?

As far as I understand spellstates you can't just Attack(Nearest(my_spellstate)), you had first to lock target by See trigger. Further, you can't See(Nearest(my_spellstate)), you had to run
IF
StateCheck(TenthNearestEnemyOf(),my_spellstate)
See(TenthNearestEnemyOf())
IF
StateCheck(NinthNearestEnemyOf(),my_spellstate)
See(NinthNearestEnemyOf())
...
IF
StateCheck(NearestEnemyOf(),my_spellstate)
See(NearestEnemyOf())
and even after all that you are royally screwed if the creature you need to target happened to be 11th nearest.

Am I missing something, could spellstate be implemented with a less clumsiness?

Edited by Creepin, 21 February 2018 - 05:08 AM.

The Old Gold - v0.2 WIP (mod for BGT/BWP/BWS)


#20 subtledoctor

subtledoctor
  • Modder
  • 656 posts

Posted 21 February 2018 - 05:23 AM

I don't know much about AI scripting. That sort of sounds like you're trying to implement some kind of "aggro management," in which I have no interest.

It also seems like there's a chicken/egg problem there: yes you can target the person with the SPECIFIC value but how do you know who to tag with the SPECIFIC value? If it's a .CRE file with a particular allegience or something lile that then sure - as GeN1e noted, this function is designed for, and recently used extensively for, AI scripting.

But that's for giving .CRE files a SPECIFIC value at install-time. This thread is about targeting via 324/326 effects. And applying a value, maybe temporarily, mid-game. For such purposes spellstates are strictly superior; for such purposes, the is simply no need nor any benefit to mucking around with SPECIFICs.

For AI, SPECIFICs seem very useful. For party members, it seems more straightforward to identify them via PLAYER1 etc. and/or other conditional checks (Class, SpellCastOnMe, CheckStat, whatever).

Edited by subtledoctor, 21 February 2018 - 05:24 AM.