PDA

View Full Version : Am I doing something wrong, or is this a bug?



Nimono
01-03-2009, 08:43 PM
I'm not sure if this is a bug or not, so I'll just ask here...

I've been working on a script for Bombs that act like those from the classic Bomberman games, in that the explosions go off in a + pattern, and stop at solid blocks. I've got the skeleton of the bombs down:


import "std.zh"

bool isspiked = false;
bool isremote = false;
bool CanCreate = true;

global script Bomberman
{
void run()
{
int bombtimer1 = 0;
int bombtimer2 = 0;
int bombtimer3 = 0;
int bombtimer4 = 0;
int bombtimer5 = 0;
int bombtimer6 = 0;
int BombX;
int BombY;
int LastMap;
int LastScreen;
int bombcount = 0;
int nrmbmb = 400;
int spkbmb = 400;
int rmtbmb = 400;
lweapon bomb1;
lweapon bomb2;
lweapon bomb3;
lweapon bomb4;
lweapon bomb5;
lweapon bomb6;
bool IsRem1 = false;
bool IsRem2 = false;
bool IsRem3 = false;
bool IsRem4 = false;
bool IsRem5 = false;
bool IsRem6 = false;
bool IsPlaced1 = false;
bool IsPlaced2 = false;
bool IsPlaced3 = false;
bool IsPlaced4 = false;
bool IsPlaced5 = false;
bool IsPlaced6 = false;
bool IsSpike1 = false;
bool IsSpike2 = false;
bool IsSpike3 = false;
bool IsSpike4 = false;
bool IsSpike5 = false;
bool IsSpike6 = false;
while(true)
{
if(Game->GetCurMap() != LastMap || Game->GetCurScreen() != LastScreen)
{
bombcount = 0;
bombtimer1 = 0;
bombtimer2 = 0;
bombtimer3 = 0;
bombtimer4 = 0;
bombtimer5 = 0;
bombtimer6 = 0;
CanCreate = true;
}
if(bombcount < Game->Counter[2] && Link->InputA && CanCreate)
{
if(bombcount >= 0 && !IsPlaced1)
{
BombX = Link->X;
BombY = Link->Y;
if(Screen->ComboS[ComboAt(BombX, BombY)] != 0)
{
BombX = Link->X;
BombY = Link->Y - 8;
}
Screen->CreateLWeapon(255);
int numwpns = Screen->NumLWeapons();
lweapon bomb1 = Screen->LoadLWeapon(numwpns);
bomb1->Step = 0;
bomb1->Damage = 0;
bomb1->X = BombX;
bomb1->Y = BombY;
bomb1->CSet = 7;
bomb1->DeadState = -1;
if(isspiked)
{
bomb1->Tile = spkbmb;
IsSpike1 = true;
IsRem1 = false;
}
else if(isremote)
{
bomb1->Tile = rmtbmb;
IsSpike1 = false;
IsRem1 = true;
}
else
{
bomb1->Tile = nrmbmb;
IsSpike1 = false;
IsRem1 = false;
}
bombtimer1 = 180;
Game->PlaySound(21);
IsPlaced1 = true;
}
else if(bombcount >= 1)
{
}
else if(bombcount >= 2)
{
}
else if(bombcount >= 3)
{
}
else if(bombcount >= 4)
{
}
else if(bombcount == 5)
{
}
}
if(IsPlaced1)
{
if(bombtimer1 > 0)
{
if(!isremote && !IsRem1)
{
bombtimer1--;
}
}
if(Link->InputB && isremote && IsRem1)
{
bombtimer1 = 0;
}
if(bombtimer1 == 0)
{
bomb1->DeadState = WDS_DEAD;
if(Screen->ComboS[ComboAt(BombX, BombY-16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
lweapon fire1 = Screen->LoadLWeapon(numwpns);
fire1->Step = 0;
fire1->Damage = 2;
fire1->X = BombX;
fire1->Y = BombY - 16;
fire1->ASpeed = 8;
fire1->NumFrames = 8;
fire1->OriginalTile = 440;
fire1->DeadState = 60;
fire1->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX-16, BombY)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
lweapon fire2 = Screen->LoadLWeapon(numwpns);
fire2->Step = 0;
fire2->Damage = 2;
fire2->X = BombX - 16;
fire2->Y = BombY;
fire2->ASpeed = 8;
fire2->NumFrames = 8;
fire2->OriginalTile = 385;
fire2->DeadState = 60;
fire2->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX+16, BombY)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
lweapon fire3 = Screen->LoadLWeapon(numwpns);
fire3->Step = 0;
fire3->Damage = 2;
fire3->X = BombX + 16;
fire3->Y = BombY;
fire3->ASpeed = 8;
fire3->NumFrames = 8;
fire3->OriginalTile = 405;
fire3->DeadState = 60;
fire3->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX, BombY+16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
lweapon fire4 = Screen->LoadLWeapon(numwpns);
fire4->Step = 0;
fire4->Damage = 2;
fire4->X = BombX;
fire4->Y = BombY + 16;
fire4->ASpeed = 8;
fire4->NumFrames = 8;
fire4->OriginalTile = 500;
fire4->DeadState = 60;
fire4->CSet = 7;
}
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
lweapon fire5 = Screen->LoadLWeapon(numwpns);
fire5->Step = 0;
fire5->Damage = 2;
fire5->X = BombX;
fire5->Y = BombY;
fire5->ASpeed = 8;
fire5->NumFrames = 8;
fire5->OriginalTile = 480;
fire5->DeadState = 60;
fire5->CSet = 7;
Game->PlaySound(3);
IsPlaced1 = false;
}
}
while(Link->InputA)
{
CanCreate = false;
Waitframe();
}
if(!Link->InputA)
{
CanCreate = true;
}
LastMap = Game->GetCurMap();
LastScreen = Game->GetCurScreen();
Waitframe();
}
}
}

