Jump to content


Photo

Enemy item shattering and standard AI scripts


  • Please log in to reply
28 replies to this topic

#1 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 09 August 2008 - 04:26 AM

BGT Tweak is coming along nicely. I've managed to get enemy item shattering working using the standard AI scripts (managed to smash a guard's weapon and shield...took too long to smash his armor, though). However, the method of implementation comes with significant caveats, namely the fact that some enemies don't use the standard AI scripts.

Other issues that can be addressed:

I need to know whether there are any standard AI scripts used in BG1 other than WDARSGT, WDASIGHT, WTARSFT, and WTASIGHT.
I need to know exactly what mods out there replace the use of the standard AI scripts, e.g. does BP replace these scripts with its own copies?

Also, do people want additional feedback that enemies' items have shattered apart from the change in graphic? I am currently thinking that it is more strategic only to give you the visual cue rather than a blatant verbal, vocal, or textual cue.

Edited by Ascension64, 09 August 2008 - 04:29 AM.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#2 Salk

Salk
  • Modder
  • 1411 posts

Donator

Posted 09 August 2008 - 10:56 PM

Personally I would not mind limiting the feedback to the visual clue.

#3 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 10 August 2008 - 02:28 AM

I need to know whether there are any standard AI scripts used in BG1 other than WDARSGT, WDASIGHT, WTARSFT, and WTASIGHT.

Well, you might want to merge this with the other thread I just replied in, and it depends on what you mean by 'standard AI' but those are the common enemy attack scripts, yes.

As for mods that change or overwrite them, a 'weidu --change-log wtasight.bcs' on my BWP install shows SCS, SCSII, BPSeries (this is a different mod than BP), D0QuestPack and Tactics. The first mod is the only one I know of that is relevant to BG1 (or the BG1 portion of Tutu or BGT, really, as it isn't BG1 compatible).

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#4 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 10 August 2008 - 03:28 AM

I need to know whether there are any standard AI scripts used in BG1 other than WDARSGT, WDASIGHT, WTARSFT, and WTASIGHT.

Well, you might want to merge this with the other thread I just replied in, and it depends on what you mean by 'standard AI' but those are the common enemy attack scripts, yes.

As for mods that change or overwrite them, a 'weidu --change-log wtasight.bcs' on my BWP install shows SCS, SCSII, BPSeries (this is a different mod than BP), D0QuestPack and Tactics. The first mod is the only one I know of that is relevant to BG1 (or the BG1 portion of Tutu or BGT, really, as it isn't BG1 compatible).

I didn't mean 'overwrite', but completely replaced. For example, I think BP might replace those scripts with BPWDSGT.BCS, etc., or something similar, which makes modifying the standard AI scripts useless.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#5 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 10 August 2008 - 06:35 PM

I didn't mean 'overwrite', but completely replaced. For example, I think BP might replace those scripts with BPWDSGT.BCS, etc., or something similar, which makes modifying the standard AI scripts useless.

Well, DavidW answered that for SCS - I don't have a lot of familiarity with those other mods. Why not just extend the script regardless of what the script is rather than hardcoding the script list? P5Tweaks v2 does this for its Frozen Death component if you want an example (the code is primarily Nythrun's).

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#6 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 11 August 2008 - 02:03 AM

I didn't mean 'overwrite', but completely replaced. For example, I think BP might replace those scripts with BPWDSGT.BCS, etc., or something similar, which makes modifying the standard AI scripts useless.

Well, DavidW answered that for SCS - I don't have a lot of familiarity with those other mods. Why not just extend the script regardless of what the script is rather than hardcoding the script list? P5Tweaks v2 does this for its Frozen Death component if you want an example (the code is primarily Nythrun's).

