Jump to content


Zed Nocear's Trigger-Simulations for BG1


55 replies to this topic

#16 jastey

    Titleless

  • Gibberlings
  • 4769 posts
  • Gender:Female
  • Location:Germany

Posted 15 September 2008 - 11:58 AM

There is a multiple area script use in Durlag's Tower (AR0507, AR0508, AR0509 and AR0510 ALL use AR0507.bcs), as Wisp found out. With the original code, this indeed gets broken.
Does the corrected code above reflect this? (I really wished I would understand the tp2 patching enough to answer that question myself.)

Would that also mean that with the corrected area script patching, the AreaCheck simulation wouldn't work in the ares AR0508, AR0509, and AR0510 since they all would give back "Area AR0507"?

Can someone give me the patching code for the area pacthing... I don't seem to understand how to integrate the new code into the existing one. What do I have to replace what would stay? :laugh:

#17 plainab

    Sasha al'Therin

  • Members
  • 1717 posts
  • Gender:Male
  • Location:Lost on the Sword Coast

Posted 15 September 2008 - 02:36 PM

The above code or the below code both take into account that there could be an existing script assigned and makes sure that the current information gets carried over to the new script.

Anytime you change the script name you run the risk of incompatibility with other mods that depend upon the original script. However, with the above or below methods you can at least ensure that all mod information added to the area scripts prior to your mods installation is carried over. Any mod coming after which does not look for the presence of the currently assigned script file may be incompatible.

I'll use your bg1npc code as an example. You'll have to change it for the non-tutu version, but this should help you to understand what is needed.

I will make comments and space things out for a better read. Final code doesn't need the comments.
/* ToSC only: */
ACTION_IF FILE_EXISTS_IN_GAME ~FW1500.are~ THEN BEGIN // if TotSC is installed
  COPY_EXISTING ~FW0500.ARE~ ~override~ // TotSC: Durlag's Tower
				~FW0501.ARE~ ~override~ // TotSC: Durlag's Tower: Cellar
				~FW0502.ARE~ ~override~ // TotSC: Durlag's Tower: L1
				~FW0503.ARE~ ~override~ // TotSC: Durlag's Tower: L2
				~FW0504.ARE~ ~override~ // TotSC: Durlag's Tower: L3
				~FW0505.ARE~ ~override~ // TotSC: Durlag's Tower: L4
				~FW0506.ARE~ ~override~ // TotSC: Durlag's Tower: Chessboard
				~FW0507.ARE~ ~override~ // TotSC: Durlag's Tower: Ice Chamber
				~FW0508.ARE~ ~override~ // TotSC: Durlag's Tower: Fire Chamber
				~FW0509.ARE~ ~override~ // TotSC: Durlag's Tower: Air Chamber
				~FW0510.ARE~ ~override~ // TotSC: Durlag's Tower: Earth Chamber
				~FW0511.ARE~ ~override~ // TotSC: Durlag's Tower: D1
				~FW0512.ARE~ ~override~ // TotSC: Durlag's Tower: D2
				~FW0513.ARE~ ~override~ // TotSC: Durlag's Tower: D3
				~FW0514.ARE~ ~override~ // TotSC: Durlag's Tower: D4
				~FW0515.ARE~ ~override~ // TotSC: Durlag's Tower: Compass Room
				~FW0516.ARE~ ~override~ // TotSC: Durlag's Tower: Demonknight's Chamber
				~FW1000.ARE~ ~override~ // TotSC: Ulgoth's Beard
				~FW1001.ARE~ ~override~ // TotSC: Ulgoth's Beard: Inn
				~FW1002.ARE~ ~override~ // TotSC: Ulgoth's Beard: Demon's Chamber
				~FW1003.ARE~ ~override~ // TotSC: Ulgoth's Beard: Storehouse
				~FW1004.ARE~ ~override~ // TotSC: Ulgoth's Beard: Mendas' House
				~FW1005.ARE~ ~override~ // TotSC: Ulgoth's Beard: Therella's House
				~FW1006.ARE~ ~override~ // TotSC: Ulgoth's Beard: House2
				~FW1007.ARE~ ~override~ // TotSC: Ulgoth's Beard: House1
				~FW1008.ARE~ ~override~ // TotSC: Ice Island
				~FW1009.ARE~ ~override~ // TotSC: Ice Island: Maze L1
				~FW1500.ARE~ ~override~ // TotSC: Isle of Balduran (North)
				~FW1501.ARE~ ~override~ // TotSC: Isle of Balduran (North): Ship D1
				~FW1502.ARE~ ~override~ // TotSC: Isle of Balduran (North): Ship D2
				~FW1503.ARE~ ~override~ // TotSC: Isle of Balduran (North): Ship D3
				~FW1504.ARE~ ~override~ // TotSC: Isle of Balduran (North): Ship D4
				~FW1505.ARE~ ~override~ // TotSC: Isle of Balduran (North): Dradeel's House
				~FW2000.ARE~ ~override~ // TotSC: Isle of Balduran (South)
				~FW2001.ARE~ ~override~ // TotSC: Isle of Balduran (South): Great Hut
				~FW2002.ARE~ ~override~ // TotSC: Isle of Balduran (South): Kaishas' Hut
				~FW2003.ARE~ ~override~ // TotSC: Isle of Balduran (South): Large Hut 3
				~FW2004.ARE~ ~override~ // TotSC: Isle of Balduran (South): Large Hut 2
				~FW2005.ARE~ ~override~ // TotSC: Isle of Balduran (South): Large Hut 4
				~FW2006.ARE~ ~override~ // TotSC: Isle of Balduran (South): Large Hut 1
				~FW2007.ARE~ ~override~ // TotSC: Isle of Balduran (South): Harbor Hut
				~FW2008.ARE~ ~override~ // TotSC: Isle of Balduran (South): Store Hut 2
				~FW2009.ARE~ ~override~ // TotSC: Isle of Balduran (South): Store Hut 1
				~FW2010.ARE~ ~override~ // TotSC: Isle of Balduran (South): Store Hut 4
				~FW2011.ARE~ ~override~ // TotSC: Isle of Balduran (South): Store Hut 3
				~FW2012.ARE~ ~override~ // TotSC: Werewolf Caverns