The problem? The Bomb never dies when its DeadState is set to 0. The explosion fires seem to vanish at first sight, but then they start cycling through a few combos as THEIR DeadState starts going down to 0. Honestly, I'm hoping it's not a bug with DeadState... Also, on a side note, why are certain values on the way to 0 set aside for specific actions? Wouldn't that, y'know...BREAK THIS THING? Just a thought...

beefster09
01-03-2009, 09:15 PM
Try just relocating the bombs just offscreen. Usually, that invalidates them.

BTW: Why don't you use arrays? It would certainly help with the readability of the code.

Nimono
01-03-2009, 09:34 PM
I considered using Arrays, but then I remembered that there were some problems using Arrays in certain ways, so I didn't want to risk it.


...Besides, I don't have plans on fully releasing this to the public.

Now, besides this, I have one more problem- The Bomb itself needs to be positioned EXACTLY in the center of a combo. However, I don't know how to do this. Normally, the Bomb would be placed at Link's X and Y positions, and if the combo at that about position is completely solid, like if Link was standing on the top half of the tile below it, it would move the Bomb down 8 pixels. But this alone isn't enough. I need to find a way to check how far from the center of that combo it is, and move it to there depending on how far away it is. What'd help would be a reverse of the function of ComboAt: "(y & 240)+(x>>4)". However, I'm not sure how to reverse that to take a single number and split it into an X position and a Y position

Also, I just tried to have the Bomb moved. For some reason, it still left its graphic behind. I'm assuming this means it's doing something it really shouldn't be doing...like say, creating more than one copy of this Bomb at one time...

pkmnfrk
01-03-2009, 10:28 PM
As a first thought, I would look closer at how you load the bomb lweapon. Arbitrarily picking the last lweapon on the screen might work okay, if it's the only lweapon on the screen. Link's sword, other bombs, etc might interfere, though.

Second, arrays would be fine in this case. Much better than that huge mess that takes up more than a page.

Third, the combo number is simply the position of the combo on the screen, starting with the top-left combo, and working its way left, then down. So, it would be 1, 2, 3, 4, 5, ... 13, 14, 15. Then, the next row would be 16, 17, 18 ... 30, 31. And so forth.

Given this information, it's easy to get the X/Y position from the Combo Position:


int cx;
int cy;
int theCombo = 123;

cx = Floor(theCombo % 16); //if we divide theCombo by 16, what's the remainder?
cy = Floor(theCombo / 16); //in fact, we also want the result of this division!

//cx and cy are the position, measured in tiles.
//in fact, for 123, it's (11, 7)

cx *= 16;
cy *= 16; //now it's measured in pixels.

Nimono
01-03-2009, 11:31 PM
Well, the location stuff works now, thanks. Only problem I have left is getting the dang Bomb to vanish, which it should be doing because its position in the lweapon table should remain in the same spot by the time it explodes! I don't do anything to it after it's created until after the explosions are created, and that's just moving it off-screen!

pkmnfrk
01-03-2009, 11:54 PM
Well, the best thing to do would be to save a copy of the lweapon pointer, so you don't even have to load it up again! No muss, no fuss!

Nimono
01-04-2009, 12:14 AM
Well, the best thing to do would be to save a copy of the lweapon pointer, so you don't even have to load it up again! No muss, no fuss!

What do you mean, save a copy of it? Could you please explain this?

EDIT: Nevermind on that, I figured out why it wasn't working: I redeclared "lweapon" before assigning it- even though I already declared it as an lweapon pointer before all the code and the while loop, to make it a script-wide variable... I removed that extra declaration, and it worked. Now my Bombs vanish when they explode...even when you explode them remotely. :D

pkmnfrk
01-04-2009, 01:19 AM
Oh, good that you figured it out.

What I means was to do something like:


lweapon theBomb;

global script whatever {
void run() {
if(we trigger a bomb somehow) {
theBomb = Screen->CreateLWeapon(LW_BOMB);
//do whatever with theBomb
}
}
}

(PS: post 500)

Nimono
01-04-2009, 04:31 PM
Okay, I have a new problem...


import "std.zh"

bool isspiked = false;
bool isremote = false;
bool CanCreate = true;

