I know, another double-post. But this is big! Cane of Somaria version 3.0 is ready! And guess what? IT'S THE PERFECT OOA CANE OF SOMARIA! Here you go (It's a copy of what I posted at AGN, so meh):
No words can express the joy I have because... I JUST PERFECTED THE CANE OF SOMARIA. Granted, right now it's only the Oracle of Ages version, but I'll work on the LttP/FSA version at a later time, when making Wand Magic spawn in 4 different directions is a bit more feasible. So, without further ado, I bring you...
THE CANE OF SOMARIA: ORACLE OF AGES VERSION. This is version 3.0 of my Cane of Somaria script. It has EVERYTHING: Only one block can be on the screen at a time, it can be pushed, slashing it gets rid of it, and anything you'd expect the OoA Cane of Somaria to do (Minus any picking up, of course).
CODE
// Cane of Somaria (OoA version)- When used, this item will create a block in front of Link if the block in front of him isn't solid.
// If the combo is solid, this script does nothing.
// Variables:
// Cmb- The combo that the Cane switches a screen's combo to. Simply enter the combo number seen in the combo editor!
// CmbC- The CSet of the new combo. Only use 0-11 for best results.
// CmbS- Secret Flag of the new combo.
// SomariaCheck- A special variable used only for checking if a Somaria Block is already on-screen. Creating a Block
// sets this Variable to 1. Destroying one sets it to 0. This variable is checked only by one function. DO NOT MESS WITH IT!!!!
// CmbR- The combo the Block resets to when SomariaCheck is set to 1 when you use this item.
// CmbRC- CSet the of the reset combo.
// CmbRS- Secret Flag of the reset combo.
import "std.zh"
item script CaneSomariaOoA
{
int SomariaBlockX = 0;
int SomariaBlockY = 0;
int SomariaCheck = 0;
int SomariaBlockPosition = 0;
int CurScreen = 0;
int LastScreen = 0;
int CurMap = 0;
int LastMap = 0;
int Cmb = A;
int CmbC = B;
int CmbS = C;
int CmbR = D;
int CmbRC = E;
int CmbRS = F;
void run()
{
CurScreen = Game->GetCurScreen();
CurMap = Game->GetCurMap();
if (CurScreen != LastScreen)
{
SomariaCheck = 0;
}
else if (CurMap != LastMap)
{
SomariaCheck = 0;
}
if (SomariaCheck == 1)
{
SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
if (Screen->ComboS [SomariaBlockPosition] == 15)
{
Screen->ComboD [SomariaBlockPosition] = CmbR;
Screen->ComboC [SomariaBlockPosition] = CmbRC;
Screen->ComboF [SomariaBlockPosition] = CmbRS;
SomariaCheck = 0;
}
}
if (Link->Dir == 0)
{
int BlockCheckY = Link->Y - 32;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y - 32;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
else if (Link->Dir == 1)
{
int BlockCheckY = Link->Y + 32;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y + 32;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
else if (Link->Dir == 2)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X - 32;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X - 32;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
else if (Link->Dir == 3)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X + 32;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if ( BlockRmndrY <= 8 )
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X + 32;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
LastScreen = CurScreen;
LastMap = CurMap;
SomariaCheck = 1;
}
}
Replace "A" with the number of the combo the Cane will "spawn". If you wish to have a poof, use the "poof" animation as the starting combo and have it cycle to the pushable block. Just... Be careful. This script places the block on layer 0, so try to put the ground on Layers 1 or 2, okay? And give the poof the push flag, too.
"B" is the Cset of the starting combo. "C" is its Secret Flag. I have it set to 79 because in OoA, hitting the block with your Sword made it vanish.
You can replace that with anything else if you want, EXCEPT THE PUSH FLAG. Unless you LIKE pushing non-solid ground. No fun, is it? That's why every pushable combo in the cycle MUST HAVE THE PUSH FLAG AS AN INHERENT COMBO. That way it vanishes. Since trigger flags remove themselves when you trigger them (even as normal flags), it's perfectly fine to use the Sword flag as a normal flag. However, no singular flags can be put on them this way. May I suggst 2.11's Slash->Next combo? Seriously, that'd be MUCH better (WHY DIDN'T I THINK OF THAT UNTIL JUST NOW?! XD). So, you can just leave "C" at 0 if you wish. "D" is the combo that is used to "remove" the Block if one is on the screen. Set it like you would Cmb, but remember, this one HAS to cycle back to normal, walkable ground! "E" is the CSet the combo uses when it "resets" to normal ground. Simple, no? Finally, "F" is, as you'd expect, the Secret Flag of the combo when "reset".
Oh no! Triple-post! Sorry, but I ran out of room on my last post. You understand, right?
If you create a block but leave the screen, SomariaCheck (the Variable that tells if a Block is on the screen or not) will stay at 1 (Block is on the screen). Thus, you'd expect the script to try to remove a Block that isn't there anymore, right? That's what the CurScreen, LastScreen, CurMap, and LastMap variables are for. If CurScreen doesn't equal LastScreen, SomariaCheck is set to 0. If it does, then if CurMap and LastMap don't equal each other, SomariaCheck is set to 0. If all are equal to their Last counterparts, nothing happens.
But what if you make a Block, leave the screen, and come back without making a block on the other screen? The Block will be gone, but SomariaCheck is still 1! Wouldn't that make the script try to "remove" a Block that isn't there? Not a chance! I figured that in case something went wrong in the checking of the value of SomariaCheck, another check would be needed just in case. I never knew that THIS is what it'd be for. After checking the value of SomariaCheck, if it's 1, the script ALSO checks for Total Solidity (Screen->ComboS[] == 15) at the SomariaBlock's last location. If total solidity is there, the values of CmbR, CmbRC, and CmbRS are placed there. If not, it obviously means you switched screens and came back, so there's no Block there. And it actually works. It then resets SomariaCheck back to 0 (Just for completeness and because of common sense- It's not really needed, but SomariaCheck is 1 if there IS a block on the screen, so common sense says that it doesn't need to be 1 anymore if a block isn't there.
).
The rest places the block onto the screen. Now... I'd suggest you leave the script alone after this point, but just in case you wish to make the block spawn one tile in front of you instead, here you go:
CODE
// Cane of Somaria (OoA version)- When used, this item will create a block in front of Link if the block in front of him isn't solid.
// If the combo is solid, this script does nothing.
// Variables:
// Cmb- The combo that the Cane switches a screen's combo to. Simply enter the combo number seen in the combo editor!
// CmbC- The CSet of the new combo. Only use 0-11 for best results.
// CmbS- Secret Flag of the new combo.
// CmbI- Inherent Flag of the new combo.
// CmbT- Combo type of the new combo.
// CmbS- Solidity of the new combo. Note: SOLIDITY USES THE BINARY SYSTEM. 1111 is total solidity, which is 15 in decimal.
// SomariaCheck- A special variable used only for checking if a Somaria Block is already on-screen. Creating a Block
// sets this Variable to 1. Destroying one sets it to 0. This variable is checked only by one function. DO NOT MESS WITH IT!!!!
// CmbR- The combo the Block resets to when SomariaCheck is set to 1 when you use this item.
// CmbRC- CSet the of the reset combo.
// CmbRS- Secret Flag of the reset combo.
import "std.zh"
item script CaneSomariaOoA
{
int SomariaBlockX = 0;
int SomariaBlockY = 0;
int SomariaCheck = 0;
int SomariaBlockPosition = 0;
int CurScreen = 0;
int LastScreen = 0;
int CurMap = 0;
int LastMap = 0;
int Cmb = 2123;
int CmbC = 10;
int CmbS = 79;
int CmbR = 0;
int CmbRC = 2;
int CmbRS = 0;
void run()
{
CurScreen = Game->GetCurScreen();
CurMap = Game->GetCurMap();
if (CurScreen != LastScreen)
{
SomariaCheck = 0;
}
else if (CurMap != LastMap)
{
SomariaCheck = 0;
}
if (SomariaCheck == 1)
{
SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
if (Screen->ComboS [SomariaBlockPosition] == 15)
{
Screen->ComboD [SomariaBlockPosition] = CmbR;
Screen->ComboC [SomariaBlockPosition] = CmbRC;
Screen->ComboF [SomariaBlockPosition] = CmbRS;
SomariaCheck = 0;
}
}
if (Link->Dir == 0)
{
int BlockCheckY = Link->Y - 16;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y - 16;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
else if (Link->Dir == 1)
{
int BlockCheckY = Link->Y + 16;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y + 16;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
else if (Link->Dir == 2)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X - 16;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X - 16;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
else if (Link->Dir == 3)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X + 16;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if ( BlockRmndrY <= 8 )
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X + 16;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
}
}
LastScreen = CurScreen;
LastMap = CurMap;
SomariaCheck = 1;
}
}
Same stuff as before, but all instances of the number "32" have been replaced with "16".
Have fun, and a special demo will come soon featuring the Cane of Somaria and many things you can do with it!
Oh yeah, and as for the LttP/FSA-style Cane, I'm planning on doing that next. I'll most likely wait a ew betas, though. I've been working on this for about 5 or 6 days, and my parents are mad at me for being on all day everyday. Now that I finished this, I won't have to stay on all dang day!