//we add here

//Note: we don't do file name matching in Tutu because script and area file name only match in number not in letters.

//this gets every area that has an existing script

//we read old script ref
 READ_ASCII 0x94 ~old_area_script~

//we see if old script ref exists
 PATCH_IF (FILE_EXISTS_IN_GAME ~%old_area_script%.bcs~) BEGIN

//we go ahead and make the change in the area file
  WRITE_EVALUATED_ASCII 0x95 ~%SOURCE_RES%~ #7 // area script
  WRITE_ASCII 0x94 ~_AR~ #3 // area script

//we read the new area script ref
  READ_ASCII 0x94 ~new_area_script~

//we copy the old area script ref into the new area script ref
  INNER_ACTION BEGIN
   COPY_EXISTING ~%old_area_script%.bcs~ ~override/%new_area_script%.bcs~
  END
 END ELSE BEGIN

//we go back to original here

//this gets every area that does not have an existing script
  WRITE_EVALUATED_ASCII 0x95 ~%SOURCE_RES%~ #7 // area script
  WRITE_ASCII 0x94 ~_AR~ #3 // area script
 END
 BUT_ONLY_IF_IT_CHANGES
END

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm

#18 jastey

    Titleless

  • Gibberlings
  • 4769 posts
  • Gender:Female
  • Location:Germany

Posted 15 September 2008 - 09:59 PM

OK, I'll try to understand it, but I was hoping you'd show me the changed BG1 area patching as used in the tutorial.

#19 jastey

    Titleless

  • Gibberlings
  • 4769 posts
  • Gender:Female
  • Location:Germany

Posted 16 September 2008 - 11:29 AM

View Postplainab, on Sep 6 2008, 12:41 AM, said:

BUT_IF_ONLY_IT_CHANGES
What is the difference between "BUT_IF_ONLY_IT_CHANGES" and "BUT_ONLY_IF_IT_CHANGES" (the latter I am using)?

#20 jastey

    Titleless

  • Gibberlings
  • 4769 posts
  • Gender:Female
  • Location:Germany

Posted 16 September 2008 - 11:36 AM

I think I see clearer now. Do I replace in the original tutorial script
COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~ // for all areas in game
WRITE_EVALUATED_ASCII 0x94 ~%SOURCE_RES%~ // sets name of scripts in ARE files
READ_ASCII 0x94 ~Script_Name~

With the new
COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~ // for all areas in game
SPRINT area_name ~%SOURCE_RES%~
//we read old script ref
READ_ASCII 0x94 ~old_script_name~
//go ahead and write because matching names will still match
WRITE_EVALUATED_ASCII 0x94 ~%SOURCE_RES%~
//see if odd named script file exists, if so copy to correct name.
INNER_ACTION BEGIN
ACTION_IF !(~%old_script_name%~ STRING_EQUAL_CASE ~%area_name%~)
		  AND (FILE_EXISTS_IN_GAME ~%old_script_name%.bcs~) THEN BEGIN
