PDA

View Full Version : Cane of Somaria - Updated!



Nimono
01-31-2008, 01:32 PM
Copy-paste from PureZC....

Yes, I know there's another topic for this script. But the last post was MONTHS ago, so just to be safe, I'll just make a new one here.


Okay, I updated my Cane of Somaria script. That's all you need to know.


// 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.
// Reset- The combo the Block resets to when SomariaCheck is set to 1 when you use this item.
// ResetC- CSet the of the reset combo.
// ResetS- Secret Flag of the reset combo.

int SomariaX = 0;
int SomariaY = 0;
int SomariaCheck = 0;
int CurScreen = 0;
int LastScreen = 0;
int CurMap = 0;
int LastMap = 0;
int Cmb = 1990;
int Reset;
int cmbcntr;
int BlockPosition;
int BlockCheckY;
int BlockCheckX;
bool blockappear = false;
bool cancheck = false;
bool remove = false;
item script CaneSomariaOoA
{
void run()
{
if (SomariaCheck == 1)
{
for (int cmbchk = 0; cmbchk < 176; cmbchk++)
{
if (Screen->ComboD[cmbchk] == Cmb)
{
blockappear = true;
remove = true;
Screen->ComboD[cmbchk] = Reset;
SomariaCheck = 0;
}
}
}
if (Link->Dir == 0)
{
BlockCheckY = Link->Y - 16;
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;
}
BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS[BlockPosition] == 0 && Screen->ComboF[BlockPosition] != 67 && Screen->ComboI[BlockPosition] != 67)
{
Reset = Screen->ComboD[BlockPosition];
Screen->ComboD[BlockPosition] = Cmb;
}
}
else if (Link->Dir == 1)
{
BlockCheckY = Link->Y + 16;
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;
}
BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS[BlockPosition] == 0 && Screen->ComboF[BlockPosition] != 67 && Screen->ComboI[BlockPosition] != 67)
{
Reset = Screen->ComboD[BlockPosition];
Screen->ComboD[BlockPosition] = Cmb;
}
}
else if (Link->Dir == 2)
{
BlockCheckY = Link->Y;
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;
}
BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS[BlockPosition] == 0 && Screen->ComboF[BlockPosition] != 67 && Screen->ComboI[BlockPosition] != 67)
{
Reset = Screen->ComboD[BlockPosition];
Screen->ComboD[BlockPosition] = Cmb;
}
}
else if (Link->Dir == 3)
{
BlockCheckY = Link->Y;
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;
}
BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS[BlockPosition] == 0 && Screen->ComboF[BlockPosition] != 67 && Screen->ComboI[BlockPosition] != 67)
{
Reset = Screen->ComboD[BlockPosition];
Screen->ComboD[BlockPosition] = Cmb;
}
}
LastScreen = CurScreen;
LastMap = CurMap;
SomariaCheck = 1;
blockappear = true;
Game->PlaySound(63);
cmbcntr = BlockPosition;
}
}

And there you have it. ...What?

...Okay, I lied.


// Cane of Somaria (Global Script)- This script checks for the Somaria Block and constantly keeps track of the 4 combos around it. If pushed, a variable from
// the "canesomariaooa" script is changed to be the same as the combo the Block was just pushed over. This way, you can have the block work perfectly on
// screens with multiple walkable tiles that Blocks can be pushed over.

int cmbnorth;
int cmbsouth;
int cmbwest;
int cmbeast;
int ResetOld;
int Poof1 = 6480;
int Poof2 = 6481;
int Poof3 = 6482;
int Poof4 = 6483;
int Poof5 = 6484;

