Z3-esque Keys (and Item Pickup)
SubmittedDecember 14, 2016
ZoriaRPG
Notice: This first section of this script, is a set of global functions, useful for handling item interaction with FFCs. If you are already using these functions, then you will only need the FFC section of this script.
Z3-esque Keys & Items, is an FFC script, that allows you to set a specific item on a screen, that the player may obtain through one of two items: The item given, and the items that can retrieve it are set in script arguments.
The base function of this, is to allow the player to pick up keys, using items such as the boomerang, or the hookshot, to solve puzzles, without enabling the 'Z3 Boomerang/Hookshot' Quest Rule, which allows the player to pick up any Screen->Item with the boomerang, and hookshot class items.
When using it, you will need to set a few arguments, to assign the items that can pick up the FFC Key, or you may hared-code the value into the script, if your quest will never use items other than these two, for item collection. You may also expand this, to allow any number of items to collect the FFC-generated item, should you want a wider variety, but the base script assumes that you will set one, or two items, in script arguments.
The default item generated by this script is a normal key. You may change this to a level-specific key, by setting the value of one argument, and you may further give other items, by further argument settings.
Essentially, you can give any item in your game, and allow any two items to collect it, but the player will not be able to pick up the item merely by touching it.
This script is intended for placing items in out-of-reach places, and requiring clever item usage to collect them.
If You Have an Existing Script Set
Add the global constants, global variables, and global functions to your existing script.
Add the FFC script to your existing scripts.
Place the global functions in your main active while loop, before Waitdraw().
Compile.
Assign the FFC script 'Z3_Key_Pickup' into an FFC Script slot.
If You Do Not Have an Existing Script Set
Import this file as your main script, and compile it. (It is a self-contained, and complete set-up.)
Assign the FFC script 'Z3_Key_Pickup' into an FFC Script slot.
Assign the included Global Active script to your Global Active Script Slot (2).
Usage
Add the combo used for the item that you want the player to obtain, to your combo pages.
Create an FFC, and set the combo for the item to it, as you wish the player to see it.
Enable the script 'Z3_Key_Pickup' to the FFC as its active script.
Enable the FFC Flag: 'Run Script on Screen init'
Set the Arguments as Follows
D0: Set to the Item Class of the primary item that you want to be able to pick up the item generated by the FFC, using the numeric values from std_constants.zh. (Using specific items is planned for a later update.) The default value for the boomerang, is '1'.
D1: Set to the Item Class of the secondary item that you want to be able to pick up the item generated by the FFC, using the numeric values from std_constants.zh. (Using specific items is planned for a later update.) The default value for the hookshot is '21'.
Note: If you do not wish to use a secondary item, set this to '0'.
D2: If you wish to give the player a normal key, leave this at '0'.
If you want to give the player a level-specific key, set this to a value of '1'.
If you want to give the player a specific item, set this to a negative number, equal to the item editor number.
(Thus, for the blue ring, item 17, you would enter '-17' as the value of this argument.
D3: Set this to the audio/SFX Data value to play when picking u the item.
The Default value for 'Item Pickup' is 22.
You're done!. Position the FFC on the screen, as you desire.
Note: This is tested for one instance per screen, and secondary instances per screen may not work. I may allow for additional instances, in a future update.
All argument information is also contained in the script file, which is commented so that you may more easily follow its operation.
import "std.zh"
//////////////////////
/// ItemHandling.zh //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// This is a global function set for handlinbg item interaction. ///
/// The original author of this function set is grayswandir, who provided it to me, for use in TGC, ///
/// and I use it for so many components, that in sharing other scriots, I may as well make it a header, ///
/// to provide the functionality needed for many FFC scripts that I make available to others operable ///
/// without duplicating these functions in every instance. I may expand on it at some future point. ///
/// ///
/// Note: The pick-up is instantaneous, and does not need to wait for Link to touch the item. ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////
/// Global Constants ///
////////////////////////
const int MISC_LWEAPON_ITEM = 0; // The id of the item used to create an lweapon.
////////////////////////
/// Global Variables ///
////////////////////////
int LastItemUsed = 0; // The item id of the last item Link has used.
////////////////////////
/// Global Functions ///
////////////////////////
void UpdateLWeapons() { //// Updates every LWeapon on screen. Call in the active script.
for (int i = 1; i NumLWeapons(); i++) {
UpdateLWeapon(Screen->LoadLWeapon(i));
}
}
void UpdateLWeapon(lweapon lw) { //// Update a given LWeapon.
// If the weapon does not have it's source item marked, mark it as being created by the last item that Link has used.
if (lw->Misc[MISC_LWEAPON_ITEM] == 0) {
lw->Misc[MISC_LWEAPON_ITEM] = LastItemUsed;
}
}
/////////////////////////////////////////////////////////////////////////
/// Updates the LastItemUsed variable to our best guess at what was ///
/// most recently used. This should be called at the end of the loop, ///
/// right before Waitdraw or Waitframe, because the item marked in ///
/// LastItemUsed isn't actually used until after the Waitdraw or ///
/// Waitframe. ///
/////////////////////////////////////////////////////////////////////////
void UpdateLastItem() {
// Since we don't know which button has priority if both are pressed
// at once, cancel the B button press if A has also been pressed
// this frame.
if (Link->PressA && Link->PressB) {
Link->PressB = false;
}
// If Link is currently in an action where he obviously can't use items, then ignore his button presses.
if (Link->Action != LA_NONE &&
Link->Action != LA_WALKING) {
return;
}
// Check which button is being pressed, if any. Also check for the appopriate Jinx.
if (Link->PressA && Link->SwordJinx == 0) {
LastItemUsed = GetEquipmentA();
}
else if (Link->PressB && Link->ItemJinx == 0) {
LastItemUsed = GetEquipmentB();
}
}
bool IsFromItem(lweapon lw, int itemNumber) { //// Return true if the given lweapon is from the given item.
return lw->Misc[MISC_LWEAPON_ITEM] == itemNumber;
}
bool IsFromItemClass(lweapon lw, int itemClass) { //// Return true if the given lweapon is from the given item class.
itemdata data = Game->LoadItemData(lw->Misc[MISC_LWEAPON_ITEM]);
return data->Family == itemClass;
}
////////////////////
/// Item Pick-Up ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// This script creates an FFC, that gives Link a key, and clears the FFC if the FFC is touched by the ///
/// boomerang, or the hookshot. This is useful if you want the boomerang/hookshot to pick up keys as in Z3, ///
/// without also allowing them to pick up other special items (per quest rules for Z3 boomerang. ///
/// ///
/// Note: The pick-up is instantaneous, and does not need to wait for Link to touch the item. ///
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// D0 : Item Class (Positive Number), or Item Number (negative Number) of primary trigger. ///
/// Standard value is 1 (IC_BRANG). ///
/// D1 : Item Class (positive Number), or Item Number (negative Number) of secondary trigger. ///
/// Standard value is 21 (IC_HOOKSHOT). ///
/// D2: Set to 0 to give a normal key, or 1 to give a key specific to the level that the player is inside. ///
/// Set to a negative number to give a specific item, other than a key, or a level key. ///
/// D3: Set this to the Sound Effect to play on giving the player the item, from Quest->Audio->SFX Data. ///
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
ffc script Z3_Key_Pickup {
void run(int trigger, int trigger2, int level, int SFX) {
bool waiting = true;
while(waiting){
if ( Screen->D[0] >= 1 ) { // If the FFC has already run on the screen
this->Data = 0; //Remove sprite
return; //Quit
}
else if ( Screen->D[0] == 0 ) {
for (int i = 1; i NumLWeapons(); i++) { // Loop through all LWeapons on screen.
lweapon lw = Screen->LoadLWeapon(i);
if (lw->CollDetection && Collision(this, lw)) { // If the LWeapon is touching us.
if (trigger > 0) { // If is positive, test the lweapon for being the correct item class.
if (IsFromItemClass(lw, trigger) || IsFromItemClass(lw, trigger2)) {
waiting = false;
if ( level == 0 ) {
Game->Counter[CR_KEYS] += 1;
Game->PlaySound(SFX);
Screen->D[0] = 1;
this->Data = 0; //Remove sprite
return; //Quit
}
else if ( level > 0 ) {
item levelKeyGiven = Screen->CreateItem(I_LEVELKEY);
levelKeyGiven->X = Link->X;
levelKeyGiven->Y = Link->Y;
levelKeyGiven->Z = Link->Z;
Game->PlaySound(SFX);
Screen->D[0] = 1;
this->Data = 0; //Remove sprite
return; //Quit
}
else if ( level CreateItem(-level);
levelKeyGiven->X = Link->X;
levelKeyGiven->Y = Link->Y;
levelKeyGiven->Z = Link->Z;
Game->PlaySound(SFX);
Screen->D[0] = 1;
this->Data = 0; //Remove sprite
return; //Quit
}
}
}
// else { // If is negative, test the lweapon for being the correct item number.
// if (IsFromItem(lw, -trigger) || IsFromItem(lw trigger2)) {
// waiting = false;
// }
// }
}
}
Waitframe();
//Screen->D[0] = 1;
//this->Data = 0; //Remove sprite
//return; //Quit
}
// Do stuff
}
// Clear the FFC if needed
}
}
/////////////////////////////
/// Sample Active Script. ///
/////////////////////////////
global script Active {
void run() {
while (true) {
UpdateLWeapons();
UpdateLastItem();
if (Link->PressB) {LastItemUsed = GetEquipmentB();}
if (Link->PressA) {LastItemUsed = GetEquipmentA();}
Waitdraw();
Waitframe();
}
}
}
Review this entry
You must be logged in to post a comment.