PDA

View Full Version : Assign Items to the Ex and R buttons



CJC
04-06-2009, 04:00 PM
You don't even have to reprogram them!

This script swaps the functions of the input buttons, so that when you input the button you want, the game uses the imput that that function is SUPPOSED to be attached to.


For instance, say you want to use the "B" button for the sword, but don't want to be able to assign any other items to that button. Normally you could not, you would just have to settle for placing items on both buttons. But now... we can tell the B button that when we press it, we're actually pressing the A button. In the player, if you press B, the A button action occurs.


Here's the code:


import "std.zh"

////global variables go here

int ButtonShuffle; //You'll have to define this at the global level,
//or this won't work.
//ButtonShuffle is used to tell the code that Link is performing an imput
//that the keyboard did not initiate. Here are the values for ButtonShuffle:
//ButtonShuffle == 1 is for the A button.
//ButtonShuffle == 2 is for the B button.
//ButtonShuffle == 3 is for the R button.
//ButtonShuffle == 4 is for the L button.
//ButtonShuffle == 5 is for the Ex1 button.
//ButtonShuffle == 6 is for the Ex2 button.
//ButtonShuffle == 7 is for the Ex3 button.
//ButtonShuffle == 8 is for the Ex4 button.
//ButtonShuffle == 9 is for the Start Button.
//ButtonShuffle == 10 is for InputUp. This is 10 + the Direction constant for facing up.
//ButtonShuffle == 11 is for InputDown. This is 10 + the Direction constant for facing down.
//ButtonShuffle == 12 is for InputLeft. This is 10 + the Direction constant for facing left.
//ButtonShuffle == 13 is for InputRight. This is 10 + the Direction constant for facing right.
//ButtonShuffle == 20 is for the Map Button.
//If you ever force the engine to use an input, through input = true, you
//will have to precede that line with ButtonShuffle = #, using the number
//for the forced button. This will make sense shortly.



global script onstart {
void run() {

////one time things go here
ButtonShuffle = 0;
while(true) {
if(Link->InputB && ButtonShuffle != 2){ //Checks if Link actually pressed the button
//or if this script simulated the press of that button. Necessary to avoid
//creating a loop.
ButtonShuffle = 1; //Sets the button truth to the button who's
//effect you want the B button to have
//For Bool ButtonTruth to function properly, you must have this
//kind of integer assignment above EVERY script-forced input.
//The number is 1, because the forced input is for A and "A"
//has an assigned number of 1 in the ButtonTruth.
Link->InputA = true; //Same as button truth, makes this button
//have that effect. To change the target button, change
//this line to the target button, and change the ButtonTruth
//number to that appropriate for the target button.
Link->InputB = false; //Disables the original function of this
//button.

//I've set the B button to function as "A", so I could dedicate
//"B" to the sword without recoding the sword script.
}
else if(Link->InputA && ButtonShuffle != 1){ //Checks if Link actually pressed the button
//or if this script simulated the press of that button.
ButtonShuffle = 3; //For each button who's function you change, you will
//also need to change the function of the target button. For example, if
//you wanted to swap B and A, you would have to use this code for both buttons
//and not just one. If you want B to act as A and A to act as something else,
//(in this case R), then you must also make R act as something else. Otherwise
//you will have two buttons with the same function, and one button who's
//function CANNOT be used, period.
Link->InputR = true; //I am making A function as "R" so I may
//attach an activate script to it later. My other scripts will
//still say "InputR", but in the player you will hit the "A" button
//to use that effect.
Link->InputA = false; //Disables the original function of this
//button.
}
else if(Link->InputR && ButtonShuffle != 3){ //Checks if link actually pressed the button
//or if this script simulated the press of that button.
ButtonShuffle = 2; //R will be the new B. Now each button with
//replaced function has a different button replacing ITS function.
Link->InputB = true;
Link->InputR = false;

//Players would press R to select items in the subscreen, and press R to use them
//with this script in place.
}
else{ButtonShuffle = 0;}
Waitframe();
}
}
////functions go here
}


It uses the Onstart global script setup (That can be found at PureZC). If you don't know what that is, I can provide it here too (On request). If you are combining this with another global script and using that template, then...


////global variables go here

