Jump to content

Photo

GameBoy style Compass->sfx script


  • Please log in to reply
18 replies to this topic

#1 Bayta

Bayta

    Follower of Destiny

  • Members
  • Real Name:Robin Evans
  • Location:Suffolk County, NY

Posted 06 February 2008 - 08:24 PM

You know how in the GameBoy Zelda games, if you had the compass, and you entered a room with a key in it somewhere, a tone would play? Well I've scripted it! Finally, a script of my own design!



CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
  void run(int itm, int sfx){ //these are the D0 and D1 variables. They are for the item ID, and sfx number. For most, it should be 22 and 7.
    if(true);{
      if(Link->Item[itm]);{
        Game->PlaySound(sfx);
      }
    }
  }
}




Note, it has not actually been tested. It should compile correctly though. I actually just put this together 5 minutes ago. icon_heh.gif



#2 Russ

Russ

    Caelan, the Encouraging

  • Administrators
  • Location:Washington

Posted 06 February 2008 - 08:32 PM

Wow, this should be pretty useful. Nice work.

#3 Joe123

Joe123

    Retired

  • Members

Posted 07 February 2008 - 02:54 AM

Well, you'll need something a bit more like this:

CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        if(Game->LItems[4]){
            Game->PlaySound(sfx);
        }
    }
}

Firstly, if(true){ is pointless.
It'll just always run that bit of code, and only ever once.
You could've meant while(true){, but you don't need a while loop in this script.

CODE
if(something);{

is wrong, whereas
CODE
if(something){

is corrent.
You don't end if requirements with a semicolon.

Also, I'm afraid checking whether Link has the compass isn't as easy as 'if(Link->Item[22]){'.
When you pick up the compass, the only thing that is 'item ID' 22, is the sprite that appears on the screen that Link then grabs.
Once the game loads it into your inventory, it is no longer 'item ID' 22, it is 'the current DMap's compass item'.
This is the same for boss key, map and triforce piece.

This means you have to access it with this array:
CODE
int LItems[]
* The level items of level i currently under the posession of the player,
* where i is the index used to access this array. Each element of this
* array consists of flags ORed (|) together; use the LI_ constants in
* std.zh to set or compare these values.

Which is sort of what I wrote, although my code won't actually work either because I don't understand how this function works.

Different flags ORed together?
Eh?

EDIT:
Ah, after a little thinking, I have produced these:
CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        if(Game->LItems[lvnum] == 4|5|6|12|20){
            Game->PlaySound(sfx);
        }
    }
}


CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        if(Game->LItems[lvnum] == 4){
            Game->PlaySound(sfx);
        }
    }
}


CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        if(Game->LItems[lvum] == 4 || Game->LItems[lvum] == 5 || Game->LItems[lvum] == 6 || Game->LItems[lvum] == 12 || Game->LItems[lvum] == 20){
            Game->PlaySound(sfx);
        }
    }
}


You could try any one of those three and see if they work.
In fact, however, I think the command uses binary, which I'm just going to research icon_smile.gif

EDIT2:
Ok, I have come to the conclusion that none of the above scripts will work, and I am currently devisng one that will.
However, I'm under the impression that I need to be able to express 16 in 4-bit binary, which seems rather illogical to me icon_confused2.gif

EDIT3:
Right.
CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        int cmp = 0100b;
        int curitems = Game->LItems[lvnum];
        int chk = cmp & curitems;
        if(chk == 0100b){
            Game->PlaySound(sfx);
        }
    }
}


That should work if Link has the compass, but not if he has the compass and the boss key, due to not being able to express 16 in a 4 bit byte.
When I work out how to do this (I think I'm supposed to use 2 4-bit bytes, but I'm not sure of how to do it properly and make it work), then I'll update it.

Edited by Joe123, 07 February 2008 - 12:28 PM.


#4 Bayta

Bayta

    Follower of Destiny

  • Members
  • Real Name:Robin Evans
  • Location:Suffolk County, NY

Posted 07 February 2008 - 01:52 PM

Wow, I was way off. icon_eek.gif I don't even know how to use most of those commands. I guess I'll try that though, to see if it works.

#5 Joe123

Joe123

    Retired

  • Members