I think this case is a lot more difficult than that one, for several reasons:
  • P5Tweaks seems to only work at the Override script level
  • If P5Tweaks modified the Override script for one CRE, then for a later CRE that Override script becomes, say, the Default script, then for that CRE two copies of the script block are created (bad for BGTTweaks because this causes probability addition to the chance that the item will shatter)
  • If P5Tweaks modifies the Override script for one CRE, but for a previous CRE that Override script was, say, the Default script, then the script block duplication occurs again (but this time you can't even check it without doing a consistency check after patching all CREs - and fixing the consistency issue is even harder, which involves a matrix detailing scripts that are exclusive of each other)
I'm sure it is possible in WeiDU, though. Will need to think about any easier ways to do this.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#7 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 11 August 2008 - 02:43 AM

* P5Tweaks seems to only work at the Override script level

Yes, but that's easy enough to change. Since the scripts you're interested are usually assigned in the Default slot, all you have to do is change 0x248 to 0x268, as I'm sure you know. If there is nothing in that slot, a new one with your code will be assigned (and this same one will be used if it finds any other blanks).

* If P5Tweaks modified the Override script for one CRE, then for a later CRE that Override script becomes, say, the Default script, then for that CRE two copies of the script block are created (bad for BGTTweaks because this causes probability addition to the chance that the item will shatter)
* If P5Tweaks modifies the Override script for one CRE, but for a previous CRE that Override script was, say, the Default script, then the script block duplication occurs again (but this time you can't even check it without doing a consistency check after patching all CREs - and fixing the consistency issue is even harder, which involves a matrix detailing scripts that are exclusive of each other)

No to both. It uses an array to keep track of all scripts it scans and a PATCH_IF NOT VARIABLE_IS_SET construction to make sure scripts aren't added to the array redundantly, then an ACTION_PHP_EACH to EXTEND them all one time only, once it has finalised that array (like I said, the code is mostly Nythrun's).

Edit: I see what you are saying though, in that there is a potential for some redundancy if an extended script is used in a slot other than Default, but I think that potential is quite slim, and could probably be handled just by a variable or some other type of check in your script block.

Also I exclude animals on the basis they shouldn't have much in their inventories, if anything, and summonees on the basis that they shouldn't be dropping anything anyway. You may want to exclude the former as well, though the latter may be relevant to breakage. You can, of course, exclude anything else you wish using similar code.

Edited by Miloch, 11 August 2008 - 02:50 AM.

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#8 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 11 August 2008 - 04:39 AM

* P5Tweaks seems to only work at the Override script level

Yes, but that's easy enough to change. Since the scripts you're interested are usually assigned in the Default slot, all you have to do is change 0x248 to 0x268, as I'm sure you know. If there is nothing in that slot, a new one with your code will be assigned (and this same one will be used if it finds any other blanks).

Ideally, the shattering script would be applied to every single creature. So, I would be interested in practically all 5 script slots at the same time. Easy enough to change, though.

* If P5Tweaks modified the Override script for one CRE, then for a later CRE that Override script becomes, say, the Default script, then for that CRE two copies of the script block are created (bad for BGTTweaks because this causes probability addition to the chance that the item will shatter)
* If P5Tweaks modifies the Override script for one CRE, but for a previous CRE that Override script was, say, the Default script, then the script block duplication occurs again (but this time you can't even check it without doing a consistency check after patching all CREs - and fixing the consistency issue is even harder, which involves a matrix detailing scripts that are exclusive of each other)

No to both. It uses an array to keep track of all scripts it scans and a PATCH_IF NOT VARIABLE_IS_SET construction to make sure scripts aren't added to the array redundantly, then an ACTION_PHP_EACH to EXTEND them all one time only, once it has finalised that array (like I said, the code is mostly Nythrun's).

Edit: I see what you are saying though, in that there is a potential for some redundancy if an extended script is used in a slot other than Default, but I think that potential is quite slim, and could probably be handled just by a variable or some other type of check in your script block.

The first one should be OK for redundancy check, however the second requires a backward check. In addition, the second may pose extra problems if script assignation is not always assumed to be in the Default block (I have already noted some examples of this). The worst part is if SCS or BP change the location in which the standard AI scripts are assigned. Anyway, I'll give it a shot on the weekend and see what happens.

Plus, I find Nythrun's code quite obfuscated just because of the way she names her variables with gross abbreviations - but, I'll get used to that. :)

Also I exclude animals on the basis they shouldn't have much in their inventories, if anything, and summonees on the basis that they shouldn't be dropping anything anyway. You may want to exclude the former as well, though the latter may be relevant to breakage. You can, of course, exclude anything else you wish using similar code.

I'll likely exclude some creatures too, depending on which ones never use breakable weapons, armor, and shields.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#9 DavidWallace

DavidWallace
  • Validating
  • 337 posts

Posted 11 August 2008 - 05:12 AM

Out of interest, if you're recoding this anyway, why not use the TUTU method. That seems pretty reliable, and doesn't rely on scripts.

#10 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 11 August 2008 - 05:51 AM

Out of interest, if you're recoding this anyway, why not use the TUTU method. That seems pretty reliable, and doesn't rely on scripts.

Well, I'm not re-coding the shattering of items. This is different because I'm trying to apply this to enemies. For weapon shattering, the Tutu method is fine. However, the Tutu method cannot handle armor and shield shattering.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#11 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 11 August 2008 - 12:12 PM

Ideally, the shattering script would be applied to every single creature. So, I would be interested in practically all 5 script slots at the same time.

Well, no... then you definitely would get duplication. You should pick one slot and stick with it - probably the first or last (Override or Default) depending on what kind of priority is important for your block. Like I said, it'll assign a script if there's not one in the slot you're targetting. But yes, you might want to scan the other slots and skip extension if there's a script in another slot that's already been extended. It probably wouldn't be a major coding effort to do this. For p5tweaks, I didn't see the need, since it only adds a few lines as an initial script block (triggering on death) and redundancy isn't an issue.

Plus, I find Nythrun's code quite obfuscated just because of the way she names her variables with gross abbreviations - but, I'll get used to that. :)

That's probably my code. I personally find it more readable than long variable names, particularly when they're repeated multiple times and wrap several lines. Matter of preference I suppose. I usually comment what the variables are on first-time use at least.

Doesn't BG2 Tweaks have (or claim to have) a breakable weapons and armour component too?

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#12 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 11 August 2008 - 07:39 PM

Ideally, the shattering script would be applied to every single creature. So, I would be interested in practically all 5 script slots at the same time.

