One way to do it...
There's many ways to go about this... I just whomped up a quick one as an illustrative example (a 3-prim plywood umbrella - I'll drop a fullperms one on you after I finish this note). If anyone else has a better/cleaner/more-correct way to do this, feel free to hop in

.
So... a three-prim umbrella, consisting of 3 parts: a 'handle' (is always shown), a 'closed' prim (shows the canopy of the umbrella in its closed position) and an 'open' prim (shows the canopy of the umbrella in its open position). As placeholders, I've also taken an animation (just a freebie I pulled at random out of my inventory), made 3 copies and renamed each to associate with each of three commands: flourish, open, and close.
The 'main' script lives in the handle - and has a listen on channel 7. The three commands are 'o' (for open), 'c' (for close) and 'f' (for flourish). So typing /7o in your chat window would cause the umbrella to open, /7c to close, etc. The main control script catches the commands on channel 7 and then passes link messages to the other prim(s) (this to avoid having an active listen in each child prim, which would contribute to lag).
Here's the contents of the 'main' script in the handle:
// Umbrella (main) control script v0.0
// Author: Tengu Yamabushi
// License: Free for any and all use. Don't get wet!
integer theChannel = 7; // change the listen channel here, if desired
// these animations should be placed in the same prim as the script
string FlourishAnimation = "umbrella_flourish";
string OpenAnimation = "umbrella_open";
string CloseAnimation = "umbrella_close";
// Command definitions
integer COMMAND_FLOURISH = 0;
integer COMMAND_OPEN = 1;
integer COMMAND_CLOSE = 2;
ShowUsage()
{
string msg = "Tengu's Umbrella Control Script 0.0\n";
msg += "Commands:\n";
msg += "/" + (string)theChannel + " f - Flourish\n";
msg += "/" + (string)theChannel + " o - Open\n";
msg += "/" + (string)theChannel + " c - Close\n";
llOwnerSay(msg);
}
default
{
state_entry()
{
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
llListen(theChannel, "", llGetOwner(), "");
}
on_rez(integer param)
{
llResetScript();
}
attach(key attached)
{
if (attached != NULL_KEY) // the umbrella has been attached
{
ShowUsage();
llResetScript(); // ensure proper ownership
}
}
listen(integer channel, string name, key id, string message)
{
integer command = -1;
string cmpMessage = llToLower(message);
string animation = "";
if (cmpMessage == "f")
{
command = COMMAND_FLOURISH;
animation = FlourishAnimation;
}
else
{
if (cmpMessage == "o")
{
command = COMMAND_OPEN;
animation = OpenAnimation;
}
else
{
if (cmpMessage == "c")
{
command = COMMAND_CLOSE;
animation = CloseAnimation;
}
}
}
if ((command == COMMAND_FLOURISH) ||
(command == COMMAND_OPEN) ||
(command == COMMAND_CLOSE))
{
integer permissions = llGetPermissions();
llMessageLinked(LINK_ALL_OTHERS, command, "", NULL_KEY);
if (permissions & PERMISSION_TRIGGER_ANIMATION)
{
// only start the animation if we have privs to do so, avoids spam of
// 'permission denied' type messages...
llStartAnimation(animation);
}
}
}
}
Here's the contents of the 'closed' script (it lives in the 'closed' umbrella subprim):
// Umbrella (closed) control script v0.0
// Author: Tengu Yamabushi
// License: Free for any and all use.
// Command definitions
integer COMMAND_FLOURISH = 0;
integer COMMAND_OPEN = 1;
integer COMMAND_CLOSE = 2;
init()
{
llSetAlpha(1.0, ALL_SIDES); // the umbrella rezzes 'closed'
}
default
{
state_entry()
{
init();
}
on_rez(integer param)
{
init();
}
// Waits for parent control script to send a control message
link_message(integer sender_num, integer num, string str, key id)
{
if (num == COMMAND_FLOURISH)
{
// put some relevant operation here... I can't think of one right now, so leaving it a no-op.
}
else
{
if (num == COMMAND_OPEN)
{
// the umbrella is opening, so we must hide the 'closed' prim
llSetAlpha(0.0, ALL_SIDES);
}
else
{
if (num == COMMAND_CLOSE)
{
// the umbrella is closing, so we must show the 'closed' prim
llSetAlpha(1.0, ALL_SIDES);
}
}
}
}
}
And finally the contents of the 'opened' script (it lives in the 'open' umbrella subprim):
// Umbrella (open) control script v0.0
// Author: Tengu Yamabushi
// License: Free for any and all use.
// Command definitions
integer COMMAND_FLOURISH = 0;
integer COMMAND_OPEN = 1;
integer COMMAND_CLOSE = 2;
init()
{
llSetAlpha(0.0, ALL_SIDES); // the umbrella rezzes 'closed'
}
default
{
state_entry()
{
init();
}
on_rez(integer param)
{
init();
}
// Waits for parent control script to send a control message
link_message(integer sender_num, integer num, string str, key id)
{
if (num == COMMAND_FLOURISH)
{
// put some relevant operation here... I can't think of one right now, so leaving it a no-op.
}
else
{
if (num == COMMAND_OPEN)
{
// the umbrella is opening, so we must show the 'open' prim
llSetAlpha(1.0, ALL_SIDES);
}
else
{
if (num == COMMAND_CLOSE)
{
// the umbrella is closing, so we must hide the 'open' prim
llSetAlpha(0.0, ALL_SIDES);
}
}
}
}
}
Hope this helps. Happy scripting!