Jump to content

Photo

Moving an Item


  • Please log in to reply
13 replies to this topic

#1 klop422

klop422

    Guess I'm full of monsters and treasure

  • Members
  • Real Name:Not George
  • Location:Planet Earth

Posted 29 April 2018 - 07:27 AM

Could I have a script where, after the player reads a signpost (using the Signpost script), it moves the room item to either the player's position or the position of an ffc? If possible, it shouldn't appear underneath the player until the string(s) finish(es).

If the item has to be moved before you read the string (where it would appear underneath the player and look weird), could I have another script where you can pick up one item and have Link hold up another one? Possibly an alteration to the Item Bundle script.



#2 Gégé

Gégé

    Senior

  • Members
  • Real Name:Gérard
  • Location:France

Posted 01 May 2018 - 11:40 AM

Untested
d0 : item id (if not present, quit)
d1 : string message
d2 : button
d3 : item position (instantly) 0 = Link; 1 = FFC 

ffc script MessageItem{
    void run(int id, int m, int press, int type){
        for(int i = 0; i <= Screen->NumItems(); i++){
            item itm = Screen->LoadItem(i);
            if(itm->ID != id)Quit();
        }
        int loc = ComboAt(this->X, this->Y);
        bool Input = false;
        while(true){
            if(Link->Z == 0 && (Link->Dir == DIR_UP && Link->Y == ComboY(loc)+8 && Abs(Link->X-ComboX(loc)) < 8)){
                if(SelectPressInput(press))Input = true;
                if(Input){
                    if(type <= 0){
                        for(int i = 0; i <= Screen->NumItems(); i++){
                            item itm = Screen->LoadItem(i);
                            if(itm->ID == id){
                                itm->X = Link->X;
                                itm->Y = Link->Y;
                            }
                        }
                    }
                    else{
                        for(int i = 0; i <= Screen->NumItems(); i++){
                            item itm = Screen->LoadItem(i);
                            if(itm->ID == id){
                                itm->X = this->X;
                                itm->Y = this->Y;
                            }
                        }
                    }
                    break;
                }
                else Screen->Message(m);
            }
            Waitframe();
        }
    }
}

bool SelectPressInput(int input){
    if(input == 0)return Link->PressA;
    else if(input == 1)return Link->PressB;
    else if(input == 2)return Link->PressL;
    else if(input == 3)return Link->PressR;
}


#3 klop422

klop422

    Guess I'm full of monsters and treasure

  • Members
  • Real Name:Not George
  • Location:Planet Earth

Posted 01 May 2018 - 01:39 PM

I've been trying to get this to work, but it appears not to respond to anything - I made a sign as usual (worked as a signpost) but then changed the ffc to this one and changed the D variables, and it didn't respond at all.



#4 Gégé

Gégé

    Senior

  • Members
  • Real Name:Gérard
  • Location:France

Posted 11 May 2018 - 09:52 AM

d0 : item id
d1 : string message
d2 : button
d3 : item position (instantly) 0 = Link; 1 = FFC 
d4 : Screen->D variable
 
ffc script MessageItem{
    void run(int id, int m, int press, int type, int screend){
        if(Screen->D[screend] > 0)Quit();
        int loc = ComboAt(this->X, this->Y);
        bool Input = false;
        while(true){
            if(Link->Z == 0 && (Link->Dir == DIR_UP && Link->Y == ComboY(loc)+8 && Abs(Link->X-ComboX(loc)) < 8)){ //if collision
                if(SelectPressInput(press))Input = true; //input ok
                if(Input){ //if input
                    if(type <= 0){
                        for(int i = 0; i <= Screen->NumItems(); i++){
                            item itm = Screen->LoadItem(i);
                            if(itm->ID == id){
                                itm->X = Link->X;
                                itm->Y = Link->Y;
                            }
                        }
                    }
                    else{
                        for(int i = 0; i <= Screen->NumItems(); i++){
                            item itm = Screen->LoadItem(i);
                            if(itm->ID == id){
                                itm->X = this->X;
                                itm->Y = this->Y;
                            }
                        }
                    }
                    Screen->D[screend] = 1;
                    break;
                }
                else Screen->Message(m);
            }
            Waitframe();
        }
    }
}
 
bool SelectPressInput(int input){
    if(input == 0)return Link->PressA;
    else if(input == 1)return Link->PressB;
    else if(input == 2)return Link->PressL;
    else if(input == 3)return Link->PressR;
}

Edited by Gégé, 11 May 2018 - 09:54 AM.


#5 klop422

klop422

    Guess I'm full of monsters and treasure

  • Members
  • Real Name:Not George
  • Location:Planet Earth

Posted 11 May 2018 - 10:08 AM

This one appears to be playing the string when Link is touching the signpost FFC, then replaying as soon as it's done. The item doesn't seem to move/appear either...



#6 ywkls

ywkls

    Master

  • Members

Posted 11 May 2018 - 10:38 AM

This section is probably the problem.

for(int i = 0; i <= Screen->NumItems(); i++){
     item itm = Screen->LoadItem(i);
     if(itm->ID == id){
          itm->X = Link->X;
          itm->Y = Link->Y;
     }
}

What this does, is if the item is already onscreen; moves it to Link's position. If the item doesn't exist, it does nothing.

 

If I understand correctly, you want the sign to give Link an item once and only once?

Do you care whether or not Link holds the item in the air or if a message plays whenever he acquires it?

 

Edit:

 

 