global script Bomberman
{
void run()
{
int bombtimer1 = 0;
int bombtimer2 = 0;
int bombtimer3 = 0;
int bombtimer4 = 0;
int bombtimer5 = 0;
int bombtimer6 = 0;
int BombX1;
int BombY1;
int BombX2;
int BombY2;
int BombX3;
int BombY3;
int BombX4;
int BombY4;
int BombX5;
int BombY5;
int BombX6;
int BombY6;
int LastMap;
int LastScreen;
int bombcount = 0;
int nrmbmb = 400;
int spkbmb = 400;
int rmtbmb = 400;
int randomnumber;
int Items[8] = {0,0,3,3,3,124,123,123};
lweapon bomb1;
lweapon bomb2;
lweapon bomb3;
lweapon bomb4;
lweapon bomb5;
lweapon bomb6;
bool IsRem1 = false;
bool IsRem2 = false;
bool IsRem3 = false;
bool IsRem4 = false;
bool IsRem5 = false;
bool IsRem6 = false;
bool IsPlaced1 = false;
bool IsPlaced2 = false;
bool IsPlaced3 = false;
bool IsPlaced4 = false;
bool IsPlaced5 = false;
bool IsPlaced6 = false;
bool IsSpike1 = false;
bool IsSpike2 = false;
bool IsSpike3 = false;
bool IsSpike4 = false;
bool IsSpike5 = false;
bool IsSpike6 = false;
lweapon Fire1[6];
lweapon Fire2[6];
lweapon Fire3[6];
lweapon Fire4[6];
lweapon Fire5[6];
while(true)
{
if(bombcount < Game->Counter[3] && Link->InputA && CanCreate)
{
if(bombcount >= 0 && !IsPlaced1)
{
BombX1 = Floor(ComboAt(Link->X+7, Link->Y+12) % 16);
BombY1 = Floor(ComboAt(Link->X+7, Link->Y+12) / 16);
BombX1 *= 16;
BombY1 *= 16;
BombY1 += 2;
Screen->CreateLWeapon(255);
int numwpns = Screen->NumLWeapons();
bomb1 = Screen->LoadLWeapon(numwpns);
bomb1->Step = 0;
bomb1->Damage = 0;
bomb1->X = BombX1;
bomb1->Y = BombY1;
bomb1->CSet = 7;
if(isspiked)
{
bomb1->OriginalTile = spkbmb;
IsSpike1 = true;
IsRem1 = false;
bomb1->DeadState = 180;
}
else if(isremote)
{
bomb1->OriginalTile = rmtbmb;
IsSpike1 = false;
IsRem1 = true;
}
else
{
bomb1->OriginalTile = nrmbmb;
IsSpike1 = false;
IsRem1 = false;
bomb1->DeadState = 180;
}
bombtimer1 = 180;
Game->PlaySound(21);
IsPlaced1 = true;
bombcount++;
}
else if(bombcount >= 1 && !IsPlaced2)
{
BombX2 = Floor(ComboAt(Link->X+7, Link->Y+12) % 16);
BombY2 = Floor(ComboAt(Link->X+7, Link->Y+12) / 16);
BombX2 *= 16;
BombY2 *= 16;
BombY2 += 2;
Screen->CreateLWeapon(255);
int numwpns = Screen->NumLWeapons();
bomb2 = Screen->LoadLWeapon(numwpns);
bomb2->Step = 0;
bomb2->Damage = 0;
bomb2->X = BombX2;
bomb2->Y = BombY2;
bomb2->CSet = 7;
if(isspiked)
{
bomb2->OriginalTile = spkbmb;
IsSpike2 = true;
IsRem2 = false;
bomb2->DeadState = 180;
}
else if(isremote)
{
bomb2->OriginalTile = rmtbmb;
IsSpike2 = false;
IsRem2 = true;
}
else
{
bomb2->OriginalTile = nrmbmb;
IsSpike2 = false;
IsRem2 = false;
bomb2->DeadState = 180;
}
bombtimer2 = 180;
Game->PlaySound(21);
IsPlaced2 = true;
bombcount++;
}
}
if(IsPlaced1)
{
if(bombtimer1 > 0)
{
if(!isremote && !IsRem1)
{
bombtimer1--;
}
}
if(Link->InputB && isremote && IsRem1)
{
bombtimer1 = 0;
bomb1->DeadState = 0;
}
if(bombtimer1 == 0)
{
bombcount--;
if(Screen->ComboS[ComboAt(BombX1, BombY1-16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire1[0] = Screen->LoadLWeapon(numwpns);
Fire1[0]->Step = 0;
Fire1[0]->Damage = 2;
Fire1[0]->X = BombX1;
Fire1[0]->Y = BombY1 - 16;
Fire1[0]->ASpeed = 8;
Fire1[0]->NumFrames = 8;
Fire1[0]->OriginalTile = 440;
Fire1[0]->DeadState = 40;
Fire1[0]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX1-16, BombY1)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire2[0] = Screen->LoadLWeapon(numwpns);
Fire2[0]->Step = 0;
Fire2[0]->Damage = 2;
Fire2[0]->X = BombX1 - 16;
Fire2[0]->Y = BombY1;
Fire2[0]->ASpeed = 8;
Fire2[0]->NumFrames = 8;
Fire2[0]->OriginalTile = 385;
Fire2[0]->DeadState = 40;
Fire2[0]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX1+16, BombY1)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire3[0] = Screen->LoadLWeapon(numwpns);
Fire3[0]->Step = 0;
Fire3[0]->Damage = 2;
Fire3[0]->X = BombX1 + 16;
Fire3[0]->Y = BombY1;
Fire3[0]->ASpeed = 8;
Fire3[0]->NumFrames = 8;
Fire3[0]->OriginalTile = 405;
Fire3[0]->DeadState = 40;
Fire3[0]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX1, BombY1+16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire4[0] = Screen->LoadLWeapon(numwpns);
Fire4[0]->Step = 0;
Fire4[0]->Damage = 2;
Fire4[0]->X = BombX1;
Fire4[0]->Y = BombY1 + 16;
Fire4[0]->ASpeed = 8;
Fire4[0]->NumFrames = 8;
Fire4[0]->OriginalTile = 500;
Fire4[0]->DeadState = 40;
Fire4[0]->CSet = 7;
}
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire5[0] = Screen->LoadLWeapon(numwpns);
Fire5[0]->Step = 0;
Fire5[0]->Damage = 2;
Fire5[0]->X = BombX1;
Fire5[0]->Y = BombY1;
Fire5[0]->ASpeed = 8;
Fire5[0]->NumFrames = 8;
Fire5[0]->OriginalTile = 480;
Fire5[0]->DeadState = 40;
Fire5[0]->CSet = 7;
Game->PlaySound(3);
IsPlaced1 = false;
if(Screen->ComboI[ComboAt(BombX1, BombY1-16)] == 6)
{
Screen->ComboD[ComboAt(BombX1, BombY1-16)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX1;
RndmItm->Y = BombY1 - 17;
}
}
if(Screen->ComboI[ComboAt(BombX1, BombY1+16)] == 6)
{
Screen->ComboD[ComboAt(BombX1, BombY1+16)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX1;
RndmItm->Y = BombY1 + 15;
}
}
if(Screen->ComboI[ComboAt(BombX1-16, BombY1)] == 6)
{
Screen->ComboD[ComboAt(BombX1-16, BombY1)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX1 - 16;
RndmItm->Y = BombY1 - 1;
}

}
if(Screen->ComboI[ComboAt(BombX1+16, BombY1)] == 6)
{
Screen->ComboD[ComboAt(BombX1+16, BombY1)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX1 + 16;
RndmItm->Y = BombY1 - 1;
}

}
}
}
if(IsPlaced2)
{
if(bombtimer2 > 0)
{
if(!isremote && !IsRem2)
{
bombtimer2--;
}
}
if(Link->InputB && isremote && IsRem2)
{
bombtimer2 = 0;
bomb2->DeadState = 0;
}
if(bombtimer2 == 0)
{
bombcount--;
if(Screen->ComboS[ComboAt(BombX2, BombY2-16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire1[1] = Screen->LoadLWeapon(numwpns);
Fire1[1]->Step = 0;
Fire1[1]->Damage = 2;
Fire1[1]->X = BombX2;
Fire1[1]->Y = BombY2 - 16;
Fire1[1]->ASpeed = 8;
Fire1[1]->NumFrames = 8;
Fire1[1]->OriginalTile = 440;
Fire1[1]->DeadState = 40;
Fire1[1]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX2-16, BombY2)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire2[1] = Screen->LoadLWeapon(numwpns);
Fire2[1]->Step = 0;
Fire2[1]->Damage = 2;
Fire2[1]->X = BombX2 - 16;
Fire2[1]->Y = BombY2;
Fire2[1]->ASpeed = 8;
Fire2[1]->NumFrames = 8;
Fire2[1]->OriginalTile = 385;
Fire2[1]->DeadState = 40;
Fire2[1]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX2+16, BombY2)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire3[1] = Screen->LoadLWeapon(numwpns);
Fire3[1]->Step = 0;
Fire3[1]->Damage = 2;
Fire3[1]->X = BombX2 + 16;
Fire3[1]->Y = BombY2;
Fire3[1]->ASpeed = 8;
Fire3[1]->NumFrames = 8;
Fire3[1]->OriginalTile = 405;
Fire3[1]->DeadState = 40;
Fire3[1]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX2, BombY2+16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire4[1] = Screen->LoadLWeapon(numwpns);
Fire4[1]->Step = 0;
Fire4[1]->Damage = 2;
Fire4[1]->X = BombX2;
Fire4[1]->Y = BombY2 + 16;
Fire4[1]->ASpeed = 8;
Fire4[1]->NumFrames = 8;
Fire4[1]->OriginalTile = 500;
Fire4[1]->DeadState = 40;
Fire4[1]->CSet = 7;
}
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire5[1] = Screen->LoadLWeapon(numwpns);
Fire5[1]->Step = 0;
Fire5[1]->Damage = 2;
Fire5[1]->X = BombX2;
Fire5[1]->Y = BombY2;
Fire5[1]->ASpeed = 8;
Fire5[1]->NumFrames = 8;
Fire5[1]->OriginalTile = 480;
Fire5[1]->DeadState = 40;
Fire5[1]->CSet = 7;
Game->PlaySound(3);
IsPlaced1 = false;
if(Screen->ComboI[ComboAt(BombX2, BombY2-16)] == 6)
{
Screen->ComboD[ComboAt(BombX2, BombY2-16)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX2;
RndmItm->Y = BombY2 - 17;
}
}
if(Screen->ComboI[ComboAt(BombX2, BombY2+16)] == 6)
{
Screen->ComboD[ComboAt(BombX2, BombY2+16)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX2;
RndmItm->Y = BombY2 + 15;
}
}
if(Screen->ComboI[ComboAt(BombX2-16, BombY2)] == 6)
{
Screen->ComboD[ComboAt(BombX2-16, BombY2)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX2 - 16;
RndmItm->Y = BombY2 - 1;
}

}
if(Screen->ComboI[ComboAt(BombX2+16, BombY2)] == 6)
{
Screen->ComboD[ComboAt(BombX2+16, BombY2)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX2 + 16;
RndmItm->Y = BombY2 - 1;
}

}
}
}
if(IsPlaced3)
{
if(bombtimer3 > 0)
{
if(!isremote && !IsRem3)
{
bombtimer3--;
}
}
if(Link->InputB && isremote && IsRem3)
{
bombtimer3 = 0;
bomb2->DeadState = 0;
}
if(bombtimer3 == 0)
{
bombcount--;
if(Screen->ComboS[ComboAt(BombX3, BombY3-16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire1[2] = Screen->LoadLWeapon(numwpns);
Fire1[2]->Step = 0;
Fire1[2]->Damage = 2;
Fire1[2]->X = BombX3;
Fire1[2]->Y = BombY3 - 16;
Fire1[2]->ASpeed = 8;
Fire1[2]->NumFrames = 8;
Fire1[2]->OriginalTile = 440;
Fire1[2]->DeadState = 40;
Fire1[2]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX3-16, BombY3)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire2[2] = Screen->LoadLWeapon(numwpns);
Fire2[2]->Step = 0;
Fire2[2]->Damage = 2;
Fire2[2]->X = BombX3 - 16;
Fire2[2]->Y = BombY3;
Fire2[2]->ASpeed = 8;
Fire2[2]->NumFrames = 8;
Fire2[2]->OriginalTile = 385;
Fire2[2]->DeadState = 40;
Fire2[2]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX3+16, BombY3)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire3[2] = Screen->LoadLWeapon(numwpns);
Fire3[2]->Step = 0;
Fire3[2]->Damage = 2;
Fire3[2]->X = BombX3 + 16;
Fire3[2]->Y = BombY3;
Fire3[2]->ASpeed = 8;
Fire3[2]->NumFrames = 8;
Fire3[2]->OriginalTile = 405;
Fire3[2]->DeadState = 40;
Fire3[2]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX3, BombY3+16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire4[2] = Screen->LoadLWeapon(numwpns);
Fire4[2]->Step = 0;
Fire4[2]->Damage = 2;
Fire4[2]->X = BombX3;
Fire4[2]->Y = BombY3 + 16;
Fire4[2]->ASpeed = 8;
Fire4[2]->NumFrames = 8;
Fire4[2]->OriginalTile = 500;
Fire4[2]->DeadState = 40;
Fire4[2]->CSet = 7;
}
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire5[2] = Screen->LoadLWeapon(numwpns);
Fire5[2]->Step = 0;
Fire5[2]->Damage = 2;
Fire5[2]->X = BombX3;
Fire5[2]->Y = BombY3;
Fire5[2]->ASpeed = 8;
Fire5[2]->NumFrames = 8;
Fire5[2]->OriginalTile = 480;
Fire5[2]->DeadState = 40;
Fire5[2]->CSet = 7;
Game->PlaySound(3);
IsPlaced1 = false;
if(Screen->ComboI[ComboAt(BombX3, BombY3-16)] == 6)
{
Screen->ComboD[ComboAt(BombX3, BombY3-16)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX3;
RndmItm->Y = BombY3 - 17;
}
}
if(Screen->ComboI[ComboAt(BombX3, BombY3+16)] == 6)
{
Screen->ComboD[ComboAt(BombX3, BombY3+16)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX3;
RndmItm->Y = BombY3 + 15;
}
}
if(Screen->ComboI[ComboAt(BombX3-16, BombY3)] == 6)
{
Screen->ComboD[ComboAt(BombX3-16, BombY3)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX3 - 16;
RndmItm->Y = BombY3 - 1;
}

}
if(Screen->ComboI[ComboAt(BombX3+16, BombY3)] == 6)
{
Screen->ComboD[ComboAt(BombX3+16, BombY3)] = 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = BombX3 + 16;
RndmItm->Y = BombY3 - 1;
}

}
}
}
if(Link->InputA)
{
CanCreate = false;
}
if(!Link->InputA)
{
CanCreate = true;
}
LastMap = Game->GetCurMap();
LastScreen = Game->GetCurScreen();
Waitframe();
}
}
}

