PDA

View Full Version : Header to Check ZC Version



ZoriaRPG
11-30-2015, 02:14 AM
I am not yet ready to commit this to the script database on PZC, but for all of you who want a way to check the version Zelda Classic that a player is using, by script, to modify effects, you may try this:

Package Update:
01-DEC-2015, v 0.6.1
Fixed one code typo ( Version[ZC_VERSION], was erroneously typed as Version[Version] ), added function ForceUpdate() and constants for it. Cleaned up some comments, and rearranged initial file details/credits/notes. Added an additional header sub-version that requires no global variables. I may integrate these at some point, but I'd prefer not to do that.

03-DEC-2015, v0.6.3
Fixed a bug resetting the value of Link->Jump.

03-DEC-2015, v0.6.4
Modified function ForceUpdate, and added ForceUpdate(bool specific)

-=SPOILER=-

File: FIX_CheckZC_Version_0.6.4.zs

////////////////////////////
/// ZC Version Detecting ///
/// v0.6.4 ///
/// 3rd December, 2015 ///
/// By: ZoriaRPG ///
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Note: The ZC Dev Staff will *never* support this. Provided as-is, with limited supprort by author. ///
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Crediting: /// Testing: /// Discussion: /// Misc. / Feedback ///
/// Saffith, Information /// Epad /// Dimentio /// Avataro ///
/// Saffith, Gen. Assist /// Moosh /// Evan /// elektriktoad ///
/// /// /// Grayswandir /// Tamamo ///
/// /// /// Moosh /// SUCCESSOR ///
/// /// /// TheBlueTophat /// ///
/// /// /// ywkls /// ///
//////////////////////////////////////////////////////////////////////////////////////////////////////////

//Prime Settings
const int VERSION_CHECK_CANNOT_USE_GLOBAL_VARIABLES = 0;

//Version array, and constants for its indices.
float Version[20]={250,0,0,0,0,0,0}; //Assume 2.50.0 first.
const int ZC_VERSION = 0; //Index 0, to hold the version.
const int DETECT_250_1_PASS1 = 1; //Holds 2.50.1 check passes.
const int DETECT_250_1_PASS2 = 2; //...
const int DETECT_250_2_JUMP = 3; //Detect 2.50.2 from Link->Jump values.
const int VERSION_CLEANUP = 4; //Flag that we're done.

//Constants for the temporary weapon used to detect 2,50.1.
const int DETECT_250_1_WEAPON_INDEX = 15; //The Misc[] index to check for the 2.50.1 validation.
const int DETECT_250_1_WEAPON_ARB_VAL = 1023.9187; //A sufficiently arbitrary value to store in the index.

const int DEBUG_VERSION_FUNCTIONS = 1; //Set to '1' if you want to enable debugging.
const int VERSION_ENABLE_RECHECK = 1; //Set to '1' to enable re-checking between saving. Set to '0' to disable.

//////////////////////
/// User Functions ///
//////////////////////


//Returns the verion of ZC that the player is using as ( 250.0, 250.1, or 250.2 ).
float Version(){
return Version[ZC_VERSION];
}

//Boolean for checking the ZC Version.
bool Version(float vers){
return Version[ZC_VERSION] == vers;
}
//Call as :
//if ( Version(250.2) )
//or
//if ( Version(250.0) )

//Replacement for InvertedCircle() in stdExtra.zh, that is compliant with this header.
//Draw an inverted circle (fill whole screen except circle)
void InvertedCircle(int bitmapID, int layer, int x, int y, int radius, int scale, int fillcolor){
Screen->SetRenderTarget(bitmapID); //Set the render target to the bitmap.
Screen->Rectangle(layer, 0, 0, 256, 176, fillcolor, 1, 0, 0, 0, true, 128); //Cover the screen
Screen->Circle(layer, x, y, radius, 0, scale, 0, 0, 0, true, 128); //Draw a transparent circle.
Screen->SetRenderTarget(RT_SCREEN); //Set the render target back to the screen.
if ( Version() < 250.2 ) Screen->DrawBitmap(layer, bitmapID, 0, 0, 256, 176, 0, 56, 256, 176, 0, true); //Draw the bitmap for 2.50.0/1
else Screen->DrawBitmap(layer, bitmapID, 0, 0, 256, 176, 0, 0, 256, 176, 0, true); //Draw the bitmap for 2.50.2
}


