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.