int ButtonShuffle; //You'll have to define this at the global level,
//or this won't work.
//ButtonShuffle is used to tell the code that Link is performing an imput
//that the keyboard did not initiate. Here are the values for ButtonShuffle:
//ButtonShuffle == 1 is for the A button.
//ButtonShuffle == 2 is for the B button.
//ButtonShuffle == 3 is for the R button.
//ButtonShuffle == 4 is for the L button.
//ButtonShuffle == 5 is for the EX1 button.
//ButtonShuffle == 6 is for the EX2 button.
//ButtonShuffle == 7 is for the EX3 button.
//ButtonShuffle == 8 is for the EX4 button.
//ButtonShuffle == 9 is for the Start Button.
//ButtonShuffle == 10 is for InputUp. This is 10 + the Direction constant for facing up.
//ButtonShuffle == 11 is for InputDown. This is 10 + the Direction constant for facing down.
//ButtonShuffle == 12 is for InputLeft. This is 10 + the Direction constant for facing left.
//ButtonShuffle == 13 is for InputRight. This is 10 + the Direction constant for facing right.
//ButtonShuffle == 20 is for the Map Button.
//If you ever force the engine to use an input, through input = true, you
//will have to precede that line with ButtonShuffle = #, using the number
//for the forced button. This will make sense shortly.

goes before the global script starts.

And:


if(Link->InputB && ButtonShuffle != 2){ //Checks if Link actually pressed the button
//or if this script simulated the press of that button. Necessary to avoid
//creating a loop.
ButtonShuffle = 1; //Sets the button truth to the button who's
//effect you want the B button to have
//For Bool ButtonTruth to function properly, you must have this
//kind of integer assignment above EVERY script-forced input.
//The number is 1, because the forced input is for A and "A"
//has an assigned number of 1 in bool ButtonTruth.
Link->InputA = true; //Same as button truth, makes this button
//have that effect. To change the target button, change
//this line to the target button, and change the ButtonTruth
//number to that appropriate for the target button.
Link->InputB = false; //Disables the original function of this
//button.

//I've set the B button to function as "A", so I could dedicate
//"B" to the sword without recoding the sword script.
}
else if(Link->InputA && ButtonShuffle != 1){ //Checks if Link actually pressed the button
//or if this script simulated the press of that button.
ButtonShuffle = 3; //For each button who's function you change, you will
//also need to change the function of the target button. For example, if
//you wanted to swap B and A, you would have to use this code for both buttons
//and not just one. If you want B to act as A and A to act as something else,
//(in this case R), then you must also make R act as something else. Otherwise
//you will have two buttons with the same function, and one button who's
//function CANNOT be used, period.
Link->InputR = true; //I am making A function as "R" so I may
//attach an activate script to it later. My other scripts will
//still say "InputR", but in the player you will hit the "A" button
//to use that effect.
Link->InputA = false; //Disables the original function of this
//button.
}
else if(Link->InputR && ButtonShuffle != 3){ //Checks if link actually pressed the button
//or if this script simulated the press of that button.
ButtonShuffle = 2; //R will be the new B. Now each button with
//replaced function has a different button replacing ITS function.
Link->InputB = true;
Link->InputR = false;

//Players would press R to select items in the subscreen, and press R to use them
//with this script in place.
}
else{ButtonShuffle = 0;}

goes in your "While" loop.

I suppose I should explain how this works. The script works off the concept of ButtonTruth, which I attempted and failed to use as a bool and instead incorperated into the global section itself.

What's ButtonTruth? Well, the engine cannot tell the difference between whether the player presses the B button or the script does. In its eyes, Link->InputB = true means the player is holding down the button, even if you really are not.

So... to make the function work without having the program think you were resting your hand on the keyboard, I had to inject a variable to test whether you had infact pressed the button, or the script had.

That variable is ButtonShuffle. When you press a button with altered function, the ButtonShuffle variable is assigned a value equal to the value representative of your target button. For example, if you press "B" and intend for it to be "A", ButtonShuffle is assigned to the "A" value, which is 1. If ButtonShuffle is 1 and Link->InputA = true, then the function of A is not changed. In other words, ButtonShuffle prevents looping cycles between the function-swapped buttons.

What does that mean for you? It means that, with the ButtonShuffle condition, the script can now tell whether you pressed the button or the script did!


Onward to setup. Currently this script is configured to make B function as A, make A function as R, and make R function as B. In a classic quest, that would mean you press R to use your equipped item, press B to use your sword, and press A to cycle between items. You may have noticed that the assignments make a loop? If you didn't, that's okay, but there's a reason. After we're done reassigning buttons, each button has to be accounted for. If you assign B to function as A, you have to assign A to function as something else, or the A button will be lost in ZC player land. "A" doesn't necessarily have to be assigned to "B", but it needs to go somewhere. And another button needs to be assigned to "B" to close the circuit.

