Jump to content

Touched prim in a range says specific phrase


polygraph
 Share

You are about to reply to a thread that has been inactive for 1303 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I'm trying to set up a game to practice my scripting, where I have a grid of prims and one gives a prize on touch. I want to make each non-winning prim have a phrase that it says to tell how close you are to the prize, but I don't want to have to put a script in every single one of the prims, so I'm going to make one script and place it in a root prim. I also want to limit how many lines of code the script has to run, so I want to have set phrases that get called if the detected link number is in a defined range of numbers.

This is about where I get hung up. I think I can define a range of numbers in a list, and I know how to compare the detected link to an integer, but I don't know how to combine the two.

integer winner = 7;
//list touchedLink = [];

default
{
    touch_start(integer num)
    {
        if(llDetectedLinkNumber(0) == winner)
        {
            llSay(0, "You found me! Here's your prize.");
            llGiveInventory(llDetectedKey(0), "PRIZE ITEM");
        }
        
        //else if(llDetectedLinkNumber(0) == )
        //{
        //llSay(0, "You're ice cold!");   
        //}
        
        //else if(llDetectedLinkNumber(0) == )
        //{
        //llSay(0, "You're getting warmer.");   
        //}
        
        //else if(llDetectedLinkNumber(0) == )
        //{
        //llSay(0, "You're getting hot!");   
        //}
    }
}

 

Link to comment
Share on other sites

There are several ways to approach the idea.  Maybe the easiest is to use four if statements...

// Assuming, that you have, say, nine links (remember that links in a linkset are numbered starting from link #1)
integer iLink = llDetectedLinkNumber(0);
if (iLink  <= 3 )
{
    llSay(0, "You're ice cold.");
}
else if (iLink  > 7)
{
    llSay(0,"You're getting hot!");
}
else if (iLink == 7 )
{
    llSay(0,"Wowza!);
    llGiveInventory(llDetectedKey(0),"Prize");
}
else
{
    llSay(0, "You're getting warmer!");
}

 

Edited by Rolig Loon
Oops, I forgot the prize
Link to comment
Share on other sites

NyfCSKE.png

I have a grid of 25, I changed the colors to make it easier to visualize for this post. The white underneath is the root prim, and I don't want it to speak when clicked. Green is the prize giver, link 7. Orange is the hot range, link numbers 2, 4, 5, 6, 8. Cyan is the warm range, link numbers 3, 9, 17, 19, 22, 24. Blue is the cold range, link numbers 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 23, 25, 26. The ordering of the links in comparison to the grid is a bit random because that's just how I selected things while I was building it.

You don't have to use these numbers or anything, they're more outlining what I'm working with. I'd be happy enough with just being pointed in the right direction for using a list to compare against. I wanted to use a list of the ranges because I think it'd be useful to know for future projects, plus I didn't want to redo my entire linkset haha.

Link to comment
Share on other sites

OK, try this ....

Name each of your links.  "PRIZE" is the prize link,  "HOT" is the orange ones, "WARM" is the cyan ones, and "COLD" is the blue ones.   Then create a global integer variable iPrize and three global lists, lHot, lWarm, and lCold.

state_entry()
{     // Now load the variables ...
     integer i = 1;
     while ( i < llGetNumberOfPrims() )
     {
          ++i;   // So counting starts with the first child prim
          string name = llGetLinkName(i);
          if (name == "PRIZE") 
          {
               iPrize = i;
          }
          else if (name == "HOT")
          {
               lHot += [ i ];
          }
          else if ( name == "WARM")
          {
               lWarm += [i ];
          }
          else
          {
               lCold += [ i ];
          }
     }
}

Now you're all set.  Whenever anyone clicks on a link, you can ask

integer iLink = llDetectedLinkNumber(0);
if (iLink == iPrize) { // give the prize}
else if ( ~llListFindList( lHot, [ iLink ]) )  { // Say hot stuff }
else if ( ~llListFindList( lWarm, [ iLink ] ) ) { // Say warm things }
else if ( ~llListFindList( lCold, [ iLink ] ) ) { // Say cold words }

 

Edited by Rolig Loon
Ooops
Link to comment
Share on other sites

Renaming the links would definitely allow easy cheating, and you'd have to rename all of the links by hand or figure out a way to rename the links in the correct order by script, which is the same problem as the original.

If you want the prize prim to change at the start of each game, what I might suggest is a quite literal solution to the problem:

You want to know how close you were to the prize, whenever you touch the wrong prim. You know the prize prim, and you know the prim that was touched.

So... If the prize prim wasn't touched, use llGetLinkPrimitiveParams to get the position of the prize prim and the one that was touched. Then just use llVecDist to get the distance between them. This way, your code doesn't have to change no matter how many squares you add/remove, or what order you've linked them in.

Edited by Wulfie Reanimator
  • Like 2
Link to comment
Share on other sites

This is a grid-offset game, so math can help.  First, re-link them all properly so that the bottom left is link 2, then to the right is link 3, 4, 5, 6, and the next row up starts at 7 and so on.  Now you can calculate the grid position of the touched prim.  Set X and Y variables (or a vector) to store coords of the touched prim.

vector.x = (linknum - 2)%5+1.  The minus two compensates for the root prim and the plus one makes the grid start at 1,1.  That gives X a value 1-5 per five columns.

vector.y = llFloor((linknum-2)/5)+1.  This gives Y value 1-5 with the bottom row at 1 and the top row at 5 (llFloor() rounds down).

So now, every prim has unique coordinates.  Assign coordinates to your "winning" prim too, then, as Wulfie suggests, use llVectDist() to calculate the distance between then touched prim coords and the winning coords.  if that equals 0, then you have a winner, else colder the greater the distance.

Edited by DoteDote Edison
  • Like 1
Link to comment
Share on other sites

Other than to accept touch to invoke a response from the root prim, what do your child prims do? If nothing, you could reduce the complexity of the game considerably by texturing the game surface of a single prim with an image of your grid, then use:

http://wiki.secondlife.com/wiki/LlDetectedTouchST

You'll want to scale and quantize the measured distance from the touch point to your target, so you can select messages, perhaps as DoteDote suggests. You could also keep track of the previous guess, and intermix comparative adjectives like "colder" or "warmer" if they're moving away/towards the target, with straight adjectives like "hot" and "freezing", which require no knowledge of the previous guess.

  • Like 2
Link to comment
Share on other sites

Or, forget all of those child prims completely.  Replace them with a single prim that covers the entire area and has a grid texture on its visible surface.  Then write your script to use llDetectedTouchUV or llDetectedTouchST to recognize the exact coordinates of the spot that someone clicked.  (Those functions report a vector that contains the X and Y coordinates of the touched spot.)  Then all you have to do is determine which grid area the touch spot lies in and decide where that grid area lies on your Hot <-->  Cold spectrum.

So many ways to approach the task.....  ;)  [ Edit: /me waves to Maddy, who is a faster typist than I am ]

 

 

Edited by Rolig Loon
  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1303 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...