Possible revised code

If that isn't what you're looking for or doesn't work, let me know.


Edited by ywkls, 11 May 2018 - 01:08 PM.


#7 klop422

klop422

    Guess I'm full of monsters and treasure

  • Members
  • Real Name:Not George
  • Location:Planet Earth

Posted 11 May 2018 - 11:43 AM

Ideally, Link should hold up the item and the item's pickup script should play.

One thing I'll say is that I am choosing not to copy the bool at the bottom because I already have the one from the signpost script in my buffer.

 

EDIT: It won't compile. The message is: "Syntax error, unexpected arrow, unexpected identifier, on token ->"

The relevant line, as far as I can tell, is:

item->Pickup|= IP_HOLDUP;


Edited by klop422, 11 May 2018 - 11:45 AM.


#8 ywkls

ywkls

    Master

  • Members

Posted 11 May 2018 - 01:10 PM

I edited the script. 

//item->Pickup|=IP_HOLDUP;
//Should be
itm->Pickup|=IP_HOLDUP;
 

So, did you want one message to play for the sign and another for the item?

Or have where examining the sign gives you the item and plays it's pickup message; then you can't examine the sign again?



#9 klop422

klop422

    Guess I'm full of monsters and treasure

  • Members
  • Real Name:Not George
  • Location:Planet Earth

Posted 11 May 2018 - 04:35 PM

Examining the sign should play a string (and the following stings as specified in the string editor), after which you'll pick up the item, and the item pickup string will play. I'm using the message script as a pickup script anyway, though.
The sign should be readable again (perhaps for a different string, but if not, I can work around it), but never give you the item again.

#10 ywkls

ywkls

    Master

  • Members

Posted 12 May 2018 - 01:15 AM

Examining the sign should play a string (and the following stings as specified in the string editor), after which you'll pick up the item, and the item pickup string will play. I'm using the message script as a pickup script anyway, though.
The sign should be readable again (perhaps for a different string, but if not, I can work around it), but never give you the item again.

That's eminently doable.

So, here's how it'd work.

 

String 1: Text played when you don't have the item. 

Use string control codes to check for the item and change the string after you've gotten it.

String 2: Item pickup message.

//d0 : item id
//d1 : sign message
//d2 : item message
//d3 : button
//d4 : item position (instantly) 0 = Link; 1 = FFC 
//d5 : Screen->D variable

ffc script MessageItem{
    void run(int id, int string1, int string2, int press, int type, int screend){
        //If we do this, the message will only play once.
        //if(Screen->D[screend] > 0)Quit();
        int loc = ComboAt(this->X, this->Y);
        bool Input = false;
        while(true){
            if(Link->Z == 0 
               && (Link->Dir == DIR_UP 
               && Link->Y <= ComboY(loc)+8 
               && Abs(Link->X-ComboX(loc)) <=8)){ //if collision
                if(SelectPressInput(press))Input = true; //input ok
                if(Input){ //if input
					//The message plays every time you read the sign.
                    Screen->Message(string1);
					//A failsafe to make sure things don't happen the wrong way.
					Waitframes(5);
                    //Only give the item once.
					if(Screen->D[screend]==0){
						//Item spawns on Link and he holds it up.
						if(type <= 0){
							item itm = Screen->CreateItem(i);
							itm->X = Link->X;
							itm->Y = Link->Y;
							itm->Pickup|= IP_HOLDUP;
							Screen->Message(string2);
						}
						else if(type == 1){
							item itm = Screen->CreateItem(i);
							itm->X = this->X;
							itm->Y = this->Y;
							itm->Pickup|= IP_HOLDUP;
						}
						Screen->D[screend] = 1;
					}
                }
            }
            Waitframe();
		}
	}
}
      

I'm not entirely sure what you want to about the input check.

The limits of Screen->D mean that this could only be used 8 times on any given screen.



#11 klop422

klop422

    Guess I'm full of monsters and treasure

  • Members
  • Real Name:Not George
  • Location:Planet Earth

Posted 12 May 2018 - 03:09 AM

Thanks. Works almost perfectly, except when you've read the signpost once, it goes back to playing the string whenever you're in contact with the ffc.

Also, it didn't compile, because "variable i was undeclared", but I changed that variable to id.


  • ywkls likes this

#12 ywkls

ywkls

    Master

  • Members

Posted 12 May 2018 - 10:56 AM

To fix the bug where the sign is read just by touching the ffc, change this line like so.

Screen->Message(string1);//Add next line.
Input = false;

This tells the ffc that you've read the string and need to press the button again before the sign should work.



#13 klop422

klop422

    Guess I'm full of monsters and treasure

  • Members
  • Real Name:Not George
  • Location:Planet Earth

Posted 13 May 2018 - 04:22 PM

One very minor issue is that Link still uses his item when he reads the signpost, something he doesn't do with the signpost script. Other than that, works wonders. Thanks!


  • ywkls likes this

#14 ywkls

ywkls

    Master

  • Members

Posted 14 May 2018 - 12:43 AM

One very minor issue is that Link still uses his item when he reads the signpost, something he doesn't do with the signpost script. Other than that, works wonders. Thanks!

The only way to prevent item use is to add the following lines to the script.

if(Input){//Place immediately after this.
     //Set A and B button use to false to keep items from being used.
     Link->InputA= false;
     Link->PressA= false;
     Link->InputB= false;
     Link->PressB= false;

Glad that you found it useful!




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users