Well, no... then you definitely would get duplication. You should pick one slot and stick with it - probably the first or last (Override or Default) depending on what kind of priority is important for your block. Like I said, it'll assign a script if there's not one in the slot you're targetting. But yes, you might want to scan the other slots and skip extension if there's a script in another slot that's already been extended. It probably wouldn't be a major coding effort to do this. For p5tweaks, I didn't see the need, since it only adds a few lines as an initial script block (triggering on death) and redundancy isn't an issue.

If all 5 slots are not considered, then there is an increased chance of redundancy, e.g. WTASIGHT is used in some cases in the Class script position rather than the Default script. I am not saying all 5 slots need to be patched, but they all need to be considered.

Plus, I find Nythrun's code quite obfuscated just because of the way she names her variables with gross abbreviations - but, I'll get used to that. :)

That's probably my code. I personally find it more readable than long variable names, particularly when they're repeated multiple times and wrap several lines. Matter of preference I suppose. I usually comment what the variables are on first-time use at least.

If you have standard abbreviations, it is OK I guess, but that won't help anyone else figure out what those abbreviations mean. I find portability of code more of an issue, but as long as it works, and has some resemblance of structure and formatting, it shouldn't really matter.

Doesn't BG2 Tweaks have (or claim to have) a breakable weapons and armour component too?

I don't know, but I will check.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#13 Kastagir

Kastagir
  • Member
  • 58 posts

Posted 12 August 2008 - 07:19 AM

Ideally, the shattering script would be applied to every single creature. So, I would be interested in practically all 5 script slots at the same time.

Well, no... then you definitely would get duplication. You should pick one slot and stick with it - probably the first or last (Override or Default) depending on what kind of priority is important for your block. Like I said, it'll assign a script if there's not one in the slot you're targetting. But yes, you might want to scan the other slots and skip extension if there's a script in another slot that's already been extended. It probably wouldn't be a major coding effort to do this. For p5tweaks, I didn't see the need, since it only adds a few lines as an initial script block (triggering on death) and redundancy isn't an issue.

If all 5 slots are not considered, then there is an increased chance of redundancy, e.g. WTASIGHT is used in some cases in the Class script position rather than the Default script. I am not saying all 5 slots need to be patched, but they all need to be considered.

Plus, I find Nythrun's code quite obfuscated just because of the way she names her variables with gross abbreviations - but, I'll get used to that. :)

That's probably my code. I personally find it more readable than long variable names, particularly when they're repeated multiple times and wrap several lines. Matter of preference I suppose. I usually comment what the variables are on first-time use at least.

If you have standard abbreviations, it is OK I guess, but that won't help anyone else figure out what those abbreviations mean. I find portability of code more of an issue, but as long as it works, and has some resemblance of structure and formatting, it shouldn't really matter.

Doesn't BG2 Tweaks have (or claim to have) a breakable weapons and armour component too?

I don't know, but I will check.


I understand that you are working on *enemy* item shattering, but will the updated version of BGT Tweaks actually allow you to disable item shattering? The current version (v7) gives me an error whenever I try to enable that component. This is with a clean BGT 1.06 install with no mods other than BGT Tweaks, and only the explored city areas and bags of the sword coast components installed.

#14 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 20 December 2008 - 05:24 AM

Still working on this. I've made some convoluted code that tries to ensure that all CREs have only one of their scripts patched. Thanks to Miloch's tweaks code I've abused arrays to the max.

The biggest problem I have had is the following scenario:
1. Creature X has script A only
2. Creature Y has script F only
3. Creature Z has scripts A and F

4. So long as the setup looks at creatures X and Y first, creature Z will always have both its scripts modified
5. Then multiply this by lots of script triplets that do this

The only way I have been able to get around this is to make the setup re-iterate the entire sequence again but excluding F (as in the above example) -> then setup will create a new script for Y. Unfortunately, because there are so many triplets, it takes setup 7 iterations to settle to a satisfying outcome (which takes a lot of time), and if you exclude all the BG2 only files (since this is only for BG1), it takes setup 2 iterations (a lot better, but who knows what happens in a BWP install...).

The other problem with this is that creatures with 5 scripts in their slots already and all their scripts are excluded cannot be modified. That sucks.

Hence, in the next version of BGT Tweaks, this will only be a 'testing' component, because it could produce really awful results, and on some installations it might iterate forever!

Any suggestions of how to better tackle this problem would be appreciated.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#15 Taimon

Taimon
  • Member
  • 387 posts

Posted 20 December 2008 - 08:51 AM

The other problem with this is that creatures with 5 scripts in their slots already and all their scripts are excluded cannot be modified. That sucks.

I think this is only a theoretical problem. Most creatures with 5 scripts should have at least 1 very specific script, not shared by others.

What does your code for the shattering look like?

#16 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 20 December 2008 - 11:10 PM

The other problem with this is that creatures with 5 scripts in their slots already and all their scripts are excluded cannot be modified. That sucks.

I think this is only a theoretical problem. Most creatures with 5 scripts should have at least 1 very specific script, not shared by others.

What does your code for the shattering look like?

It's probably because I'm promoting a catch-all method by starting from the default script slot rather than the override slot. I can test by starting with the override first.