COPY_EXISTING ~%old_script_name%.bcs~ ~override/%area_name%.bcs~
END
END
//read new for rest of patch
READ_ASCII 0x94 ~script_name~

and everything else stays the same?

#21 Zed Nocear

  • Members
  • 30 posts
  • Gender:Male

Posted 16 September 2008 - 12:55 PM

I supposed, your proposal was good. But in situation, when more then one area use the same script, as you describe above, it suffice not.

If AR0507, AR0508, AR0509 and AR0510 ALL use AR0507.bcs in your proposal of code for AR0508.ARE AR0508.BCS will be copied allready from patched AR0507.BCS.

Area Scripts renaming and patching must go on in two separate passes:

COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~ // for all areas in game
SPRINT area_name ~%SOURCE_RES%~
//we read old script ref
READ_ASCII 0x94 ~old_script_name~
//go ahead and write because matching names will still match
WRITE_EVALUATED_ASCII 0x94 ~%SOURCE_RES%~
//see if odd named script file exists, if so copy to correct name.
INNER_ACTION BEGIN
ACTION_IF !(~%old_script_name%~ STRING_EQUAL_CASE ~%area_name%~)
		  AND (FILE_EXISTS_IN_GAME ~%old_script_name%.bcs~) THEN BEGIN
COPY_EXISTING ~%old_script_name%.bcs~ ~override/%area_name%.bcs~
END
END
BUT_ONLY_IF_IT_CHANGES

COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~ // for all areas in game again
READ_ASCII 0x94 ~script_name~
//rest of patch...


#22 plainab

    Sasha al'Therin

  • Members
  • 1717 posts
  • Gender:Male
  • Location:Lost on the Sword Coast

Posted 16 September 2008 - 02:33 PM

Now I'm confused. Why in two passes? Can you not do it in one pass even if 4 areas use the same script?
I don't see how ar508.bcs would end up as a copy of ar507.bcs
I did some tweaking just to make sure, but I still don't where you are getting the next file to be a copy of the previous file.
I included some prints so that when it is actually ran we can use it to debug and see what happens. Note: prints will be placed in the debug file.
COPY_EXISTING_REGEXP GLOB ~.*\.are~ ~override~
PATCH_PRINT ~Begin new area file...~
SPRINT area_name ~%SOURCE_RES%~
READ_ASCII 0x94 ~old_area_script~
PATCH_PRINT ~%area_name% has script: %old_area_script%
//modify area files with name matching the current existing script OR current assigned script
PATCH_IF (~%old_area_script%~ STRING_EQUAL_CASE %area_name%) BEGIN
PATCH_PRINT ~%area_name% = %old_area_script%~
//At the moment we don't need anything here
END
//modify area files with name not matching the current existing script
PATCH_IF (FILE_EXISTS_IN_GAME ~%old_area_script%.bcs~)
	 AND !(~%old_area_script%~ STRING_EQUAL_CASE %area_name%) BEGIN
PATCH_PRINT ~%area_name% != %old_area_script%~
 WRITE_EVALUATED_ASCII 0x94 ~%area_name%~ 
 READ_ASCII 0x94 ~new_area_script~
 PATCH_PRINT ~Changed area script from %old_area_script% to %new_area_script%~
 INNER_ACTION BEGIN
  COPY_EXISTING ~%old_area_script%.bcs~ ~override/%new_area_script%~
  PRINT ~copied %old_area_script%.bcs to %new_area_script%.bcs~
 END
//At the moment we don't need anything else here
END
//modify if the assigned script name does not exist
PATCH_IF !(FILE_EXISTS_IN_GAME ~%old_area_script%.bcs~) BEGIN
PATCH_PRINT ~%old_area_script%.bcs does not exist~
 WRITE_EVALUATED_ASCII 0x94 ~%area_name%~ 
PATCH_PRINT ~Changed area script to %area_name%~
//At the moment we don't need anything else here
END
//re-read the area script ref to do all the patches
READ_ASCII 0x94 ~final_area_script~
PATCH_PRINT ~Final area script = %final_area_script%~
//do patches based on the variable 'final_area_script' for the script ref
// and the variable 'area_name' for the area file name rather than SOURCE_RES
//
PATCH_PRINT ~Done with this area file~
BUT_ONLY_IF_IT_CHANGES


Quote

What is the difference between "BUT_IF_ONLY_IT_CHANGES" and "BUT_ONLY_IF_IT_CHANGES" (the latter I am using)?
A mistake on my part, for some reason I keep wanting to write it that way...
My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm

#23 Zed Nocear

  • Members
  • 30 posts
  • Gender:Male

Posted 17 September 2008 - 04:40 AM

Your part of code is good, but I think about the whole PATCH-code after:
COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~
The error depends on order the areas taken to work on.