(You can place six bombs in the full code, but I had to remove things to shrink the size.)

I have added code to allow you to place more than 1 Bomb at once...

When the first Bomb is placed, it explodes fine. Place another after blowing up the first, it works. Place more than one before the first explodes, and all explosions after the first wig out and don't vanish. I don't know why... And I even made arrays to simplify things!

pkmnfrk
01-04-2009, 05:37 PM
Give me a little bit of time, and I'll look at the script. I will also add more arrays, since your code will benefit from liberal usage.

Nimono
01-09-2009, 07:11 PM
I finally figured out my problem while turning some things into arrays. Apparently, whenever I needed to set the IsPlaced value for a Bomb to false after the explosion, I ALWAYS USED IsPlaced1, never anything else. Thus, the explosions never ended past the first, and problems were created. I finally fixed this. :D

Now to explore a new path- Bomberman is a custom enemy controlled by the global script, and the player is set elsewhere. :O

EDIT: Err... New problem. The Bomb's explosion refuses to damage enemies... It can't be due to its Step being 0, because as an lweapon, the Bomb affects enemies. (I changed it to a mere layered tile so it WON'T affect enemies...) But never did the fires hurt enemies...


if(IsPlaced[0])
{
if(bombtimer[0] > 0)
{
if(!isremote && !IsRem[0])
{
bombtimer[0]--;
}
Screen->DrawTile(2, BombX1, BombY1-2, BombTile[0], 1, 1, 7, 1, 0, 0, 0, 0, true, 128);
}
if(Link->InputB && isremote && IsRem[0])
{
bombtimer[0] = 0;
}
if(bombtimer[0] == 0)
{
bombcount--;
if(Screen->ComboS[ComboAt(BombX1, BombY1-16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire1[0] = Screen->LoadLWeapon(numwpns);
Fire1[0]->Step = 0;
Fire1[0]->HitHeight = 16;
Fire1[0]->HitWidth = 16;
Fire1[0]->Damage = 2;
Fire1[0]->X = BombX1;
Fire1[0]->Y = BombY1 - 16;
Fire1[0]->ASpeed = 8;
Fire1[0]->NumFrames = 8;
Fire1[0]->OriginalTile = 440;
Fire1[0]->DeadState = 40;
Fire1[0]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX1-16, BombY1)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire2[0] = Screen->LoadLWeapon(numwpns);
Fire2[0]->Step = 0;
Fire2[0]->HitHeight = 16;
Fire2[0]->HitWidth = 16;
Fire2[0]->Damage = 2;
Fire2[0]->X = BombX1 - 16;
Fire2[0]->Y = BombY1;
Fire2[0]->ASpeed = 8;
Fire2[0]->NumFrames = 8;
Fire2[0]->OriginalTile = 385;
Fire2[0]->DeadState = 40;
Fire2[0]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX1+16, BombY1)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire3[0] = Screen->LoadLWeapon(numwpns);
Fire3[0]->Step = 0;
Fire3[0]->HitHeight = 16;
Fire3[0]->HitWidth = 16;
Fire3[0]->Damage = 2;
Fire3[0]->X = BombX1 + 16;
Fire3[0]->Y = BombY1;
Fire3[0]->ASpeed = 8;
Fire3[0]->NumFrames = 8;
Fire3[0]->OriginalTile = 405;
Fire3[0]->DeadState = 40;
Fire3[0]->CSet = 7;
}
if(Screen->ComboS[ComboAt(BombX1, BombY1+16)] == 0)
{
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire4[0] = Screen->LoadLWeapon(numwpns);
Fire4[0]->Step = 0;
Fire4[0]->HitHeight = 16;
Fire4[0]->HitWidth = 16;
Fire4[0]->Damage = 2;
Fire4[0]->X = BombX1;
Fire4[0]->Y = BombY1 + 16;
Fire4[0]->ASpeed = 8;
Fire4[0]->NumFrames = 8;
Fire4[0]->OriginalTile = 500;
Fire4[0]->DeadState = 40;
Fire4[0]->CSet = 7;
}
Screen->CreateLWeapon(254);
int numwpns = Screen->NumLWeapons();
Fire5[0] = Screen->LoadLWeapon(numwpns);
Fire5[0]->Step = 0;
Fire5[1]->HitHeight = 16;
Fire5[1]->HitWidth = 16;
Fire5[0]->Damage = 2;
Fire5[0]->X = BombX1;
Fire5[0]->Y = BombY1;
Fire5[0]->ASpeed = 8;
Fire5[0]->NumFrames = 8;
Fire5[0]->OriginalTile = 480;
Fire5[0]->DeadState = 40;
Fire5[0]->CSet = 7;
Game->PlaySound(3);
IsPlaced[0] = false;

(Yes, I know that this isn't closed up properly. I don't feel like copying the rest of the code in that section because it's unrelated.)

There's the code for the fire...

Nimono
02-01-2009, 02:13 AM
Sorry for the bump and double-post, but I'd like some attention for this question.

First off, disregard my previous question, as I solved it already. (I need to find a weapon that stays in place and doesn't vanish when an enemy hits it, like the Fire and Golden Arrow do...but I don't know of any way to apply that effect to any other weapon.) Anyways, here comes the question.

Is there any way I can remove the current message on-screen? I'd like to have a message that remains on-screen until a new one appears, but if I do that, I'd have to delete the old message before displaying the new one, because new messages don't make old ones vanish... Pretty much what I'm doing is making a menu screen. You've got 3 choices, and I want a message to pop up when you have one selected that describes it. :/

Thanks in advance!

pkmnfrk
02-02-2009, 06:42 PM
I would kill for this functionality. Needless to say, it does not currently exist.

Gleeok
02-02-2009, 08:11 PM
(I need to find a weapon that stays in place and doesn't vanish when an enemy hits it, like the Fire and Golden Arrow do...but I don't know of any way to apply that effect to any other weapon.) Anyways, here comes the question.

You just have to use your imagination. ;) Look at the script file in my megaman tileset. The Hurricane Kick and Shuriken achieve this. If you've played Street Fighter then you know the controls for those yes?
http://www.mediafire.com/file/ztzwztmzyiy/MegaMan_Tileset_ver0.54.1.qst -Uses 887.




Is there any way I can remove the current message on-screen? I'd like to have a message that remains on-screen until a new one appears, but if I do that, I'd have to delete the old message before displaying the new one, because new messages don't make old ones vanish... Pretty much what I'm doing is making a menu screen. You've got 3 choices, and I want a message to pop up when you have one selected that describes it. :/

Thanks in advance!

You're going to have to script custom messages. It's not too hard though. pkmnfrk and I both have made a custom message script. there's a thread somewhere...around...here.....hmm....

Well good luck to you sir.

_L_
02-05-2009, 05:40 AM
Is there any way I can remove the current message on-screen?

Screen->Message(0);

EDIT: Actually, this doesn't work. Nevermind.

lucas92
02-05-2009, 05:02 PM
Pitwarp Link to the same screen? Though that method would restore the enemies on screen... :S

_L_
02-06-2009, 01:47 AM
Look here: http://shardstorm.com/

Nimono
02-06-2009, 05:45 PM
New problem, guys~



ffc script MonsterBlast
{
void run(int ID1, int ID2, int ID3, int ID4, int MaxNPC)
{
Screen->ComboT[0] = 0;
P1Score = 0;
P2Score = 0;
frame = 0;
Reload1 = 180;
Reload2 = 180;
FlameTimer1 = 0;
FlameTimer2 = 0;
IsSpecial = true;
while(true)
{
if(Screen->NumNPCs() < MaxNPC)
{
Waitframes(10);
int RandomNum = Rand(4);
if(RandomNum == 0)
{
Screen->CreateNPC(ID1);
}
else if(RandomNum == 1)
{
Screen->CreateNPC(ID2);
}
else if(RandomNum == 2)
{
Screen->CreateNPC(ID3);
}
else
{
Screen->CreateNPC(ID4);
}
for(int c=0; c<10; c++)
{
npc E = Screen->LoadNPC(c);
if(E->X == 0 && E->Y == 0)
{
E->X = 112;
E->Y = 80;
}
}
}
if(P1Score >= 9)
{
MaxNPC = 0;
for(int c=0; c<10; c++)
{
npc E = Screen->LoadNPC(c);
E->HP = 0;
}
Waitframes(120);
Screen->ComboT[0] = 94;
}
else if(P2Score >= 9)
{
MaxNPC = 0;
for(int c=0; c<10; c++)
{
npc E = Screen->LoadNPC(c);
E->HP = 0;
}
Waitframes(120);
Screen->ComboT[0] = 95;
}
Waitframe();
}
}
}

This is part of the multiplayer minigame I scripted. (Don't ask about it- I posted it at PureZC and CZC. Go look for it if you REALLY want to play it. ;)) This is just the check for if someone's won yet...and the creating of the enemies when destroyed. Anyways, all that works fine. What DON'T are the parts that change a combo to auto-warp. THOSE works fine until you warp. They warp you to a victory screen, but when you warp there, YOU AUTOMATICALLY WARP USING THE SIDE WARP B!



ffc script VictoryScreen
{
void run()
{
P1Score = 0;
P2Score = 0;
bool AStop = false;
bool BStop = false;
IsSpecial = false;
while(true)
{
if(Link->InputA && !AStop)
{
AStop = true;
Screen->ComboT[0] = 94;
}
if(Link->InputB && !BStop)
{
BStop = true;
Screen->ComboT[0] = 95;
}
if(!Link->InputA)
{
AStop = false;
}
if(!Link->InputB)
{
BStop = false;
}
Waitframe();
}
}
}

NONE of those buttons are pressed when you first enter the screen, yet the Combo in Position 0 automatically gets set to Combo Type 95, Auto Warp B. Now, this isn't a problem with the Victory Screen script...



ffc script StoryMode
{
void run()
{
IsDisallow = false;
}
}

All this does is re-enables the normal use of Bombs for the Single-Player Mode. Yet, if you play the Minigame before going to this FFC's screen, when you enter it, YOU WARP AGAIN!! I CANNOT understand or figure out why the HECK this is happening. Please help! REWARD: 1 Thank You. *runs*

lucas92
02-06-2009, 11:21 PM
Maybe try putting a Waitframes(60=1 second); after warping the player to let the time for Link to finish warping. Also, it would be smart that you disable the input that has been pushed for at least one frame.

I don't quite understand the script itself though.

Nimono
02-08-2009, 11:56 PM
No, that didn't help anything, lucas. Hmm... Maybe it's shared combos? ...No, that wouldn't make sense for the victory screen. Hmm.. Oh well.

Another problem now.


void DestroyWall(int X, int Y, int time, int Bomb)
{
int Items[8] = {0,0,0,0,0,0,123,123};
int randomnumber;
bool Stop1 = false;
bool Stop2 = false;
bool Stop3 = false;
bool Stop4 = false;
for(int i=0; i<=Game->Counter[5]; i++)
{
if((Screen->ComboS[ComboAt(X, Y-((i*16)+16))] == 0 && !Stop1))
{
if(Screen->ComboI[ComboAt(X, Y-(i*16))] == 6)
{
Screen->ComboD[ComboAt(X, Y-(i*16))] += 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = X;
RndmItm->Y = Y - (i*16);
}
}
}
else
{
Stop1 = true;
}
if(Screen->ComboS[ComboAt(X, Y+((i*16)-16))] == 0 && !Stop2)
{
if(Screen->ComboI[ComboAt(X, Y+(i*16))] == 6)
{
Screen->ComboD[ComboAt(X, Y+(i*16))] += 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = X;
RndmItm->Y = Y + (i*16);
}
}
}
else
{
Stop2 = true;
}
if(Screen->ComboS[ComboAt(X-((i*16)+16), Y)] == 0 && !Stop3)
{
if(Screen->ComboI[ComboAt(X-(i*16), Y)] == 6)
{
Screen->ComboD[ComboAt(X-(i*16), Y)] += 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = X - (i*16);
RndmItm->Y = Y;
}
}
}
else
{
Stop3 = true;
}
if(Screen->ComboS[ComboAt(X+((i*16)-16), Y)] == 0 && !Stop4)
{
if(Screen->ComboI[ComboAt(X+(i*16), Y)] == 6)
{
Screen->ComboD[ComboAt(X+(i*16), Y)] += 1;
randomnumber = Floor(Rand(9));
if(Items[randomnumber] != 0)
{
Screen->CreateItem(Items[randomnumber]);
int numitms = Screen->NumItems();
item RndmItm = Screen->LoadItem(numitms);
RndmItm->X = X + (i*16);
RndmItm->Y = Y;
}
}
}
else
{
Stop4 = true;
}
}
}

I run this when my Bomb explodes so I can keep it seperate from the rest of the code, and thus, it looks just a wee bit neater. ...not much, though. Anyways, I have a problem with this stuff. If a block next to the Bomb is solid, and it's set to be Bombable, the wall is changed to the next combo, which removes it, as it's a cycling combo. Minor problem! For some reason, you cannot blow up walls below you unless the explosion is also blocked on the left and right, or maybe just left. Likewise, you cannot blow up a wall on your right unless the explosion is blocked on the BOTTOM! So, you cannot blow up more than one wall at a time, no matter how many walls your explosions are hitting. And I don't even know why the heck this is! Everything looks perfectly fine, right?! D:

HeroOfFire
02-18-2009, 03:03 AM
I couldn't help but notice this:


for(int i=0; i<=Game->Counter[5]; i++)


if(Screen->ComboI[ComboAt(X, Y-(i*16))] == 6)

Because your loop starts at 0, your first pass will always look at the combo at X, Y for all four directions.

More interesting:


if(Screen->ComboS[ComboAt(X, Y+((i*16)-16))] == 0 && !Stop2)

Evaluating the math here...

i Y
0 Y + ((0) - 16) = Y - 16
1 Y + ((16) - 16) = Y
2 Y + ((32) - 16) = Y + 16
3 Y + ((48) - 16) = Y + 32
etc...

I understand you're testing for solid combos, but the math of these if statements have me a little confused which combo you're trying to check.

Perhaps your bug is testing the wrong combos due to bad ComboAt math?

Nimono
02-18-2009, 01:51 PM
Perhaps your bug is testing the wrong combos due to bad ComboAt math?

Perhaps. I don't think you read the whole thing, though.

I'm not checking one direction per loop. If you had read on, you would've seen that I CHECK ALL FOUR DIRECTIONS, using the same variable. Also, I KNOW it starts at 0. It's SUPPOSED to! It increases according to the value of the Key counter, which I'm using for the explosive range. (That's how far the explosion reaches in 16x16 blocks. Anything in the range is hurt or killed. Or, in the case of soft blocks, destroyed.) I have it multiplied by 16 because 16 pixels is one combo. i=2 gives 32 pixels, so... It works. As for the combo I'm checking? The combo right before the one you're checking now. If it's solid and can be destroyed, stop checking for that direction. That way, the explosions can't reach behind the solid blocks. (They will if you get a Penetrating Bomb item, though- but I'll add that in once the actual destruction of the blocks is finished.)

But now that I think about it, you might be on to something about that i=0 thing. Perhaps it really IS messing things up... I'll check.

Edit: Yes, I figured it out! It was the + I was doing for left and up. That explains why I couldn't explode in those directions most of the time. Changing i=0 to i=1 also made it so no matter what, I'd be able to explode any wall if it could be blown up, if it's within range. Okay, I'm done with that part now. Time to add in the part to destroy enemies.