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.