For example one-pass solution:

First AR0507.ARE is parsing. Area script is set to AR0507.BCS.
The names of area and script are equal and script is not copied.
Next in the same pass AR0507.BCS is modified to extend for AreaTypeEmulation.

Now AR0508.ARE is parsing. Area script is set to AR0507.BCS.
The names of area and script are not equal and script is copied from AR0507.BCS to AR0508.BCS.
But AR0507.BCS has allready extension for AreaTypeEmulation, AR0508.BCS will have also. Therefore AR0508.BCS will be not modified by the code (NOT FILE_CONTAINS_EVALUATED(~%Script_Name%.BCS~ ~Z!EmulAreaCheck~)) and will have AreaTypeEmulation with data for AR0507.ARE.

The same with AR0509.ARE and AR0510.ARE.

The simple solution to avoid this is make the renaming of area-scripts and the patching in two separate passes. Is it not clear? Maybe you will find a trick to make it in one pass, but it is not necessary.

Edited by Zed Nocear, 17 September 2008 - 04:41 AM.


#24 jastey

    Titleless

  • Gibberlings
  • 4769 posts
  • Gender:Female
  • Location:Germany

Posted 17 September 2008 - 12:29 PM

Neither my above, nor Zed Nocear's second proposal actually does the EmulAreaCheck Patching. It does create the AR0508.bcs etc. though. :)

I'll try plainab's suggestion, too, as soon as I figure out how I'll have to integrate it.

#25 plainab

    Sasha al'Therin

  • Members
  • 1717 posts
  • Gender:Male
  • Location:Lost on the Sword Coast

Posted 17 September 2008 - 01:38 PM

Quote

The names of area and script are not equal and script is copied from AR0507.BCS to AR0508.BCS.
But AR0507.BCS has allready extension for AreaTypeEmulation, AR0508.BCS will have also.
I understand now. I took the whole thing into consideration and I believe that this should be what Jastey is looking for. IF it passes muster, comment it like crazy and use it as the tutorial... ELSE do your two pass thing.
/* BG Fixpack will make sure these get taken care of
COPY_EXISTING ~AR2612.ARE~ ~override~ //two areas in BG1 have wrong flag "Outdoor"
~AR3317.ARE~ ~override~
WRITE_BYTE 0x48 0
*/

COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~ // for all areas in game
 SPRINT area_name ~%SOURCE_RES%~
 READ_ASCII 0x94 ~old_area_script~
//modify area files with name not matching the current existing script
 PATCH_IF (FILE_EXISTS_IN_GAME ~%old_area_script%.bcs~)
	 AND !(~%old_area_script%~ STRING_EQUAL_CASE %area_name%) BEGIN
  WRITE_EVALUATED_ASCII 0x94 ~%area_name%~
  READ_ASCII 0x94 ~new_area_script~
  INNER_ACTION BEGIN
   COPY_EXISTING ~%old_area_script%.bcs~ ~override/%new_area_script%~
  END
 END
//modify if the assigned script name does not exist
 PATCH_IF !(FILE_EXISTS_IN_GAME ~%old_area_script%.bcs~) BEGIN
  WRITE_EVALUATED_ASCII 0x94 ~%area_name%~
 END
//re-read the area script ref to do all the patches
 READ_ASCII 0x94 ~final_area_script~
//if we haven't done this before, we do it else we skip it. OR if it's been done by a previous mod.
 PATCH_IF (NOT FILE_CONTAINS_EVALUATED(~%final_area_script%.BCS~ ~Z!EmulAreaCheck~)) BEGIN
/*read script ref again because the rest of the tutorial uses this variable and it's just easier to read again than to change everything else */
  READ_ASCII 0x94 ~Script_Name~
  PATCH_IF (~%SOURCE_RES%~ STRING_MATCHES_REGEXP ~AR[0-9][0-9][0-9][0-9]~) = 0
  THEN BEGIN READ_ASCII 0x96 ~Area_Number~ (4) END // number for areas named "ARxxxx", all in official game
  ELSE BEGIN READ_ASCII 0x7 ~Area_Number~ (1) END // "0" for areas not named "ARxxxx", some from unofficial mods
  READ_BYTE 0x48 ~Area_Flags~
  INNER_ACTION BEGIN
   ACTION_IF (NOT FILE_CONTAINS_EVALUATED(~%Script_Name%.BCS~ ~EmulAreaCheck~)) //modification is not allready installed
		 AND (FILE_CONTAINS_EVALUATED(~MASTAREA.2DA~ ~%Script_Name%~)) // area is "master area" as in mastarea.2DA
   THEN BEGIN
	COPY ~C#AjantisRomance_BG1/Scripts/EmulAreaCheck1.BAF~ ~Override/temp.BAF~
	 REPLACE_TEXTUALLY ~Variable_Number~ ~%Area_Number%~
	 REPLACE_TEXTUALLY ~Variable_Flags~ ~%Area_Flags%~
	 PATCH_IF ((~%Area_Flags%~ BAND 0b1) = 0b1)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~0~ END
	 PATCH_IF ((~%Area_Flags%~ BAND 0b1000) = 0b1000)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~0~ END
	 PATCH_IF ((~%Area_Flags%~ BAND 0b10000) = 0b10000)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~0~ END
	 PATCH_IF ((~%Area_Flags%~ BAND 0b100000) = 0b100000)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~0~ END