DEFINE_PATCH_MACRO ~parseCRE~ BEGIN

	READ_ASCII 0x268 $scriptlist(default)
	READ_ASCII 0x260 $scriptlist(general)
	READ_ASCII 0x258 $scriptlist(race)
	READ_ASCII 0x250 $scriptlist(class)
	READ_ASCII 0x248 $scriptlist(override)

	SET found = 0

	//check all CRE scripts to see if extended script already present
	PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	  PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
		TO_UPPER script
		PATCH_IF VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%") BEGIN
		  SET found = 1
		END
	  END
	END

	PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	  PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
		TO_UPPER script
		//if CRE script already chosen, put all other scripts on exclude list unless already on extend list
		PATCH_IF (found) BEGIN
		  PATCH_IF NOT VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%")  AND
				   NOT VARIABLE_IS_SET $excludelist(EVALUATE_BUFFER "%script%") BEGIN
			SPRINT $excludelist(EVALUATE_BUFFER "%script%") "%script%"
		  END
		END
		//if CRE script not yet chosen, put the first script not on exclude list onto extend list
		PATCH_IF (!found) BEGIN
		  PATCH_IF NOT VARIABLE_IS_SET $excludelist(EVALUATE_BUFFER "%script%") AND
				   NOT VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%")  BEGIN
			SPRINT $extendlist(EVALUATE_BUFFER "%script%") "%script%"
			SET found = 1
		  END
		END
	  END
	END
  
	PATCH_IF (!found) BEGIN
	  PATCH_IF VARIABLE_IS_SET $script5filelist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN
		PATCH_PRINT ~Warning: will attempt to create script for %SOURCE_RES% that is already full~
		SPRINT $createlist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	  END
	END

END

BEGIN ~Test script patch~

<<<<<<<<base.txt
ExcludeScripts:
>>>>>>>>

<<<<<<<<cre.txt
ExcludeCRE:
... (list of BG2-exclusive CREs)
>>>>>>>>

COPY ~base.txt~ ~current.txt~
OUTER_SET iterate = 1

OUTER_WHILE (iterate) BEGIN

  OUTER_SET problem = 0

  COPY ~cre.txt~ ~cre.txt~
	COUNT_2DA_ROWS 1 rows
	FOR (i = 1; i < rows; i+=1) BEGIN
	  READ_2DA_ENTRY i 0 1 string
	  SPRINT $excludeCRElist(EVALUATE_BUFFER "%string%") "%string%"
	END
  BUT_ONLY_IF_IT_CHANGES

//group all creature files based on how many scripts they have assigned
COPY_EXISTING_REGEXP GLOB ~^.+\.CRE$~ ~override~
  PATCH_IF NOT VARIABLE_IS_SET $excludeCRElist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN

  READ_ASCII 0x268 $scriptlist(default)
  READ_ASCII 0x260 $scriptlist(general)
  READ_ASCII 0x258 $scriptlist(race)
  READ_ASCII 0x250 $scriptlist(class)
  READ_ASCII 0x248 $scriptlist(override)

  SET numscripts = 0

  PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
	  SET numscripts += 1
	END
  END

  PATCH_IF (%numscripts% = 0) BEGIN
	SPRINT $script0filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
  END ELSE
  PATCH_IF (%numscripts% = 1) BEGIN
	SPRINT $script1filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
  END ELSE
  PATCH_IF (%numscripts% = 2) BEGIN
	SPRINT $script2filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
  END ELSE
  PATCH_IF (%numscripts% = 3) BEGIN
	SPRINT $script3filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
  END ELSE
  PATCH_IF (%numscripts% = 4) BEGIN
	SPRINT $script4filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
  END ELSE
  PATCH_IF (%numscripts% = 5) BEGIN
	SPRINT $script5filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
  END

  END
BUT_ONLY_IF_IT_CHANGES

//parse creature files in order from 5 scripts to 0 scripts
ACTION_PHP_EACH script5filelist AS script5filearray => script5file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script5file%.CRE~ BEGIN
	COPY_EXISTING ~%script5file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script4filelist AS script4filearray => script4file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script4file%.CRE~ BEGIN
	COPY_EXISTING ~%script4file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script3filelist AS script3filearray => script3file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script3file%.CRE~ BEGIN
	COPY_EXISTING ~%script3file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script2filelist AS script2filearray => script2file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script2file%.CRE~ BEGIN
	COPY_EXISTING ~%script2file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script1filelist AS script1filearray => script1file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script1file%.CRE~ BEGIN
	COPY_EXISTING ~%script1file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script0filelist AS script0filearray => script0file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script0file%.CRE~ BEGIN
	COPY_EXISTING ~%script0file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

//consistency check
COPY_EXISTING_REGEXP GLOB ~^.+\.CRE$~ ~override~
  PATCH_IF NOT VARIABLE_IS_SET $excludeCRElist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN

  READ_ASCII 0x268 $scriptlist(default)
  READ_ASCII 0x260 $scriptlist(general)
  READ_ASCII 0x258 $scriptlist(race)
  READ_ASCII 0x250 $scriptlist(class)
  READ_ASCII 0x248 $scriptlist(override)

  SET extendmatch = 0
  SET creatematch = 0

  PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	TO_UPPER script
	PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
	  PATCH_IF VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%") BEGIN
		SET extendmatch += 1
		PATCH_IF (extendmatch > 1) BEGIN
		  SET problem = 1
		  PATCH_PRINT ~Warning: %SOURCE_FILE% (%extendmatch% extended scripts)~
		  PATCH_IF NOT VARIABLE_IS_SET $newexcludelist(EVALUATE_BUFFER "%script%") BEGIN
			PATCH_PRINT ~Excluding %script% on new iteration...~
			SPRINT $newexcludelist(EVALUATE_BUFFER "%script%") "%script%"
			INNER_ACTION BEGIN
			  APPEND_OUTER ~current.txt~ "%script%"
			END
		  END
		END
	  END
	END
  END

  PATCH_IF VARIABLE_IS_SET $createlist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN
	SET creatematch = 1
  END