global script caneofsomaria
{
void run()
{
while(true)
{
CurScreen = Game->GetCurScreen();
CurMap = Game->GetCurMap();
if (CurScreen != LastScreen)
{
SomariaCheck = 0;
}
else if (CurMap != LastMap)
{
SomariaCheck = 0;
}
if(blockappear)
{
if(remove)
{
Screen->DrawTile(3, SomariaX, SomariaY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof1, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof1, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof2, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof2, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof1, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof1, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof2, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof2, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof3, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof4, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, SomariaX, SomariaY, Poof5, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Screen->DrawTile(3, BlockCheckX, BlockCheckY, Poof5, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
remove = false;
blockappear = false;
}
else if(!remove)
{
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6482, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6483, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6482, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6483, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6480, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6481, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6480, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6481, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6482, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6483, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6482, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6483, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
Waitframe();
Screen->DrawTile(3, BlockCheckX, BlockCheckY, 6484, 1, 1, 10, 1, 1, 1, 1, 0, true, 128);
blockappear = false;
}
}
if(SomariaCheck == 1)
{
for(int check = 0; check < 176; check++)
{
if(Screen->ComboD[check] == Cmb)
{
int checknorth = cmbcntr - 16;
int checksouth = cmbcntr + 16;
int checkwest = cmbcntr - 1;
int checkeast = cmbcntr + 1;
if(check == checknorth)
{
Reset = cmbnorth;
}
if(check == checksouth)
{
Reset = cmbsouth;
}
if(check == checkwest)
{
Reset = cmbwest;
}
if(check == checkeast)
{
Reset = cmbeast;
}
cmbnorth = Screen->ComboD[checknorth];
cmbsouth = Screen->ComboD[checksouth];
cmbwest = Screen->ComboD[checkwest];
cmbeast = Screen->ComboD[checkeast];
cmbcntr = check;
ResetOld = Reset;
cancheck = true;
}
}
if(Screen->ComboD[cmbcntr] != Cmb && cancheck && Screen->ComboS[cmbcntr] == 0 && CurScreen == LastScreen && CurMap == LastMap && Screen->ComboF[cmbcntr] != 67 && Screen->ComboI[cmbcntr] != 67)
{
Screen->ComboD[cmbcntr] = ResetOld;
}
}
LastScreen = Game->GetCurScreen();
LastMap = Game->GetCurMap();
SomariaY = BlockCheckY;
SomariaX = BlockCheckX;
Waitframe();
}
}
}

Say hello to the TRUE code of the Cane of Somaria! This GLOBAL script (REMEMBER THAT) makes the block work with multiple ground combos on a single screen! :D Plus, the block will be removed if you push it. Only problems that remain are...

1: Pushing the block the minute it appears somehow makes a "garbage" tile appear. Basically, it'll change the tile to something it's not supposed to be. SO DON'T DO THAT. I wouldn't have that problem if you could actually SWING the Cane, but... And no, I'm NOT gonna use DrawTile or anything to show that. :|
2: Poofs appear when removing a block. Problem? If you push said block, THEN remove it, the poof still appears at its original location. D: I don't know how to fix that, because I can't update the x and y variables every frame unless I update BlockCheckY and BlockCheckX every frame, which I can't do outside using the item. >_< Now, if only I could split up variable "cmbchk" into 2 variables, one for its x, and one for its y... I need x and y for DrawTile, which MUST use x and y positions... If anyone would like to help me out with this, LEMME KNOW.

Oh, right.... Poof1-5 are the frames used for the poofing animation when making a block appear and disappear. And remember this:

YOU DO NOT NEED TO MAKE A SCREEN USE LAYER 3 FOR THE DRAWTILE TO WORK.

In fact, you don't need combos to make DrawTile work, either. Now if only we could use DrawTile on every screen for layers and animations... Hehehe, that'd save a TON of combos. :D

Again, you will need both of these scripts for the Cane of Somaria to work.

AND YES, WAITFRAME(); DOES WORK IN GLOBAL SCRIPTS.

I'm actually getting tired of everyone saying that Waitframe(); doesn't work in Global scripts, because if it didn't, this topic wouldn't even exist right now. ;)

Now have fun! :D Oh, and this is intended for build 726... Now, I know that Items have D variables in that build, but since the global script references "cmb", I can't use it to decide what combos to use... I apologize for this major inconvenience. Yes, I could always store the value of that to a- ...Riiiight. If you wanna use it that way, add "int somariablock" to the () of void run(), and add this line at the very start of the code:


Cmb = somariablock;

And edit the Cmb thing at the start to just say "int Cmb;". Yes, a bit of editing, but people might not use a build that can do that... So it'll have to be this way. Now, enjoy this almost-perfect Cane of Somaria! :D

(I hate the look of the :D smilie here... >_>)

Russ
01-31-2008, 09:47 PM
Wow. Great job Matthew! So, will it trigger block triggers now?

And on a side note, the smily :D is awesome! :D:D:D:D:D

Nimono
01-31-2008, 11:09 PM
Wow. Great job Matthew! So, will it trigger block triggers now?

And on a side note, the smily :D is awesome! :D:D:D:D:D

Yes, it will. Speaking of which, there's one last bug I forgot to mention:

3: This script is all screwy if you try to place the block over a block trigger. Trust me, DON'T DO IT. Just put the block NEXT to the trigger, then push it into the trigger.... You WILL be sorry if you just place the block on the trigger, then move it away... Well, that is, if you have multiple triggers. I don't even get what's going on, so I have no way to fix it... You guys can live with these bugs, right? D:

Also, it's ALWAYS triggered Block triggers from the time it created a Combo....

Russ
01-31-2008, 11:12 PM
Well, that's an interesting bug.

"You got the Cane of Somaria! Use it's power to create a block. Just don't put the block directly over a switch, or you will be sorry..."

Nimono
02-01-2008, 01:11 AM
Well, that's an interesting bug.

"You got the Cane of Somaria! Use it's power to create a block. Just don't put the block directly over a switch, or you will be sorry..."

Lol. From what I've seen, it makes the block react bad when going for another switch. Okay, I've tested. Apparently, if you create a block on a Block Trigger flag and push it away, the flag will get carried to that location....odd. Lemme test one more thing. ...Okay, my suspicions were correct. Try to put it on an inherent Block Trigger and pushing it away WILL NOT make the flag move. :D That's one problem solved. The next is figuring out how to make it so it'll react to the Block Trigger if you summon the block on top of one...

Joe123
02-01-2008, 03:38 AM
Ahh, you got it working now then?

With the drawtiles in the global script?

_L_
02-02-2008, 11:07 AM
I wouldn't have that problem if you could actually SWING the Cane, but... And no, I'm NOT gonna use DrawTile or anything to show that. :|

Hmm...

Reskin the Wand. Give it a magic requirement of 255 so that it never fires. Assign it the item script. Then time the global script using Waitframes() so that it places the block when the wand completes its swing. That'd work, right?


Also: might I suggest replacing some of the DrawTiles with a command that places an animated Non-Gameplay Item that cannot be picked up and is removed by the script once the appropriate number of frames have elapsed?

Nimono
02-02-2008, 11:53 AM
Hmm...

Reskin the Wand. Give it a magic requirement of 255 so that it never fires. Assign it the item script. Then time the global script using Waitframes() so that it places the block when the wand completes its swing. That'd work, right?

From what I've seen, if you don't have the Magic for an item when you try to use it, nothing appears. Not even its stab/slash animation. I think. Lemme check.



Also: might I suggest replacing some of the DrawTiles with a command that places an animated Non-Gameplay Item that cannot be picked up and is removed by the script once the appropriate number of frames have elapsed?

But how would you make it so you can't pick it up? Freeze Link until it stops animating? Ha ha ha, no. :p But seriously, I don't know of any other way besides FFCs, which I want to save.

Joe123
02-02-2008, 03:26 PM
You can set a hearts requirement for items to be picked up in the editor can't you?

And you can swing the wand still if you have no magic.

You can also give it slash tiles.

Nimono
02-02-2008, 07:24 PM
You can set a hearts requirement for items to be picked up in the editor can't you?

And you can swing the wand still if you have no magic.

You can also give it slash tiles.

Ah, good point! :D I just set it to 21 (max in my quest is 20), and yay! Too bad that's not really gonna help much. Seriously, its X and Y can't be combined. Hey, Joe, would you mind testing something out for me? Could you try doing 2 different for loops for checking combo locations, like in _L_'s Crystal Switch script, that check for x and y? I'm thinking if I can keep 'em seperate like that, and combine 'em later, if it works perfectly, all my position problems will be solved. I'd test it myself, but....




I don't wanna. :p

Joe123
02-02-2008, 07:38 PM
int combotype;
int i; int j; int x; int y;
for(i=0; i<256; i++){
for(j=0; j<176; j++){
if(Screen->ComboT[ComboAt(i,j)] == combotype){
x = i;
y = j;
i = 256;
j = 176;
}
}
}

That should work, but I wouldn't advise doing it too often...