//Variables for flags Wather, Day/Night, Extended Night and Can't Rest were not added, because of useless.
	EXTEND_TOP ~%Script_Name%.BCS~ ~Override/temp.BAF~
   END
   ACTION_IF (NOT FILE_CONTAINS_EVALUATED(~%Script_Name%.BCS~ ~EmulAreaCheck~)) //modification is not allready installed
		 AND (NOT FILE_CONTAINS_EVALUATED(~MASTAREA.2DA~ ~%Script_Name%~)) //area is not "master area"
   THEN BEGIN
	COPY ~C#AjantisRomance_BG1/Scripts/EmulAreaCheck.BAF~ ~Override/temp.BAF~
	 REPLACE_TEXTUALLY ~Variable_Number~ ~%Area_Number%~
	 REPLACE_TEXTUALLY ~Variable_Flags~ ~%Area_Flags%~
	 PATCH_IF ((~%Area_Flags%~ BAND 0b1) = 0b1)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~0~ END
	 PATCH_IF ((~%Area_Flags%~ BAND 0b1000) = 0b1000)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~0~ END
	 PATCH_IF ((~%Area_Flags%~ BAND 0b10000) = 0b10000)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~0~ END
	 PATCH_IF ((~%Area_Flags%~ BAND 0b100000) = 0b100000)
	 THEN BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~1~ END
	 ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~0~ END
//Variables for flags Weather, Day/Night, Extended Night and Can't Rest were not added, because of useless.
	EXTEND_TOP ~%Script_Name%.BCS~ ~Override/temp.BAF~
   END
  END
 END
BUT_ONLY_IF_IT_CHANGES

Quote

I'll try plainab's suggestion, too, as soon as I figure out how I'll have to integrate it.
No need just try this one and let us know if it works... Pay close attention to the 4 totsc areas that use the same script...
My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm

#26 Zed Nocear

  • Members
  • 30 posts
  • Gender:Male

Posted 18 September 2008 - 11:30 AM

View Postjastey, on Sep 17 2008, 10:29 PM, said:

Neither my above, nor Zed Nocear's second proposal actually does the EmulAreaCheck Patching. It does create the AR0508.bcs etc. though. :)

I'll try plainab's suggestion, too, as soon as I figure out how I'll have to integrate it.

I have installed and tested my solution in clean BG1+TotSC and it's work good. Areas AR0507.ARE, AR0508.ARE, AR0509.ARE and AR0510.ARE have adequate script-refferences and AR0507.BCS, AR0508.BCS, AR0509.BCS and AR0510.BCS have proper EmulAreaCheck content.

Once again my proposal of whole code:
COPY_EXISTING  ~AR2612.ARE~ ~override~
			   ~AR3317.ARE~ ~override~
		 WRITE_BYTE 0x48 0
		 BUT_ONLY_IF_IT_CHANGES

COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~
  SPRINT area_name ~%SOURCE_RES%~
  READ_ASCII 0x94 ~old_script_name~
  WRITE_EVALUATED_ASCII 0x94 ~%SOURCE_RES%~
  INNER_ACTION BEGIN 
	ACTION_IF !(~%old_script_name%~ STRING_EQUAL_CASE ~%area_name%~)
		  AND (FILE_EXISTS_IN_GAME ~%old_script_name%.bcs~)
	  THEN BEGIN COPY_EXISTING ~%old_script_name%.bcs~ ~override/%area_name%.bcs~ END
  END
  BUT_ONLY_IF_IT_CHANGES

COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~
  READ_ASCII 0x94 ~Script_Name~
  PATCH_IF (~%SOURCE_RES%~ STRING_MATCHES_REGEXP ~AR[0-9][0-9][0-9][0-9]~) = 0
	THEN BEGIN READ_ASCII 0x96 ~Area_Number~ (4) END
	ELSE BEGIN READ_ASCII 0x7 ~Area_Number~ (1) END
  READ_BYTE 0x48 ~Area_Flags~
  INNER_ACTION BEGIN
	ACTION_IF (NOT FILE_CONTAINS_EVALUATED(~%Script_Name%.BCS~ ~Z!EmulAreaCheck~))
		  AND (FILE_CONTAINS_EVALUATED(~MASTAREA.2DA~ ~%Script_Name%~))
	  THEN BEGIN
		COPY ~TWM_Pack/99AREcheck/Z!EmulAreaCheck1.BAF~ ~Override/temp.BAF~
		  REPLACE_TEXTUALLY ~Variable_Number~ ~%Area_Number%~
		  REPLACE_TEXTUALLY ~Variable_Flags~ ~%Area_Flags%~
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1) = 0b1)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1000) = 0b1000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b10000) = 0b10000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b100000) = 0b100000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~0~ END
		EXTEND_TOP ~%Script_Name%.BCS~ ~Override/temp.BAF~
	  END
	ACTION_IF (NOT FILE_CONTAINS_EVALUATED(~%Script_Name%.BCS~ ~Z!EmulAreaCheck~))
		  AND (NOT FILE_CONTAINS_EVALUATED(~MASTAREA.2DA~ ~%Script_Name%~))
	  THEN BEGIN
		COPY ~TWM_Pack/99AREcheck/Z!EmulAreaCheck.BAF~ ~Override/temp.BAF~
		  REPLACE_TEXTUALLY ~Variable_Number~ ~%Area_Number%~
		  REPLACE_TEXTUALLY ~Variable_Flags~ ~%Area_Flags%~
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1) = 0b1)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1000) = 0b1000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b10000) = 0b10000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b100000) = 0b100000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~0~ END
		EXTEND_TOP ~%Script_Name%.BCS~ ~Override/temp.BAF~
	  END
  END
  BUT_ONLY_IF_IT_CHANGES

Edited by Zed Nocear, 18 September 2008 - 11:34 AM.


#27 jastey

    Titleless

  • Gibberlings
  • 4769 posts
  • Gender:Female
  • Location:Germany

Posted 19 September 2008 - 12:03 PM

View PostZed Nocear, on Sep 18 2008, 09:30 PM, said:

Once again my proposal of whole code:
Yes, now it is working for me, too. Cool!

EDIT: Tutorial is updated.

Edited by jastey, 19 September 2008 - 12:13 PM.


#28 jastey

    Titleless

  • Gibberlings
  • 4769 posts
  • Gender:Female
  • Location:Germany

Posted 22 December 2008 - 02:14 AM

Tutorial updated: Added Zed's prefix Z! to the script names for the AreaCheck simulation. Thank you Mike1072 for pointing it out!

#29 Zed Nocear

  • Members
  • 30 posts
  • Gender:Male

Posted 17 November 2009 - 12:15 PM

I develop a "second generation" of all three BG1-trigger-simulations.

1. Detection of AreaType and simulating AreaCheck()

New versions of scripts for patching area-scripts are simpler, shorter, and last but not least - never on non-master-areas variables become value of master-area (with trigger "Delay(5)" the disadvantage was, that one script-pass for 5 sec. variables get value from master-area).

Z!EmulAreaCheck1.BAF for master-areas:
IF
	!Global("Z!EmulAreaCheck","GLOBAL",Variable_Number)
	!GlobalTimerNotExpired("Z!EmulAreaNotMaster","GLOBAL")
	ActionListEmpty()
THEN
	RESPONSE #100
		SetGlobal("Z!EmulAreaCheck","GLOBAL",Variable_Number)
		SetGlobal("Z!LastMasterArea","GLOBAL",Variable_Number)
END

IF
	!Global("Z!EmulAreaType","GLOBAL",Variable_Flags)
	!GlobalTimerNotExpired("Z!EmulAreaNotMaster","GLOBAL")
	ActionListEmpty()
THEN
	RESPONSE #100
		SetGlobal("Z!EmulAreaType","GLOBAL",Variable_Flags)
		SetGlobal("Z!EmulAreaOutdoor","GLOBAL",Variable_Outdoor)
		SetGlobal("Z!EmulAreaCity","GLOBAL",Variable_City)
		SetGlobal("Z!EmulAreaForest","GLOBAL",Variable_Forest)
		SetGlobal("Z!EmulAreaDungeon","GLOBAL",Variable_Dungeon)
END
Z!EmulAreaCheck.BAF for non-master-areas:
IF
	Delay(1)
	ActionListEmpty()