///////////////////////
/// Forced Updating ///
///////////////////////

const int UPDATE_ZC = 0; //Set to ID of message reading 'Please update to Zelda Classic v2.50.2 before playing.'
const int UPDATE_ZC_DMAP_MUSIC_ID = 0; //Set to an music file to play for the loading screen error.
const int UPDATE_ZC_SFX = 0; //Set to an error noise to play before displaying the UPDATE_ZC string, or changing the music.
const int ZC_MIN_VERSION = 250.2; //Set to the minimum version of ZC that you wish to enforce, using the format '250', '250.1', and '250.2'

//Call after Waitdraw();
void ForceUpdate(){
if ( Version() <= ZC_MIN_VERSION ) {
if ( UPDATE_ZC_SFX ) Game->PlaySound(UPDATE_ZC_SFX);
if ( UPDATE_ZC_DMAP_MUSIC_ID ) Game->PlayMIDI(UPDATE_ZC_DMAP_MUSIC_ID);
Screen->Message(UPDATE_ZC);
Game->End();
}
}

//Call after Waitdraw();
void ForceUpdate(bool specific){
if ( ( specific && Version() != ZC_MIN_VERSION ) || ( !specific && Version() <= ZC_MIN_VERSION ) ) {
if ( UPDATE_ZC_SFX ) Game->PlaySound(UPDATE_ZC_SFX);
if ( UPDATE_ZC_DMAP_MUSIC_ID ) Game->PlayMIDI(UPDATE_ZC_DMAP_MUSIC_ID);
Screen->Message(UPDATE_ZC);
Game->End();
}
}


////////////////////////
/// Global Functions ///
////////////////////////

////////////////////////
/// Check for 2.50.1 ///
////////////////////////

//Run before Waitdraw();
void Detect250_1_Phase1(){
if ( !Version[DETECT_250_1_PASS1] ) {
eweapon e = Screen->CreateEWeapon(EW_SCRIPT1); //Make an eweapon offscreen...
e->X = -32; //Set its position to be off-screen, so that 2.50.1 will remove it, and we can check against that.
e->Y = -32;
e->Misc[DETECT_250_1_WEAPON_INDEX] = DETECT_250_1_WEAPON_ARB_VAL; //Set an index so that we can look for it later.
e->CollDetection = false; //Turn off its CollDetection.
Version[DETECT_250_1_PASS1] = 1; //Mark that pass 1 is complete.
Waitframe(); //Wait one frame, to check if the pointer is removed.
}
}

//Run before Waitdraw(), before Detect250_2();
void Detect250_1_Phase2(){
bool detected250;
if ( Version[DETECT_250_1_PASS1] && !Version[DETECT_250_1_PASS2] ) { //Start pass 2.
for ( int q = 1; q <= Screen->NumEWeapons(); q++ ) { //Look for that eweapon.
eweapon e = Screen->LoadEWeapon(q);
if ( e->Misc[DETECT_250_1_WEAPON_INDEX] == DETECT_250_1_WEAPON_ARB_VAL ) { //by finding its index with our arbitrary value...
detected250 = true; //If it still exists after that one Waitframe, then it is 2.50.2, as it would have been removed.
}
}
Version[DETECT_250_1_PASS2] = 1; //Mark that we completed this pass, so that we never check again.
if ( !detected250 ) Version[ZC_VERSION] = 250.1; //If the weapon was not there, we didn't detect 2.50, so we must be using 2.50.1, or 2.50.2 with thie rule to remove them enabled.
}
}



/////////////////////////////
/// Then check for 2.50.2 ///
/////////////////////////////


//Detects if the return value for Link->Jump > 3.2 is correct (2.50.2).
void Detect250_2(){
if ( !Version[DETECT_250_2_JUMP] ) {
Version[DETECT_250_2_JUMP] = 1;
if ( Detect_250_2_Jump() == 10 ) Version[ZC_VERSION] = 250.2;
}
}

//Sets, and returns Link->Jump = 10;
float Detect_250_2_Jump(){
Link->Jump = 10;
return Link->Jump;
}

void Version_Check_Cleanup(){
if ( !Version[VERSION_CLEANUP] ) {
Version[VERSION_CLEANUP] = 1;
Link->Jump = 0;
}
}


