Monday, 25 January 2016

TUTORIAL: Singles NPC dancers for the Paramour Clubmaster 2.0 danceball

One of the new features of the Paramour Clubmaster v2.0 Danceball is the ability for NPCs to use its new group dance capability. This tutorial covers the basics for doing this.

The most likely use would be to make the danceball work as a group choreography controller for a troup of NPC dancers but there are tons of  other possible applications.

To do this, you need one or more external (separate) NPC handler scripts that are responsible for rezzing the NPC(s) and having them touch the ball. When an NPC touches it, it will immediately begin to play the current group dance. Having the NPC touch it again will stop the NPC from dancing and return it to its default SL standing animation.

If you're rezzing multiple NPCs and having them touch the ball, it will be close to impossible to arrange for them all to touch the ball simultaneously so as each one joins the group dance they'll be out of synch until the group's dance animation advances to the next one (by default it changes every 120 seconds) at which point they'll all be in synch.

The approach for a basic external script is:
  • have a separate prim for the NPC with a touch activation
  • either supply that prim with the UUID of the danceball as a constant, or use a sensor event or other method to "look around" for the dancemaster ball and store its UUID. This is needed for the function that instructs the NPC to touch the ball
  • on touch, rez the NPC either by cloning the toucher or using a notecard from its inventory
  • have it touch the danceball
  • on subsequent touch of the NPC's prim, have the NPC touch the danceball again, then kill the NPC (or have it do something else if you want)
At its most basic, here is a script you can put in a prim as a sample

key npc=NULL_KEY;
key target="98c4f104-5ddb-4090-a6d9-8f1d4418656b";  // replace this with the key of your danceball
key user=NULL_KEY;
string emptyText="NPC singles dancer test\nTouch to rez a NPC clone\nof yourself to join the group dance\nTouch again to kill it";
default
{
    state_entry()
    {
        llSetText(emptyText,<0,1,0>,1);
    }
    touch_start(integer num)
    {
        if (npc==NULL_KEY) // no NPC currently rezzed
        {
            // rez new NPC by cloning toucher
            user=llDetectedKey(0);
            npc=osNpcCreate("NPC","Dancer",llGetPos(),user,8);  // 8 = NPC Group owned
            // give it a moment to come into existence and start its basic stand animation
            llSleep(0.5);
            // have it touch the dance ball
            osNpcTouch(npc,target,LINK_ROOT);
            llSetText("Currently in use by: "+llKey2Name(user),<0,1,0>,1);
        }
        else if ((llDetectedKey(0)==user)||(llDetectedKey(0)==llGetOwner()))// kill the current NPC
        {
            // have it touch the danceball first so the ball knows it wants to stop dancing (the ball will detect this within a couple minutes if you forget to do this)
            osNpcTouch(npc,target,LINK_ROOT);
            // then kill NPC and zero the key again, ready for re-use
            osNpcRemove(npc);
            npc=NULL_KEY;
            llSetText(emptyText,<0,1,0>,1);
        }
    }
}