Hello g_west,
After checking the code, there's indeed an extra subtlety in the way that side-quest is coded. The possibility to deposit the stones depends on a treasure variable instead of whether you have the stones themselves (the key items) in your inventory. Here are the scripts explained:
// The function to pick the Blue Stone, in Mountain Path/Trail (1551)
Function Zidane_15
// The following lines are the movement of Zidane crouching in front of the statue
TimedTurn( Angle(2679, 3842), 32 )
WaitTurn( )
SetStandAnimation( 2605 )
RunAnimation( 2606 )
WaitAnimation( )
// This replaces "[ITEM=0]" in the dialog right below by the name of the item 301 (Blue Stone)
SetTextVariable( 0, 301 )
// Display the dialog with two choices: "[ITEM=0] is set on the stone. Take it out Leave it alone"
WindowSync( 0, 0, 143 )
// The check "!GetDialogChoice" is synonymous to "GetDialogChoice == 0", eg. the player chose "Take it out"
if ( !GetDialogChoice ) {
Wait( 10 )
// Play the pickup sound
RunSoundCode3( 53248, 1340, 0, -128, 125 )
Wait( 10 )
}
// The following lines are the movement of Zidane standing up
SetStandAnimation( 200 )
RunAnimation( 2590 )
if ( !GetDialogChoice ) {
// So, this whole block executes only if the player chose "Take it out"
RunSoundCode3( 53248, 108, 0, -128, 125 )
// Give the key item "Blue Stone" to the player
AddItem( 301, 1 )
// Same as above: replaces "[ITEM=0]" by "Blue Stone" in the upcoming dialog
SetTextVariable( 0, 301 )
// Blocks with "if ( 1 )" always execute; it's a technical leftover to have a "if" block there and it could just have been "WindowSync( 7, 0, 58 )"
if ( 1 ) {
// Display the dialog "Received [ITEM=0]!"
WindowSync( 7, 0, 58 )
} else {
// That part is thus never executed and could be completly removed, it wouldn't make any difference
WindowSync( 7, 0, 59 )
}
// THERE, this is the added subtlety: this variable is a "treasure picked" memo.
// It is enabled once you picked the treasure and usually it
// (1) makes sure that you cannot pick the same treasure multiple times
// (2) counts toward the treasure rank score
// But there, it will also be used to allow the player to place the Blue Stone in the other statue
set VARL_GenBool_2865 = 1
}
WaitAnimation( )
return
// The function to place the different stones, in Mountain Path/Roots (1554)
// I'll write much less details there
Function Zidane_16
SetWalkTurnSpeed( 64 )
SetPathing( 0 )
SetWalkSpeed( 30 )
InitWalk( )
WalkXZY( 1445, 174, 1243 )
TimedTurn( 160, 32 )
WaitTurn( )
SetStandAnimation( 2605 )
RunAnimation( 2607 )
WaitAnimation( )
set VAR_LocUInt8_0 = 0
SetTextVariable( 0, 300 ) // Replace "[ITEM=0]" by "Red Stone"
SetTextVariable( 1, 301 ) // Replace "[ITEM=1]" by "Blue Stone"
SetTextVariable( 2, 302 ) // Replace "[ITEM=2]" by "Yellow Stone"
SetTextVariable( 3, 303 ) // Replace "[ITEM=3]" by "Green Stone"
// Here's the tricky part: the variable "VARL_GenUInt8_358" is tied to "VARL_GenBool_2865"
// "VARL_GenBool_2865" is actually the second bit in "VARL_GenUInt8_358"
// So "VARL_GenUInt8_358" is organised in 8 bits:
// The first 4 bytes are "have you picked up the stones"
// The last 4 bytes are "have you placed the stones"
// "VARL_GenUInt8_358 != 255" is "as long as there's a bit that is not set"
// ie. "as long as the side-quest isn't over"
// "( ( VARL_GenUInt8_358 & ( ~( VARL_GenUInt8_358 >> 4 ) ) ) & 15 )" is a complex formula that enables the different choices
// It enables a choice if the related item (1) has been picked and (2) has not been placed yet
while ( ( !VAR_LocUInt8_0 ) && ( VARL_GenUInt8_358 != 255 ) ) {
EnableDialogChoices( ( ( VARL_GenUInt8_358 & ( ~( VARL_GenUInt8_358 >> 4 ) ) ) & 15 ) | 16, 0 )
// "There’s a hole. Put [ITEM=0] in. Put [ITEM=1] in. Put [ITEM=2] in. Put [ITEM=3] in. Leave it alone"
WindowSync( 0, 0, 144 )
if ( GetDialogChoice == 4 ) {
// "Leave it alone" -> Exit the loop
set VAR_LocUInt8_0 = 1
} else {
// Update "VARL_GenUInt8_358" in order to say that the stone has been placed
set VARL_GenUInt8_358 |= ( 1 << ( GetDialogChoice + 4 ) )
SetTextVariable( 4, GetDialogChoice + 300 )
RemoveItem( GetDialogChoice + 300, 1 )
WindowSync( 0, 0, 145 ) // "Put in [ITEM=4]"
RunSoundCode3( 53248, 1339, 0, -128, 125 )
}
}
// etc...
if ( VARL_GenUInt8_358 == 255 ) {
WindowSync( 0, 128, 146 ) // "Zidane “Hmm? Something came out from the back...”"
if ( GetItemCount(229) < 99 ) { // Can carry another Moonstone
if ( VARL_GenBool_7381 == 0 ) {
RunSoundCode3( 53248, 108, 0, -128, 125 )
set VARL_GenBool_7381 = 1
SetTextVariable( 0, 229 )
AddItem( 229, 1 )
WindowSync( 7, 0, 58 ) // "Received Moonstone!"
}
} else {
WindowSync( 7, 0, 62 ) // "Cannot carry another Moonstone."
}
}
}
SetStandAnimation( 200 )
RunAnimation( 2591 )
WaitAnimation( )
TimedTurn( 32, 32 )
WaitTurn( )
InitWalk( )
WalkXZY( 1327, 170, 1228 )
MoveInstantXZY( 1327, 170, 1228 )
SetPathing( 1 )
return
In order to check for the presence of the items in the player's inventory instead of the treasure pickup flag, you can use the following code instead and use "allocate 2" in the local variable panel.
set VAR_LocUInt8_1 = GetItemCount(300)
set VAR_LocUInt8_1 |= (GetItemCount(301) << 1)
set VAR_LocUInt8_1 |= (GetItemCount(302) << 2)
set VAR_LocUInt8_1 |= (GetItemCount(303) << 3)
// Replace "VARL_GenUInt8_358 != 255" by "(VARL_GenUInt8_358 & 240) != 240"
while ( ( !VAR_LocUInt8_0 ) && ( (VARL_GenUInt8_358 & 240) != 240 ) ) {
EnableDialogChoices( ( ( VAR_LocUInt8_1 & ( ~( VARL_GenUInt8_358 >> 4 ) ) ) & 15 ) | 16, 0 )
// etc..
}
// Also for the reward that marks the end of the side-quest
if ( (VARL_GenUInt8_358 & 240) == 240 ) {
WindowSync( 0, 128, 146 ) // "Zidane “Hmm? Something came out from the back...”"
// etc...
}