//In the event that a user changes ZC versions between saves, we reset this, and re-check on continue.
void CheckVersionOnContinue(){
for ( int q = 1; q < SizeOfArray(Version); q++ ) Version[q] = 0;
}


////////////////////////////////////
/// Example Global Active Script ///
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Set up the functions in this header in your global active script, in the same manner as you see below. ///
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

global script CheckVersion{
void run(){
while(true){
Detect250_1_Phase1(); //Check to see if we are using 2.50.1...
Detect250_1_Phase2(); //2.50.1 Checking confirmed to work at this point (v0.4.2)
Detect250_2(); //Check for v2.50.2 ia Jumping mechanics.
Version_Check_Cleanup();
Waitdraw();
if ( DEBUG_VERSION_FUNCTIONS && Link->PressEx2 ) { //If debugging is on and Link presses Ex2
TraceNL(); //Put some useful traces in allegro.log.
Trace(Version[ZC_VERSION]);
}
Waitframe();
}
}
}

//Sample global OnContinue script to reset parameters, and recheck version each time that a game is loaded.
global script OnContinue{
void run(){
if ( VERSION_ENABLE_RECHECK ) CheckVersionOnContinue();
}
}





Note that this is intended to be used to run if/else codeblocks, with code variations that work differently, across ZC versions. For example, using Remove(n) on a lanmola, will crash 2.50.0, but not 2.50.1 and later; so this can give you a useful method of preventing game crashes, or other serious bugs, if a player uses an older ZC player for a quest intended for a newer release.

The problem with bitmap drawing is clearly the prime motivation for most people to use it, so a function for that is included.


Support Notes

Regarding support for these files:

I marked it, in the code, as something that the developers of Zelda Classic will never support. That is my intent, not theirs; as I do not want to make more work for them. Further, I'm ever going to contribute to the ZC engine in any fundamental way, I'd be making more work for myself. That's what I mean by 'limited support',

I'll provide LTS (long-term-support) for the main version of this package, for use with ZC versions 2.50.0, 2.50.1, and 2.50.2, but I won't commit to any support for future client (ZC) versions, nor will I support its use in any RC/Gamma build.

Tamamo
11-30-2015, 10:50 AM
ZoriaRPG

Sweet Jesus man, this is incredibly useful for cross version compatibility. Thank you so much for posting this here.

ZoriaRPG
11-30-2015, 09:07 PM
Not a problem at all. I had an idea on doing this in the past, and Saffith brought it up again, with the model that checking the position of scrolling (prior to, or after Waitdraw would be a valid method. While that is certainly the case, I moved to using Link->Jump, as checking for scrolling made it difficult to determine the version of a quest with 'No screen Scrolling' enabled; thus, side-scrolling games. Moosh asked about it, and I checked, and found that to be a problem. Thus, this should work with any quest, and any rule combination; but there may be circumstances that I did not foresee.

I should note that it is possible to integrate these checks into any quest that has at least one empty array index, so that a new save is not needed; but one empty index is the minimum requirement for that. The other values indices can be stored in Link->Misc, or a temporary eweapon, in the first frame of the game.

SUCCESSOR
12-01-2015, 01:01 AM
Honestly it makes more sense to just keep your quest up to date and debugged with the latest version of ZC. That is, the version all players should be using and the only relevant version of ZC.

Tamamo
12-01-2015, 01:28 AM
Certain features have been changed or removed. And upgrading is not always a good idea. I only use the most recent version cause I choose to do so.
Whether others choose to do so is there decision.

SUCCESSOR
12-01-2015, 02:38 AM
Certain features have been changed or removed. And upgrading is not always a good idea. I only use the most recent version cause I choose to do so.
Whether others choose to do so is there decision.

Certainly and they choose to have a faulty and outdated version.

ZoriaRPG
12-01-2015, 07:58 AM
Sub-Release w/o Global variable Requirements

For people who cannot update global variables, or arrays, here is a version that doesn't require any. This is ONLY intended for quests where a new save slot is not prudent, such as quests being play-tested, and support for it is far more limited.

File: FIX_CheckZC_Version_v0.6.1_2_NO_GLOBALS.zs
-=SPOILER=-

Support Notes for Sub-Release
I will support the 'non-global' sub-release only as much as is absolutely necessary, and only for projects completed before this was made available, or for games that are currently being play-tested.

3rd December, 2015: Both versions updated to correct a bug with resetting Link->Jump.