Posted 07 February 2008 - 02:02 PM

Yeah, I don't really either, I'm making it up as I go along =P
Let me know if it works.

I don't really understand binary too well, but I think what I've written is correct.

#6 Bayta

Bayta

    Follower of Destiny

  • Members
  • Real Name:Robin Evans
  • Location:Suffolk County, NY

Posted 07 February 2008 - 02:23 PM

I've just testd it, and it seems to work perfectly! Even if I have the Boss Key as well!

Edit: Something I didn't take into consideration though, is that the sfx will still play even if there isn't a key on the screen. Let's race to see who can fix that quicker. icon_razz.gif

Edited by Beta Link, 07 February 2008 - 02:28 PM.


#7 Joe123

Joe123

    Retired

  • Members

Posted 07 February 2008 - 02:27 PM

Oh well, that's nice icon_smile.gif

I like it when things work, especially when I don't really understand how I'm doing them.
(Well actaully, tell a lie, I did spend quite a while looking up binary and/or, but you know, I've never done it before or whatever)

#8 Bayta

Bayta

    Follower of Destiny

  • Members
  • Real Name:Robin Evans
  • Location:Suffolk County, NY

Posted 07 February 2008 - 02:44 PM

Hmm... I got this, but it won't compile correctly. I really hope I'm on the right track this time though.

CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        int cmp = 0100b;
        int curitems = Game->LItems[lvnum];
        int chk = cmp & curitems;
        int itm = 84;
        if(chk == 0100b && NumItems(itm)){
            Game->PlaySound(sfx);
            }
        }
    }

Edited by Beta Link, 07 February 2008 - 02:46 PM.


#9 Joe123

Joe123

    Retired

  • Members

Posted 07 February 2008 - 05:00 PM

Well, what are you trying to do with that number?

I'm not sure what NumItems does, but I think it counts the number of items currently on-screen, so 84 seems like a rather unreasonable answer.

Also, here's a little general note on how to use commands from zscript.txt, which you missed in what you'd posted.

All (well, most of) the statements in that text documents need a pointer to function.
This doesn't include the first section, but all other sections (FFC, Link, Screen, Global, Item, ItemClass, NPC) must use pointers to access their statements.

The pointer you used is in the 'Screen' section, so you access it like this:
CODE
NumItems()
Screen->NumItems();

However, I don't think you're supposed to put anything inside the brackets, because all that it does is return the number of items on the screen, there's no need for an input (what you put is like putting Waitframe(5); and expecting it to wait for 5 frames).

I don't know what it was you did want to do though, so if you tell me I can help icon_smile.gif

EDIT: You are missing an } off the end by the way, I assume that's in the script file though.

EDIT2: Oh no you aren't.
Right, I'm going to explain scope, because it's quite important and you seem to have got it a little wrong.

Quote from AGN:
CODE
//global
script{
    // a
    void run(){
    int foo;
         // b
        while(true){
            // c
            if(1){
                //d
            }
            //c
            if(2){
                //d
                if(3){
                    //e
                }
                //d
            }
            //c
        Waitframe();
        }
        //b
    }
    //a
}

The Global scope contains everything in your script file
Scope A contains everything within the script
Scope B contains everything within the void run
Scope C contains everything within the while loop
Scope D could be at the level of both if(1) and if(2)
Scope E contains evething within if(3)

So the while loop is within scope b, but things in the while loop are at scope c.
Different numbers of indentations show different scopes, so scope a is at one indentation, whereas scope d is at 4, within both ifs.

I always put my Waitframe() on the same scope as the while, even though it should technically be at scope c, and I always declare all integers on the same scope as the void run(), although they should tecnically be at scope b.
This is all theoretical, because you could write your script out on one line if you wanted, but it makes it a lot easier to read if you get your scope correct.


That's my explanation of the scope of scripts.
In your if command, you put this:
CODE
//this is Scope A
if(something){
    //this is Scope B
    }


When it should have been this:
CODE
//this is Scope A
if(something){
    //this is Scope B
}


Everything that opens a new scope should end on the same scope.
What you put in your script ended if a scope early, and then void run, and then the script.
I actually couldn't read that unless I went back and looked very carefully.