THEN
	RESPONSE #100
		SetGlobal("Z!EmulAreaCheck","GLOBAL",Variable_Number)
		SetGlobal("Z!EmulAreaType","GLOBAL",Variable_Flags)
		SetGlobal("Z!EmulAreaOutdoor","GLOBAL",Variable_Outdoor)
		SetGlobal("Z!EmulAreaCity","GLOBAL",Variable_City)
		SetGlobal("Z!EmulAreaForest","GLOBAL",Variable_Forest)
		SetGlobal("Z!EmulAreaDungeon","GLOBAL",Variable_Dungeon)
		SetGlobalTimer("Z!EmulAreaNotMaster","GLOBAL",3)
END
In TP2-code in two places shoud be EXTEND_BOTTOM instead EXTEND_TOP:
COPY_EXISTING  ~AR2612.ARE~ ~override~ //two areas in BG1 have wrong flag "Outdoor"
			   ~AR3317.ARE~ ~override~
		 WRITE_BYTE 0x48 0
		 BUT_ONLY_IF_IT_CHANGES

COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~ // for all areas in game
  SPRINT area_name ~%SOURCE_RES%~
  READ_ASCII 0x94 ~old_script_name~
  WRITE_EVALUATED_ASCII 0x94 ~%SOURCE_RES%~
  INNER_ACTION BEGIN
	ACTION_IF !(~%old_script_name%~ STRING_EQUAL_CASE ~%area_name%~)
		  AND (FILE_EXISTS_IN_GAME ~%old_script_name%.bcs~)
	  THEN BEGIN COPY_EXISTING ~%old_script_name%.bcs~ ~override/%area_name%.bcs~ END
  END
  BUT_ONLY_IF_IT_CHANGES

COPY_EXISTING_REGEXP GLOB ~.*\.ARE~ ~override~
  READ_ASCII 0x94 ~Script_Name~
  PATCH_IF (~%SOURCE_RES%~ STRING_MATCHES_REGEXP ~AR[0-9][0-9][0-9][0-9]~) = 0
	THEN BEGIN READ_ASCII 0x96 ~Area_Number~ (4) END
	ELSE BEGIN READ_ASCII 0x7 ~Area_Number~ (1) END
  READ_BYTE 0x48 ~Area_Flags~
  INNER_ACTION BEGIN
	ACTION_IF (NOT FILE_CONTAINS_EVALUATED(~%Script_Name%.BCS~ ~Z!EmulAreaCheck~))
		  AND (FILE_CONTAINS_EVALUATED(~MASTAREA.2DA~ ~%Script_Name%~)) // area is  master area" as in mastarea.2DA
	  THEN BEGIN
		COPY ~TWM_Pack/99AREcheck/Z!EmulAreaCheck1.BAF~ ~Override/temp.BAF~
		  REPLACE_TEXTUALLY ~Variable_Number~ ~%Area_Number%~
		  REPLACE_TEXTUALLY ~Variable_Flags~ ~%Area_Flags%~
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1) = 0b1)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1000) = 0b1000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b10000) = 0b10000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b100000) = 0b100000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~0~ END
		EXTEND_BOTTOM ~%Script_Name%.BCS~ ~Override/temp.BAF~
	  END
	ACTION_IF (NOT FILE_CONTAINS_EVALUATED(~%Script_Name%.BCS~ ~Z!EmulAreaCheck~))
		  AND (NOT FILE_CONTAINS_EVALUATED(~MASTAREA.2DA~ ~%Script_Name%~)) //area is not "master area"
	  THEN BEGIN
		COPY ~TWM_Pack/99AREcheck/Z!EmulAreaCheck.BAF~ ~Override/temp.BAF~
		  REPLACE_TEXTUALLY ~Variable_Number~ ~%Area_Number%~
		  REPLACE_TEXTUALLY ~Variable_Flags~ ~%Area_Flags%~
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1) = 0b1)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Outdoor~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b1000) = 0b1000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_City~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b10000) = 0b10000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Forest~ ~0~ END
		  PATCH_IF ((~%Area_Flags%~ BAND 0b100000) = 0b100000)
			THEN BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~1~ END
			ELSE BEGIN REPLACE_TEXTUALLY ~Variable_Dungeon~ ~0~ END
		EXTEND_BOTTOM ~%Script_Name%.BCS~ ~Override/temp.BAF~
	  END
  END
  BUT_ONLY_IF_IT_CHANGES
2. Detection of "Party rested"

This is the biggest revolution. Instead of dummy spell "(yawn)" I have used stat-parameter FATIGUE. This solution is invisible for player. No more (yawn) after every rest, and no more (yawn) as "favorite spell". The new script patching dplayer3.BCS has only one block:
//dplayer3_add.baf

IF
	CheckStat(Player1,0,FATIGUE)