Let's look at the "B" button assignment.


if(Link->InputB && ButtonShuffle != 2){ //Checks if Link actually pressed the button
//or if this script simulated the press of that button. Necessary to avoid
//creating a loop.
ButtonShuffle = 1; //Sets the button truth to the button who's
//effect you want the B button to have
//For Bool ButtonTruth to function properly, you must have this
//kind of integer assignment above EVERY script-forced input.
//The number is 1, because the forced input is for A and "A"
//has an assigned number of 1 in bool ButtonTruth.
Link->InputA = true; //Same as button truth, makes this button
//have that effect. To change the target button, change
//this line to the target button, and change the ButtonTruth
//number to that appropriate for the target button.
Link->InputB = false; //Disables the original function of this
//button.

//I've set the B button to function as "A", so I could dedicate
//"B" to the sword without recoding the sword script.
}

If you wanted to change the assignment of B, you have to change three things. First, change the ButtonShuffle # to that of the target assignment. If you were changing "B" to "Ex1", the number would change to 5. Next, change the input to match that.

So ButtonShuffle = 5 and "InputA" becomes "InputEx1"

Next, we have to assign a new function to "InputEx1".
Copy one of the other function reassignment clauses (The "else if" clause for either "A" or "R") and change the Inputs of that letter to InputEx1, and the ButtonShuffle in the "if" condition to 5.

Inside the "if" clause, change the ButtonShuffle to the target button #, as well as the "true" input.
If these steps don't make much sense, just read the code block below.



if(Link->InputB && ButtonShuffle != 2){ //Checks if Link actually pressed the button
//or if this script simulated the press of that button. Necessary to avoid
//creating a loop.
ButtonShuffle = 5; //Sets the button truth to the button who's
//effect you want the B button to have
//For Bool ButtonTruth to function properly, you must have this
//kind of integer assignment above EVERY script-forced input.
Link->InputEx1 = true; //Same as button truth, makes this button
//have that effect. To change the target button, change
//this line to the target button, and change the ButtonTruth
//number to that appropriate for the target button.
Link->InputB = false; //Disables the original function of this
//button.

//I've set the B button to function as "A", so I could dedicate
//"B" to the sword without recoding the sword script.
}
else if(Link->InputEx1 && ButtonShuffle != 5){ //We changed the ButtonShuffle to 5, and the Input to Ex1. ButtonShuffle !=5 because that is the value for InputEx1.
ButtonShuffle = 2; //We'll make it work B.
Link->InputB = true; //So that it works like the "B" button when we press it
Link->InputEx1 = false; //Disables the original function of this
//button.
}


And that is the extent of the setup.

Also, as an added bonus, you don't even have to change the input buttons for your custom coded actions. Like, let's say you coded a jump button to "L", and you reassigned "L" to "A". If you press the "A" button with this code set-up correctly, the game will think you are pressing "L" and it will use your jump code.




There's just one little catch to all of this. If you EVER set any Input to True for a button you've reassigned, you will need to precede that line with the ButtonShuffle for that button. Otherwise ZC will not be able to tell if you pressed the button or the script did, and you will get a mess.

Enjoy!
-CJC


EDIT:
For those who don't fully understand the code and just want to assign items to X and Y (Ex1 and Ex2), here's the chunk you should put in the waitframe section of your global script.



if(Link->InputB && ButtonShuffle != 2){
ButtonShuffle = 6; //B Becomes Y
Link->InputEx2 = true;
Link->InputB = false;
}
else if(Link->InputA && ButtonShuffle != 1){
ButtonShuffle = 5; //A Becomes X
Link->InputEx1 = true;
Link->InputA = false;
}
else if(Link->InputEx2 && ButtonShuffle != 6){
ButtonShuffle = 2; //Y becomes B
Link->InputB = true;
Link->InputEx2 = false;
else if(Link->InputEx1 && ButtonShuffle != 5){
ButtonShuffle = 1; //X becomes A
Link->InputA = true;
Link->InputEx1 = false;
}
else{ButtonShuffle = 0;}
Waitframe();

That will make the inventory function similar to the one in WindWaker, as far as item selection goes.