I have some stuff I'd like help with
#16
Posted 21 July 2010 - 03:21 PM
#17
Posted 21 July 2010 - 03:25 PM
aLttP had large scrollable areas rather than discrete screens so it didn't really work in the same way.
#18
Posted 21 July 2010 - 04:48 PM
#19
Posted 21 July 2010 - 04:50 PM
#20
Posted 21 July 2010 - 05:10 PM
void run(){
if(Link->MP > 16) UseCandle=1;
else Game->PlaySound(Negative);
}
}
Umm, yeah. Gotta add the Candle part at the top...
void run(){
UseBall = 0;
while(true){
doBottleFairy();
BallAndChain();
warpcoreaction();
Candle();
Waitframe();
}
}
void BallAndChain(){
if(UseBall == 0) return;
else if(UseBall < 25) ThrowBall();
else SpinBall();
....
Like that. And now
if (UseCandle == 0);
if (Link->Dir = 0);
I need to spawn an LWeapon here, yeah? So I need to define the sprite graphic, but beyond that I'm not so sure...
Edited by Eragon615, 21 July 2010 - 05:11 PM.
#21
Posted 21 July 2010 - 05:14 PM
also there's a big discretion to be made between '==' and '='. You've got them mixed up.
Well what do you want the lweapon to do exactly?
What do you mean by 'define the sprite graphic'?
#22
Posted 21 July 2010 - 05:31 PM
I want to spawn a little flame in front of Link. I set up the tiles to make it last about a half second. So I define the sprite of the flame as like T_FLAME = 101.
Then I need to spawn that Sprite with the same properties as the original candle so it can still trigger burn flags, and so it can be an enemy weakness.
As for my mistakes, I think I understand the = vs. ==, == is "is it" and = is "it is". I don't understand return though. Care to clarify?
#23
Posted 21 July 2010 - 06:19 PM
return says to return to the line where the function was called...basically
void returnit()
{
{
if(true) return;
}
int a = 99;
}
here int a is never 99 as the function returns beforehand. The function must also return it's return type, ex;
int func()
{
return; // error!
return ffc; // not integral type!
return 23; // OK
}
Edited by Gleeok, 21 July 2010 - 06:23 PM.
#24
Posted 21 July 2010 - 06:33 PM
Okay, I looked through std.zh but didn't really find what I was looking for. I'm just trying to make the flame appear in front of Link, based on the direction he's facing, and deal fire damage or trigger burn flags for the duration of it's animation.
Edited by Eragon615, 21 July 2010 - 07:15 PM.
#25
Posted 22 July 2010 - 03:49 AM
When you write a 'function' it's like saying 'take this chunk of code and place it somewhere else'.
Inside the function, any variables you declare only last for the duration of the function and aren't passed back to where the function is called:
{
int a = x * y;
}
* script foo
{
void run()
{
int b = 5;
int c = 6;
int d = multiplier(b, c);
Trace(d);
}
}
Inside the function, I've correctly worked out the value of 'x * y', but I haven't told the compiler to send it back to where the function was called anywhere.
The way you do that is with 'return' - as Gleeok said it means 'pass this value (or object or pointer) back to where the function was called).
So if it was written like this instead:
{
int a = x * y;
return a; //now we send back the value
}
* script foo
{
void run()
{
int b = 5;
int c = 6;
int d = multiplier(b, c);
Trace(d);
}
}
The word before the name of the function is what type it returns; in this case the function returns a float. Sometimes though I might want my function not to return anything, and in which case I declare it to be 'void':
{
Link->X = x;
Link->Y = y;
}
If a function is 'void' it can't return any value, so the 'return' keyword just ends it's execution at that point and brings the code back to where the function was called. Say we want to place Link but only if he's not currently frozen:
{
if(Link->Action == LA_FROZEN)
return;
Link->X = x;
Link->Y = y;
}
You could equally write it like this:
{
if(Link->Action != LA_FROZEN)
{
Link->X = x;
Link->Y = y;
}
}
To make an lweapon that's not hard coded appear you just use one of the 'LW_SCRIPT*' lweapon IDs from std.zh, a bit like this:
If I wanted to make an lweapon, place it and give it a graphic I'd do it like this:
* script foo
{
void run()
{
lweapon l = CreateLWeaponAt(LW_SCRIPT*, some coordinates infront of Link);
//CreateLWeaponAt is another function declared in std.zh which returns lweapon; have a look to see how it works
l->UseSprite(WSP_FLAME);
l->Damage = something;
}
}
#26
Posted 22 July 2010 - 07:34 PM
const int WSP_FLAME = 88;
const int SFX_NEG = 44;
int UseCandle;
global script Slot2{
void run(){
while(true){
NewCandle();
Waitframe();
}
}
void NewCandle(){
if (UseCandle == 0) return;
if (Link->Dir == 0){
Link->Action = LA_ATTACKING;
lweapon Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X+8, Link->Y+24);
Flame->UseSprite(WSP_FLAME);
Flame->Damage = 2;}
else if (Link->Dir == 1){
Link->Action = LA_ATTACKING;
lweapon Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X+8, Link->Y-8);
Flame->UseSprite(WSP_FLAME);
Flame->Damage = 2;}
else if (Link->Dir == 2){
Link->Action = LA_ATTACKING;
lweapon Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X-8, Link->Y+8);
Flame->UseSprite(WSP_FLAME);
Flame->Damage = 2;}
else if (Link->Dir == 3){
Link->Action = LA_ATTACKING;
lweapon Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X+24, Link->Y+8);
Flame->UseSprite(WSP_FLAME);
Flame->Damage = 2;}
Link->MP -= 16
UseCandle = 0
}
}
item script Candle{
void run(){
if(Link->MP >= 16) UseCandle ++;
else Game->PlaySound(SFX_NEG);
}
}
So, first issue. I thought Link->Dir was 0 = Up, 1 = Down, 2 = Left, and 3 = Right. So based on a coordinate plane my Flames would be right. Except they aren't. Now I hear somewhere that Link->X or Y had to be + 8 to get centered. Was that wrong? Because my Left and Right flames are sorta off but at least in front of me, but my Up or Down Flames spawn behind me...
Also, how do I cause the flame to disappear after a time? Because right now it stays on screen until it hits an enemy. I do know you have to give it Dead State, but that's all I know.
How do I make a Burn->Next Flag? Say flag 99.
And last but not least, I do want to make my new candle like the original, that is, only one use per screen, but once you use it I want the graphic for it to change to an unlit candle. Then it relights on the next screen if you still have magic.
#27
Posted 23 July 2010 - 07:25 AM
I'd do it a bit more like this though, makes the code slightly shorter (a few of the things you're doing in the conditional blocks are the same in each one, so you might as well put them outside):
const int WSP_FLAME = 88;
const int SFX_NEG = 44;
int UseCandle;
global script Slot2{
void run(){
while(true){
NewCandle();
Waitframe();
}
}
void NewCandle(){
if (UseCandle == 0) return;
lweapon Flame;
if (Link->Dir == DIR_UP) //using the constants makes it more readable
Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X+8, Link->Y+24);
else if (Link->Dir == DIR_DOWN)
Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X+8, Link->Y-8);
else if (Link->Dir == DIR_LEFT)
Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X-8, Link->Y+8);
else if (Link->Dir == DIR_RIGHT)
Flame = CreateLWeaponAt(LW_SCRIPT1, Link->X+24, Link->Y+8);
Link->Action = LA_ATTACKING;
Flame->UseSprite(WSP_FLAME);
Flame->Damage = 2;
Link->MP -= 16
UseCandle = 0
}
}
item script Candle{
void run(){
if(Link->MP >= 16) UseCandle ++;
else Game->PlaySound(SFX_NEG);
}
}
Link's X and Y coordinates refer to the top left corner of his hitbox.
I have a couple of functions for putting things near Link, they go like this:
{
int x = 0;
if(dir == DIR_UP || dir == DIR_DOWN)
x = 8;
else if(dir == DIR_RIGHT)
x = 16;
return x;
}
int AtFrontY(int dir)
{
int y = 0;
if(dir == DIR_DOWN)
y = 16;
else if(dir == DIR_LEFT || dir == DIR_RIGHT)
y = 8;
return y;
}
int InFrontX(int dir, int dist)
{
int x = 0;
if(dir == DIR_LEFT)
x = -16 + dist;
else if(dir == DIR_RIGHT)
x = 16 - dist;
return x;
}
int InFrontY(int dir, int dist)
{
int y = 0;
if(dir == DIR_UP)
y = -16 + dist;
else if(dir == DIR_DOWN)
y = 16 - dist;
return y;
}
lweapon NextToLink(int id, int distx, int disty)
{
lweapon l = CreateLWeaponAt(id, Link->X + InFrontX(Link->Dir, distx), Link->Y + InFrontY(Link->Dir, disty));
l->Dir = Link->Dir;
return l;
}
lweapon NextToLink(int id, int dist)
{
return NextToLink(id, dist, dist);
}
The 'dist' arguments kind of place the item a little bit further or nearer to Link, so you use it like this:
{
void run()
{
while(true)
{
LWeapons();
Waitframe();
}
}
void LWeapons()
{
lweapon l;
for(int i = Screen->NumLWeapons(); i > 0; i--)
{
l = Screen->LoadLWeapon(i);
if(l->ID == LW_SCRIPT1)
Flame(l);
else if(l->ID == AnotherLWeapon)
DoThatLWeaponsAction(l);
}
}
void Flame(lweapon Flame)
{
if(ComboFI(l->X, l->Y, CF_SCRIPT1))
{
l->DeadState = 0;
Screen->TriggerSecrets();
}
}
}
If there's any of that you don't get ask and I'll explain what it's doing.
Then there'd be a section in your global script that checked if you'd changed screen and then it'd 're-light' the candle by giving you the level 2 item if you have the level 1 one.
#28
Posted 23 July 2010 - 12:16 PM
or something like that. Any suggestions there?
I think I can look through some other weapon codes and maybe figure how deadstates work. It's just the command and a timer, right?
And as for triggering the flag, I want it like the trees in the Oracle games that just burn and disappear, not the trigger flags like we have right now. So I think the Screen->TriggerSecrets(); is unnecessary. I've already got your ball and chain script, so flag 98 is taken, but maybe flag 99 could be Flame->Next. I can most likely copy you example script and get it to work, but since you're all about understanding, I'm going to ask a few questions. Actually, I don't really get that at all, haha. I mean, this part
{
void run()
{
while(true)
{
LWeapons();
Waitframe();
}
}
I understand of course, but once you get into this
{
lweapon l;
for(int i = Screen->NumLWeapons(); i > 0; i--)
{
l = Screen->LoadLWeapon(i);
if(l->ID == LW_SCRIPT1)
Flame(l);
else if(l->ID == AnotherLWeapon)
DoThatLWeaponsAction(l);
}
}
I start to lose the reasoning. And here
{
if(ComboFI(l->X, l->Y, CF_SCRIPT1))
{
l->DeadState = 0;
Screen->TriggerSecrets();
}
}
}
is where it checks for the flag, right? If the combo on the same tile as the lweapon is the flag, deadstate the lweapon and trigger the secrets. 'Xcept when did you tell it which flag to check for? And instead of secrets, again, I'd really like it to be a ->Next style flag.
#29
Posted 23 July 2010 - 05:18 PM
or something like that. Any suggestions there?
Yeah it's a bit like that. I'd do this:
global script Slot2
{
void run()
{
while(true)
{
ChangeScreenCheck();
Waitframe();
}
}
void ChangeScreenCheck()
{
if(LastScreen != Game->GetCurDMapScreen)
OnChangeScreen();
LastScreen = Game->GetCurDMapScreen();
}
void OnChangeScreen()
{
//What you want to do when screen changes goes here
}
}
*PART WAS HERE*
is where it checks for the flag, right? If the combo on the same tile as the lweapon is the flag, deadstate the lweapon and trigger the secrets. 'Xcept when did you tell it which flag to check for? And instead of secrets, again, I'd really like it to be a ->Next style flag.
{
lweapon l; //Declare a pointer that we're going to store lweapons in
for(int i = Screen->NumLWeapons(); i > 0; i--) //This loop iterates over each lweapon on the screen. lweapons are
{ //numbered from '1' to 'Screen->NumLWeapons' inclusive, so now we've
//got some code that has 'i' as the number of each lweapon in turn
l = Screen->LoadLWeapon(i); //Load the 'ith' lweapon into l
if(l->ID == LW_SCRIPT1) //If the lweapon's ID is LW_SCRIPT1 (the type that our flame is)
Flame(l); //Run the flame code
else if(l->ID == AnotherLWeapon) //You might want to do some stuff with other lweapon types too
DoThatLWeaponsAction(l);
}
}
{ //rather than 'l' which was just a generic lweapon)
if(ComboFI(l->X, l->Y, CF_SCRIPT1)) //If the flag at the position of the lweapon is CF_SCRIPT1 (or 2 or whatever)
{
l->DeadState = 0; //Kill the lweapon
Screen->TriggerSecrets(); //Trigger secrets (or instead, Screen->ComboD[ComboAt(Flame->X, Flame->Y)]++;
//would move the combo to the next one)
}
}
}
#30
Posted 24 July 2010 - 03:23 AM
{
lweapon l; //Declare a pointer that we're going to store lweapons in
for(int i = Screen->NumLWeapons(); i > 0; i--) //This loop iterates over each lweapon on the screen. lweapons are
{ //numbered from '1' to 'Screen->NumLWeapons' inclusive, so now we've
//got some code that has 'i' as the number of each lweapon in turn
l = Screen->LoadLWeapon(i); //Load the 'ith' lweapon into l
if(l->ID == LW_SCRIPT1) //If the lweapon's ID is LW_SCRIPT1 (the type that our flame is)
Flame(l); //Run the flame code
else if(l->ID == AnotherLWeapon) //You might want to do some stuff with other lweapon types too
DoThatLWeaponsAction(l);
}
}
I understand how it works now, but what is the purpose? My code works just fine right now. Does this just put all the LWeapons into a block so I can call them with a simple command? Let me review here... This code puts an ID into the pointer l. If it's script 1 it runs the flame code, or if it's something else it runs another lweapon. So by using LWeapons() I just define the ID and it pulls the script for me? I get the feeling I'm way off here... At least I'm sure I've got the rest down.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users