THEN
	RESPONSE #100
		ApplySpellRES("Z!FATIG1",Player1)
		IncrementGlobal("X#AjantisRomanceRestCounter","GLOBAL",1)
		SetGlobalTimer("X#AjantisRomanceRestAfterTimer","GLOBAL",30)
END
The spell Z!FATIG1.SPL sets parameter FATIGUE on value 1.
The tp2 section in AjantisBG1 mod should look like:
APPEND ~action.ids~ ~160 ApplySpellRES(S:ResRef*,O:Target*)~	   UNLESS ~ApplySpellRES~

ACTION_IF (FILE_CONTAINS_EVALUATED (~dplayer3.BCS~ ~"Z!FATIG1"~))
	THEN BEGIN
		COPY_EXISTING ~dplayer3.BCS~ ~override~
			DECOMPILE_BCS_TO_BAF
			REPLACE_TEXTUALLY ~ApplySpellRES("Z!FATIG1",Player1)~
											 ~ApplySpellRES("Z!FATIG1",Player1)
												IncrementGlobal("X#AjantisRomanceRestCounter","GLOBAL",2)
											   SetGlobalTimer("X#AjantisRomanceRestAfterTimer","GLOBAL",30)~
			COMPILE_BAF_TO_BCS
	END
	ELSE BEGIN
		EXTEND_TOP ~dplayer3.BCS~ ~C#AjantisRomance_BG1/TriggerSimulations/dplayer3_add.BAF~
		COPY ~TWM_Pack/00RESTcheck/Z!FATIG1.SPL~ ~override~
	END
3. Simulating CombatCounter()

Either never version of script "CombatTimer_add.BAF", that does not break an action of scripted party-member, if player commands to attack any creature:
IF
	Global("Z!EnemyAlreadySeen","LOCALS",0)
	InParty(Myself)
	See([ENEMY])
	ActionListEmpty()
THEN
	RESPONSE #100
		SetGlobal("Z!EnemyAlreadySeen","LOCALS",1)
END

IF
	Global("Z!EnemyAlreadySeen","LOCALS",0)
	InParty(Myself)
	Died([ENEMY])
THEN
	RESPONSE #100
		SetGlobal("Z!EnemyAlreadySeen","LOCALS",1)
END

IF
	Global("Z!EnemyAlreadySeen","LOCALS",1) 
	InParty(Myself)
	!See([ENEMY])
THEN
	RESPONSE #100
		SetGlobal("Z!EnemyAlreadySeen","LOCALS",0) 
		SetGlobalTimer("Z!EnemySeenPeriod30","GLOBAL",30) //half minute, five rounds in the game
		SetGlobalTimer("Z!EnemySeenPeriod60","GLOBAL",60) //one minute, ten rounds (one tour) in the game
		SetGlobalTimer("Z!EnemySeenPeriod150","GLOBAL",150) //real 2.5 minutes, half an hour in the game
		SetGlobalTimer("Z!EnemySeenPeriod900","GLOBAL",900) // three hours in the game
		SetGlobalTimer("Z!EnemySeenPeriod7200","GLOBAL",7200) // 24 hours in the game
END

Edited by Zed Nocear, 17 March 2010 - 09:54 AM.


#30 Zed Nocear

  • Members
  • 30 posts
  • Gender:Male

Posted 19 November 2009 - 03:49 AM

Because of unexpected behavior of "Continue()" in BG1 and BG1-TotSC:
http://forums.gibber...showtopic=15925
I must change solution for AreaCheck and AreaType simulation once again. Theoretically the best solution is add the trigger "!OnCreation" to the blocks, but it doesn't work ("!OnCreation" is always false in BG1).
Therefore I have simply removed "Continue()" from all blocks and added the code to the bottom of area's scripts (EXTEND_BOTTOM instead EXTEND_TOP in TP2-code). The only danger is trigger "True()" in last block of primary scripts, but in original BG1+TotSC it exists only once in AR0516.BCS and this is not harmful because the script contains also Continue() with its buggy behavior in BG1.


Maybe it could be also changed in BG1 Tweaks Mod?

EDIT: There was an error in new method of detection of "Party rested", that causes incompatibility between many mods using this method. In TP2-code instead:
ACTION_IF (FILE_CONTAINS_EVALUATED (~dplayer3.BCS~ ~ApplySpellRES("Z!FATIG1",Player1)~))
shoud be:
ACTION_IF (FILE_CONTAINS_EVALUATED (~dplayer3.BCS~ ~"Z!FATIG1"~))

The post above was edited with this two mentioned issues.

Edited by Zed Nocear, 17 March 2010 - 10:07 AM.





Reply to this topic



  


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users


  • Yahoo