Edited by Joe123, 07 February 2008 - 05:05 PM.


#10 Nimono

Nimono

    Ultra Miyoa Extraordinaire!

  • Members
  • Real Name:Matthew
  • Location:Static Void Kingdom

Posted 07 February 2008 - 05:14 PM

QUOTE(Joe123 @ Feb 7 2008, 05:00 PM) View Post

In your if command, you put this:
CODE
//this is Scope A
if(something){
    //this is Scope B
    }


When it should have been this:
CODE
//this is Scope A
if(something){
    //this is Scope B
}


Everything that opens a new scope should end on the same scope.
What you put in your script ended if a scope early, and then void run, and then the script.
I actually couldn't read that unless I went back and looked very carefully.

Wait wait wait... WTF? Are you saying that his problem is that he did a tab on that }? If so, I seriously have to question your brain... I'm sorry, but position/indentation/whatever of the braces DO NOT MATTER so long as they're in the right order. For example...

CODE
if(foo == bar)
{
   if(foobar != bar)
  {
      foobar = bar + foo;
      }
   }


will do the same thing as:


CODE
if(foo == bar)
{
   if(foobar != bar)
  {
      foobar = bar + foo;
   }
}


And no, you don't need to put the starting brace on the same line as the if. So long as it and the closing brace are used, the compiler is happy.

#11 Joe123

Joe123

    Retired

  • Members

Posted 07 February 2008 - 05:18 PM

I know the compiler is happy, it just makes the script very hard to read >_<

QUOTE
This is all theoretical, because you could write your script out on one line if you wanted, but it makes it a lot easier to read if you get your scope correct.


I actually misread his script because he didn't put it on the right line.

EDIT: Also if you put the starting brace on the next line it makes it harder to read too in my opinion =P

Edited by Joe123, 07 February 2008 - 05:47 PM.


#12 Bayta

Bayta

    Follower of Destiny

  • Members
  • Real Name:Robin Evans
  • Location:Suffolk County, NY

Posted 07 February 2008 - 05:46 PM

Heh, that 84 there, is the ID of Level Specific Keys. I just put in the totally wrong command. icon_sweat.gif I think I need to rethink what I'm doing. I think I understand it now.

Edit: Nope. Still won't compile correctly... And I have no idea what I'm doing, do I? icon_razz.gif

CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        int cmp = 0100b;
        int curitems = Game->LItems[lvnum];
        int chk = cmp & curitems;
        if(chk == 0100b && Screen->NumItems(1)){
            Game->PlaySound(sfx);
            }
        }
    }

Edited by Beta Link, 07 February 2008 - 05:54 PM.


#13 Joe123

Joe123

    Retired

  • Members

Posted 07 February 2008 - 05:49 PM

Well why do you need to do that?

Don't you just want to apply the script only to screens with level specific keys?

#14 Bayta

Bayta

    Follower of Destiny

  • Members
  • Real Name:Robin Evans
  • Location:Suffolk County, NY

Posted 07 February 2008 - 06:10 PM

Well yeah, but I don't know how to do that, and I can't find the right command in zscript.txt. icon_confused.gif What I had tried to do with that last script, is that the sfx would only play if Link had the compass, and there was one item in the room. Obviously I did it wrong though. icon_confused.gif

#15 Joe123

Joe123

    Retired

  • Members

Posted 07 February 2008 - 06:16 PM

CODE
ffc script compass{ //This script plays a certain sfx upon entering the room if Link has a certain item.
    void run(int sfx, int lvnum){ // D0 is for the and sfx number. For most, it should be 7. lvnum is the level number of
                      // the DMap you are getting the compass on.
        int cmp = 0100b;
        int curitems = Game->LItems[lvnum];
        int chk = cmp & curitems;
        if(chk == 0100b && Screen->NumItems() == 1){
            Game->PlaySound(sfx);
        }
    }
}


You were close, but it works like that.
You don't need to put anything inside those brackets at the end of NumItems, when you type out 'Screen->NumItems()', ZC reads that whole statement as just one numerical value.

Why do you want it to work like that by the way?
I don't see the benefit.
Now it won't play the tone if the key is inside a chest ot whatever.


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users