/*
  PATCH_IF (%extendmatch% > 0 AND %creatematch% > 0) BEGIN
	PATCH_PRINT ~Warning: %SOURCE_FILE% (%extendmatch% extended script/s + create)~
  END
*/

  END
BUT_ONLY_IF_IT_CHANGES

ACTION_IF (problem) BEGIN
  CLEAR_MEMORY

  OUTER_SET problem = 1
  OUTER_SET iterate = 1

  COPY ~current.txt~ ~current.txt~
	COUNT_2DA_ROWS 1 rows
	FOR (i = 1; i < rows; i+=1) BEGIN
	  READ_2DA_ENTRY i 0 1 string
	  SPRINT $excludelist(EVALUATE_BUFFER "%string%") "%string%"
	END
  BUT_ONLY_IF_IT_CHANGES

  PRINT ~Now re-iterating...~
END ELSE BEGIN
  OUTER_SET iterate = 0
END

END

//Finally do the stuff
/*
PRINT ~Scripts to extend...~
ACTION_PHP_EACH extendlist AS extendarray => extend BEGIN
  //extend these scripts
END

PRINT ~Creatures to make new scripts for...~
ACTION_PHP_EACH createlist AS createarray => create BEGIN
  //set to some common compiled script for each
END
*/
/////////////////////////////////////////////////////////////

Edited by Ascension64, 20 December 2008 - 11:10 PM.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#17 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 21 December 2008 - 09:51 PM

Tried the top-down order (override --> default) results in more recursions than bottom-up order (default --> override), but it does get rid of the problem of 5 scripts. However, if you apply this script to all scripts on a BGT on BG2 install, it still can't handle the 5 script problem for 7 CREs.

Edited by Ascension64, 21 December 2008 - 10:18 PM.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#18 Taimon

Taimon
  • Member
  • 387 posts

Posted 22 December 2008 - 08:52 AM

Well, I'd rather have a look at the enemy item shattering code (script), to see if it's possible to ignore multiple runs through the block in one script loop. (Sorry, if my request above was unclear.)
But I'll have a look at this as well.

Btw, I think you can strip that EVALUATE_BUFFER in the dollar array notation.

/Edit:
Maybe you should prioritize scripts with higher usage counts when a CRE isn't covered and you need to add one script to the extend list.
(That would need another array to keep track of the script usage counts.)

Edited by Taimon, 22 December 2008 - 03:18 PM.


#19 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 22 December 2008 - 03:40 PM

Hold on, let me show you what I've got at the moment then.
I guess an alternative way is to work out what to extend for only the CREs with all 5 script slots taken, and then just add new scripts to all other CREs provided that they don't share a script with the 5 script slot CREs.

BaseExcl.txt
0
ExcludeScripts:

CREExcl.txt
ExcludeCRE:

Extend.txt (scripts to force extension on, increases chances of infinite loop, so the option is here but I don't actually use it)
IncludeScripts:

DEFINE_PATCH_MACRO ~__24__parseCRE~ BEGIN
  READ_ASCII 0x248 $scriptlist(0) //override
  READ_ASCII 0x250 $scriptlist(1) //class
  READ_ASCII 0x258 $scriptlist(2) //race
  READ_ASCII 0x260 $scriptlist(3) //general
  READ_ASCII 0x268 $scriptlist(4) //default

  SET found = 0

  //check all CRE scripts to see if extended script already present
  PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
	  TO_UPPER script
	  PATCH_IF VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%") BEGIN
		SET found = 1
	  END
	END
  END

  PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
	  TO_UPPER script
	  //if CRE script already chosen, put all other scripts on exclude list unless already on extend list
	  PATCH_IF (found) BEGIN
		PATCH_IF NOT VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%")  AND
				 NOT VARIABLE_IS_SET $excludelist(EVALUATE_BUFFER "%script%") BEGIN
		  SPRINT $excludelist(EVALUATE_BUFFER "%script%") "%script%"
		END
	  END
	  //if CRE script not yet chosen, put the first script not on exclude list onto extend list
	  PATCH_IF (!found) BEGIN
		PATCH_IF NOT VARIABLE_IS_SET $excludelist(EVALUATE_BUFFER "%script%") AND
				 NOT VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%")  BEGIN
		  SPRINT $extendlist(EVALUATE_BUFFER "%script%") "%script%"
		  SET found = 1
		END
	  END
	END
  END
  
  PATCH_IF (!found) BEGIN
	PATCH_IF VARIABLE_IS_SET $script5filelist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN
	  PATCH_PRINT ~Warning: will attempt to create script for %SOURCE_RES% that is already full~
	  PATCH_SILENT
	  SPRINT $createlist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	END
  END
END

//#24 Enemy items shatter////////////////////////////////////
BEGIN @2400
FORBID_COMPONENT ~Setup-BGTTweak.tp2~ 19 @7

COPY ~BGTTweak/24/BaseExcl.txt~ ~BGTTweak/24/Excl.txt~
OUTER_SET iterate = 1

OUTER_WHILE (iterate) BEGIN

  OUTER_SET problem = 0

  COPY ~BGTTweak/24/CREExcl.txt~ ~BGTTweak/24/CREExcl.txt~
	COUNT_2DA_ROWS 1 rows
	FOR (i = 1; i < rows; i+=1) BEGIN
	  READ_2DA_ENTRY i 0 1 string
	  SPRINT $excludeCRElist(EVALUATE_BUFFER "%string%") "%string%"
	END
  BUT_ONLY_IF_IT_CHANGES

  COPY ~BGTTweak/24/Extend.txt~ ~BGTTweak/24/Extend.txt~
	COUNT_2DA_ROWS 1 rows
	FOR (i = 1; i < rows; i+=1) BEGIN
	  READ_2DA_ENTRY i 0 1 string
	  SPRINT $extendlist(EVALUATE_BUFFER "%string%") "%string%"
	  SPRINT $forceextendlist(EVALUATE_BUFFER "%string%") "%string%"
	END
  BUT_ONLY_IF_IT_CHANGES

//group all creature files based on how many scripts they have assigned
COPY_EXISTING_REGEXP GLOB ~^.+\.CRE$~ ~override~
  PATCH_IF NOT VARIABLE_IS_SET $excludeCRElist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN

	READ_ASCII 0x248 $scriptlist(0) //override
	READ_ASCII 0x250 $scriptlist(1) //class
	READ_ASCII 0x258 $scriptlist(2) //race
	READ_ASCII 0x260 $scriptlist(3) //general
	READ_ASCII 0x268 $scriptlist(4) //default

	//check for CREs with two copies of the same script and remove appropriately
	PATCH_IF ("%scriptlist_0%" STRING_COMPARE_CASE "%scriptlist_1%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_0%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_1%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: override script == class script (%scriptlist_0%). Removing override script...~
	  WRITE_ASCII 0x248 "" #8
	  READ_ASCII 0x248 $scriptlist(0)
	END ELSE
	PATCH_IF ("%scriptlist_0%" STRING_COMPARE_CASE "%scriptlist_2%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_0%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_2%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: override script == race script (%scriptlist_0%). Removing override script...~
	  WRITE_ASCII 0x248 "" #8
	  READ_ASCII 0x248 $scriptlist(0)
	END ELSE
	PATCH_IF ("%scriptlist_0%" STRING_COMPARE_CASE "%scriptlist_3%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_0%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_3%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: override script == general script (%scriptlist_0%). Removing override script...~
	  WRITE_ASCII 0x248 "" #8
	  READ_ASCII 0x248 $scriptlist(0)
	END ELSE
	PATCH_IF ("%scriptlist_0%" STRING_COMPARE_CASE "%scriptlist_4%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_0%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_4%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: override script == default script (%scriptlist_0%). Removing override script...~
	  WRITE_ASCII 0x248 "" #8
	  READ_ASCII 0x248 $scriptlist(0)
	END

	PATCH_IF ("%scriptlist_1%" STRING_COMPARE_CASE "%scriptlist_2%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_1%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_2%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: class script == race script (%scriptlist_1%). Removing class script...~
	  WRITE_ASCII 0x250 "" #8
	  READ_ASCII 0x250 $scriptlist(1)
	END ELSE
	PATCH_IF ("%scriptlist_1%" STRING_COMPARE_CASE "%scriptlist_3%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_1%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_3%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: class script == general script (%scriptlist_1%). Removing class script...~
	  WRITE_ASCII 0x250 "" #8
	  READ_ASCII 0x250 $scriptlist(1)
	END ELSE
	PATCH_IF ("%scriptlist_1%" STRING_COMPARE_CASE "%scriptlist_4%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_1%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_4%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: class script == default script (%scriptlist_1%). Removing class script...~
	  WRITE_ASCII 0x250 "" #8
	  READ_ASCII 0x250 $scriptlist(1)
	END

	PATCH_IF ("%scriptlist_2%" STRING_COMPARE_CASE "%scriptlist_3%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_2%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_3%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: race script == general script (%scriptlist_2%). Removing race script...~
	  WRITE_ASCII 0x258 "" #8
	  READ_ASCII 0x258 $scriptlist(2)
	END ELSE
	PATCH_IF ("%scriptlist_2%" STRING_COMPARE_CASE "%scriptlist_4%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_2%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_4%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%: race script == default script (%scriptlist_2%). Removing race script...~
	  WRITE_ASCII 0x258 "" #8
	  READ_ASCII 0x258 $scriptlist(2)
	END

	PATCH_IF ("%scriptlist_3%" STRING_COMPARE_CASE "%scriptlist_4%" = 0) AND
			 FILE_EXISTS_IN_GAME "%scriptlist_3%.BCS" AND
			 FILE_EXISTS_IN_GAME "%scriptlist_4%.BCS" BEGIN
	  PATCH_PRINT ~%SOURCE_FILE%.CRE: general script == default script (%scriptlist_3%). Removing general script...~
	  WRITE_ASCII 0x260 "" #8
	  READ_ASCII 0x260 $scriptlist(3)
	END

	SET numscripts = 0

	PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	  PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
		SET numscripts += 1
	  END
	END

	PATCH_IF (%numscripts% = 0) BEGIN
	  SPRINT $script0filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	END ELSE
	PATCH_IF (%numscripts% = 1) BEGIN
	  SPRINT $script1filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	END ELSE
	PATCH_IF (%numscripts% = 2) BEGIN
	  SPRINT $script2filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	END ELSE
	PATCH_IF (%numscripts% = 3) BEGIN
	  SPRINT $script3filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	END ELSE
	PATCH_IF (%numscripts% = 4) BEGIN
	  SPRINT $script4filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	END ELSE
	PATCH_IF (%numscripts% = 5) BEGIN
	  SPRINT $script5filelist(EVALUATE_BUFFER "%SOURCE_RES%") "%SOURCE_RES%"
	END

  END
BUT_ONLY_IF_IT_CHANGES

SILENT

//parse creature files in order from 5 scripts to 0 scripts
ACTION_PHP_EACH script5filelist AS script5filearray => script5file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script5file%.CRE~ BEGIN
	COPY_EXISTING ~%script5file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~__24__parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script4filelist AS script4filearray => script4file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script4file%.CRE~ BEGIN
	COPY_EXISTING ~%script4file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~__24__parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script3filelist AS script3filearray => script3file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script3file%.CRE~ BEGIN
	COPY_EXISTING ~%script3file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~__24__parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script2filelist AS script2filearray => script2file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script2file%.CRE~ BEGIN
	COPY_EXISTING ~%script2file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~__24__parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script1filelist AS script1filearray => script1file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script1file%.CRE~ BEGIN
	COPY_EXISTING ~%script1file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~__24__parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

ACTION_PHP_EACH script0filelist AS script0filearray => script0file BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%script0file%.CRE~ BEGIN
	COPY_EXISTING ~%script0file%.CRE~ ~override~
	  LAUNCH_PATCH_MACRO ~__24__parseCRE~
	BUT_ONLY_IF_IT_CHANGES
  END
END

VERBOSE

//consistency check
COPY_EXISTING_REGEXP GLOB ~^.+\.CRE$~ ~override~
  PATCH_IF NOT VARIABLE_IS_SET $excludeCRElist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN

	READ_ASCII 0x248 $scriptlist(0) //override
	READ_ASCII 0x250 $scriptlist(1) //class
	READ_ASCII 0x258 $scriptlist(2) //race
	READ_ASCII 0x260 $scriptlist(3) //general
	READ_ASCII 0x268 $scriptlist(4) //default

	SET extendmatch = 0
	SET creatematch = 0
	SPRINT prevscript "Nothing will match this"

	PATCH_PHP_EACH scriptlist AS scriptarray => script BEGIN
	  TO_UPPER script
	  PATCH_IF FILE_EXISTS_IN_GAME ~%script%.bcs~ BEGIN
		PATCH_IF VARIABLE_IS_SET $extendlist(EVALUATE_BUFFER "%script%") BEGIN
		  SET extendmatch += 1
		  PATCH_IF (extendmatch > 1) BEGIN
			SET problem = 1
			PATCH_PRINT ~Warning: %SOURCE_FILE% (%extendmatch% extended scripts)~
			PATCH_IF NOT VARIABLE_IS_SET $newexcludelist(EVALUATE_BUFFER "%script%") BEGIN
			  PATCH_IF NOT VARIABLE_IS_SET $forceextendlist(EVALUATE_BUFFER "%script%") BEGIN
				PATCH_PRINT ~Excluding %script%.BCS on new iteration...~
				SPRINT $newexcludelist(EVALUATE_BUFFER "%script%") "%script%"
				INNER_ACTION BEGIN
				  SILENT
				  APPEND_OUTER ~BGTTweak/24/Excl.txt~ "%script%"
				  VERBOSE
				END
			  END ELSE BEGIN
				PATCH_IF NOT VARIABLE_IS_SET $newexcludelist(EVALUATE_BUFFER "%prevscript%") BEGIN
				  PATCH_IF NOT VARIABLE_IS_SET $forceextendlist(EVALUATE_BUFFER "%prevscript%") BEGIN
					PATCH_PRINT ~Excluding %prevscript%.BCS on new iteration...~
					SPRINT $newexcludelist(EVALUATE_BUFFER "%prevscript%") "%prevscript%"
					INNER_ACTION BEGIN
					  SILENT
					  APPEND_OUTER ~BGTTweak/24/Excl.txt~ "%prevscript%"
					  VERBOSE
					END
				  END ELSE
				  INNER_ACTION BEGIN
					FAIL ~Component installation would loop indefinitely (prevscript = %prevscript%, script = %script%.~
				  END
				END
			  END
			END
		  END
		  SPRINT prevscript "%script%"
		END
	  END
	END

	/*
	PATCH_IF VARIABLE_IS_SET $createlist(EVALUATE_BUFFER "%SOURCE_RES%") BEGIN
	  SET creatematch = 1
	END

	PATCH_IF (%extendmatch% > 0 AND %creatematch% > 0) BEGIN
	  PATCH_PRINT ~Warning: %SOURCE_FILE% (%extendmatch% extended script/s + create)~
	END
	*/

  END
BUT_ONLY_IF_IT_CHANGES

ACTION_IF (problem) BEGIN
  CLEAR_MEMORY

  OUTER_SET problem = 1
  OUTER_SET iterate = 1

  COPY ~BGTTweak/24/Excl.txt~ ~BGTTweak/24/Excl.txt~
	COUNT_2DA_ROWS 1 rows
	FOR (i = 2; i < rows; i+=1) BEGIN
	  READ_2DA_ENTRY i 0 1 string
	  SPRINT $excludelist(EVALUATE_BUFFER "%string%") "%string%"
	END

	READ_2DA_ENTRY 0 0 1 iterate_num
	SET iterate_num += 1
	SET_2DA_ENTRY 0 0 1 %iterate_num%
  BUT_ONLY_IF_IT_CHANGES

  PRINT ~Now re-iterating...~
END ELSE BEGIN
  OUTER_SET iterate = 0
  COPY ~BGTTweak/24/Excl.txt~ ~BGTTweak/24/Excl.txt~
	READ_2DA_ENTRY 0 0 1 iterate_num
	SET iterate_num += 1
	SET_2DA_ENTRY 0 0 1 %iterate_num%
  BUT_ONLY_IF_IT_CHANGES
  PRINT ~Completed in %iterate_num% iterations.~
END

END

//Finally do the stuff
PRINT ~Extending scripts...~
SILENT
ACTION_PHP_EACH extendlist AS extendarray => extend BEGIN
  //extend these scripts
  ACTION_IF FILE_EXISTS_IN_GAME "%extend%.bcs" BEGIN
	EXTEND_BOTTOM ~%extend%.bcs~ ~BGTTweak/24/A6SHATTE.BAF~
	ACTION_IF MOD_IS_INSTALLED ~Setup-BGTTweak.tp2~ 20 BEGIN
	  EXTEND_BOTTOM ~%extend%.bcs~ ~BGTTweak/24/A6SHATT2.BAF~
	END
  END
END

PRINT ~Modifying creatures...~
SILENT
ACTION_PHP_EACH createlist AS createarray => create BEGIN
  //set to some common compiled script for each
  PRINT ~%create%.cre~
  ACTION_IF FILE_EXISTS_IN_GAME "%create%.cre" BEGIN
	COPY_EXISTING ~%create%.cre~ ~override~
	  READ_ASCII 0x248 $scriptlist(0) //override
	  READ_ASCII 0x250 $scriptlist(1) //class
	  READ_ASCII 0x258 $scriptlist(2) //race
	  READ_ASCII 0x260 $scriptlist(3) //general
	  READ_ASCII 0x268 $scriptlist(4) //default

	  PATCH_IF NOT FILE_EXISTS_IN_GAME "%scriptlist_4%.bcs" BEGIN
		WRITE_ASCII 0x268 "A6SHATTE" #8
	  END ELSE
	  PATCH_IF NOT FILE_EXISTS_IN_GAME "%scriptlist_3%.bcs" BEGIN
		WRITE_ASCII 0x260 "A6SHATTE" #8
	  END ELSE
	  PATCH_IF NOT FILE_EXISTS_IN_GAME "%scriptlist_2%.bcs" BEGIN
		WRITE_ASCII 0x258 "A6SHATTE" #8
	  END ELSE
	  PATCH_IF NOT FILE_EXISTS_IN_GAME "%scriptlist_1%.bcs" BEGIN
		WRITE_ASCII 0x250 "A6SHATTE" #8
	  END ELSE
	  PATCH_IF NOT FILE_EXISTS_IN_GAME "%scriptlist_0%.bcs" BEGIN
		WRITE_ASCII 0x248 "A6SHATTE" #8
	  END ELSE
	  INNER_PATCH "1" BEGIN
		PATCH_PRINT ~Warning: %SOURCE_RES%.CRE not patched due to all script slots full~
		PATCH_SILENT
	  END
	BUT_ONLY_IF_IT_CHANGES
  END
END
VERBOSE

COMPILE ~BGTTweak/24/A6SHATTE.BAF~
ACTION_IF MOD_IS_INSTALLED ~Setup-BGTTweak.tp2~ 20 BEGIN
  EXTEND_BOTTOM ~A6SHATTE.BCS~ ~BGTTweak/24/A6SHATT2.BAF~
END

Edited by Ascension64, 22 December 2008 - 03:43 PM.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#20 Taimon

Taimon
  • Member
  • 387 posts

Posted 01 January 2009 - 11:16 AM

Spent quite some time with this interesting problem. I've attached my approach to solve it.
The tp2 was able to find a solution in about 5 iterations on my vanilla BGT install. (~ 5300 CREs)

Unfortunately, the code is a bit nasty and I did not include much (any?) debugging information.
But the general structure is similar to your approach.

Attached Files