Jump to content

Zed Nocear's Trigger-Simulations for BG1


Recommended Posts

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:

Link to comment

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
Link to comment

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?

Link to comment

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...

Link to comment

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

 

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...
Link to comment

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.

Link to comment
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
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...
Link to comment
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
Link to comment

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

Link to comment

Because of unexpected behavior of "Continue()" in BG1 and BG1-TotSC:

http://forums.gibberlings3.net/index.php?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.

Link to comment

Archived

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

×
×
  • Create New...