Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
NPC NPC General Utility Rez and Pose Dancer  

NPC General Utility Rez and Pose Dancer

Holds data for NPC - auto generated notecard

Category: NPC
By : Aine Caoimhe (aka Mata Hari)
Created: 2014-02-20 Edited: 2015-01-22
Worlds: OpenSim

the Zip file

Download all files for NPC General Utility Rez and Pose Dancer
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Script V1.lsl
Get file # 2. Script V2.lsl
Get file # 3. Script V3.lsl
1 notecard

NPC General Utility Rez and Pose Dancer

This was written as a "dancer" script for a club.

Category: NPC
By : Aine Caoimhe (aka Mata Hari)
Created: 2014-02-20 Edited: 2015-01-22
Worlds: OpenSim

1 // :SOURCE: http://forums.osgrid.org/viewtopic.php?f=5&t=4989
2
3 // Place this in a prim along with at least 1 animation.
4 // When you first touch it you will be cloned to notecard, then an NPC will rez, jump on the poseball and
5 // begin to play the animation(s) in its inventory. Subsequent touched of the prim will rez/unrez the dancer.
6 // On region restart, the dancer will auto-rez by default. You can add more animations or delete them during use
7 // (but it will reset the NPC's dance queue). Deleting the appearance notecard will disable the ball until you touch it again.
8 // Note that this script uses a very handy "orphan checker" that helps to prevent the accidentaly orphaning of a dancer.
9 // If an unexpected NPC is detected as already being on the poseball the ball will "take control" of that NPC instead of rezzing a new one.
10
11 // REVISIONS:
12 // V2 09-25-2014 - Ferd Frederix - added debug info
13 // save NPC key in description so pose ball can be removed and replaced
14 // Added Sensor to make NPCs go away when no one is around
15
16 // V3 01-22-2015 - Ferd Frederix - Fixed the timer so it plays more than ane animation-
17 //
18
19 // NPC General Utility Rez & Pose Dancer
20 // Written by Aine Caoimhe (aka Mata Hari) 2012/2013
21 //
22 // OVERVIEW
23 //
24 // This basic script is designed to be placed in any object (usually a poseball) along with at least one animation.
25 // When the owner touches the poseball for the first time their appearance will be cloned and stored to use for
26 // an NPC who will then rez, sit on the poseball, and begin to play the animation. Subsequent touches of the poseball
27 // will remove or restore the NPC. The script doesn't provide any "advanced" features such as variable timers, variable NPCs,
28 // dance selection/controls, etc.
29 //
30 // Because this was written by special request, several default behaviours are part of the script but can be altered
31 // easily either by changing the settings in the USE VARIABLES section below (even a novice can do this!) or more
32 // drastic changes can be made by altering the main body of the script.
33 //
34 // This script requires a region that is configured to allow the OSSL functions necessary to create and animate NPC
35 // (uses osAvatarPlayAnimation() and osAvatarStopAnimation() rather than the NPC versions of those functions because
36 // at the time I wrote most of it the NPC versions didn't work correctly).
37 //
38 // TERMS OF USE
39 //
40 // This script is provided as a courtesy to other users of OpenSim on an as-is basis. I'll try to help you if you ask nicely
41 // but I won't promise to fix or resolve any issues you might encounter or further customize it for your uses.
42 // You are free to use and modify it as desired, provided you:
43 // - also provide it free of charge with full perms as per GPU General Public Licence 3.0
44 // - never alter the script to allow it to clone another avatar appearance without that owner's explicit and informed consent (avi theft)
45 //
46
47
48 // -----------------------------------------------------------------------
49 // USER VARIABLES
50 // you can change these default values to suit your preferences
51 // -----------------------------------------------------------------------
52 integer debug = FALSE; // set to TRUE or FALSE for debug chat on various actions
53 integer iTitleText = FALSE; // set to TRUE or FALSE for hovertext various actions
54
55 // If Set to a non-zero number the NPC will appear only when someone is withing this RADIUS.
56 float RADIUS = 30; // in meters
57 float RATE = 5.0; // the smaller this is, the quicker the NPC will appear and the laggier it will be. Keep this as large as usefully possible for a given RADIUS.
58
59 // The name of your dancer...this is the name she will show in world
60 string dancerFirstName="Club";
61 string dancerLastName="Dancer";
62
63 // How she changes dances...one of the two following lines must be commented (disabled using // at the start of the line) and the
64 // other line must be active (no // at the start)
65
66 //string danceSeq="random"; // dancer will pick the next animation randomly
67 string danceSeq="seq"; // dancer will pick the next animation in the poseball
68
69 // How often she changes dances -- set a value here in seconds that you want her to play each dance before advancing to the next
70 float danceTimer=15.0;
71
72 // Is the poseball active? Set this to TRUE to have her automatically rezzed whenever the region is restarted. Otherwise set to FALSE.
73 integer active=TRUE;
74
75 // Positioning...how far from the ball to place the dancer (essentially this is her sit target) as a (x,y,z) vector
76 vector offSet=<0.0, 0.0, 1.0>;
77 vector rot = <0,0,0>; // In case it is not a pose ball, and easily rotated, you can adjust the axis here.
78
79 vector RezPos = <0,0,1.0>; // set this Z to a large number, and they fall out of the sky.
80
81 // OS_NPC_CREATOR_OWNED will create an 'owned' NPC that will only respond to osNpc* commands issued from scripts that have the same owner as the one that created the NPC.
82 // OS_NPC_NOT_OWNED will create an 'unowned' NPC that will respond to any script that has OSSL permissions to call osNpc* commands.
83 integer NPCOptions = OS_NPC_CREATOR_OWNED; // anyone, not just the owner of this box can control this NPC.
84
85 // Control
86 integer PRIVATE = TRUE; // set to FALSE to a allow anyone to touch and control the NPC;
87
88 // -----------------------------------------------------------------------
89 // DON'T CHANGE ANYTHING BELOW HERE UNLESS YOU KNOW WHAT YOU ARE DOING :)
90 // -----------------------------------------------------------------------
91
92 string npcCard="My Dancer";
93 key dancerID;
94 integer danceIndex;
95 list danceList;
96
97 // V2
98 // DEBUG(string) will chat a string or display it as hovertext if debug == TRUE
99 DEBUG(string str)
100 {
101 if(debug)
102 llSay(0, str); // Send the owner debug info so you can chase NPCS
103
104 if(iTitleText)
105 {
106 llSleep(0.1);
107 llSetText(str,<1.0,1.0,1.0>,1.0); // show hovertext
108 }
109 }
110
111
112 // V2
113 BootDancer()
114 {
115 //DEBUG("BootDancer()");
116
117 if(dancerID==NULL_KEY || ! NpcIsSeated() ){
118 DEBUG("No NPC key in RAM");
119 rezDancer();
120 danceIndex=0; // start with the first dance
121 }
122
123 // other wise, boot will do nothing as there is already a NPC
124 }
125
126 updateDanceList()
127 {
128 DEBUG("updateDanceList()");
129 // build list of animations in inventory
131 while(--anims > -1)
132 {
134 }
135 if(danceSeq=="seq")
136 danceList=llListSort(danceList,1,TRUE);
137 else
138 danceList=llListRandomize(danceList,1);
139
140 danceIndex=0;
141
142 DEBUG("We have " + (string) llGetListLength(danceList) + " animations");
143
144 }
145 rezDancer()
146 {
147 DEBUG("rezDancer()");
148 // make sure there are animations
149 if(!llGetListLength(danceList))
150 {
151 llOwnerSay("Cannot create the dancer because there are no animations in the poseball inventory to play");
152 return;
153 }
154 // make sure there is a dancer to rez (shouldn't be possible to get this result but included just in case
156 {
157 llOwnerSay("Cannot create the dancer because there is no stored appearance in inventory");
158 return;
159 }
160 // see if an npc is already sitting...helps to recover from accidental script reset with active NPC
161 if(NpcIsSeated()) {
162 DEBUG(" NPC already in world - starting animation");
163
164 } else {
165 DEBUG("NPC rezzing");
166 dancerID = osNpcCreate(dancerFirstName,dancerLastName,llGetPos()+ RezPos ,npcCard, NPCOptions);
167 llSetObjectDesc(dancerID); // V2
168 llSleep(0.5);
169 osNpcSit(dancerID,llGetKey(),OS_NPC_SIT_NOW);
170 }
171
172 }
173 removeDancer()
174 {
175 //DEBUG("removeDancer()");
176 // kill active npc
177
178 // V2 if we rtest or there is a sitter
179 if(dancerID == NULL_KEY || ! NpcIsSeated() ) {
180 //DEBUG("Dancer is unknown and not sittting, using the Description");
181 dancerID = llGetObjectDesc();
182 }
183
184 if(llStringLength(dancerID)) {
185 //DEBUG("Removing Dancer NPC UUID " + (string) dancerID);
186 osNpcRemove(dancerID);
187 }
188 dancerID=NULL_KEY;
190 }
191 integer NpcIsSeated()
192 {
193 // a safety net to try to catch stray NPCs cause by script edit/reset while an NPC is active
194 // if an NPC is detected already on the ball but no dancerID is set...this is only called at
195 // a time when a new NPC would otherwise be created
196
197 key sitterID=llAvatarOnSitTarget();
198
199 if(sitterID != NULL_KEY)
200 {
201 if(osIsNpc(sitterID))
202 {
203 dancerID=sitterID;
204 return TRUE;
205 }
206 else
207 {
208 return FALSE;
209 }
210 }
211
212 return FALSE;
213 }
214 startDancing()
215 {
216 DEBUG("StartDancing()");
217
218
219 // called when an NPC first sits
220 string dance=llList2String(danceList,danceIndex);
221 // start currently indexed dance
222 osAvatarPlayAnimation(dancerID,dance);
223 DEBUG("playing animation " + dance);
224
225 llSleep(0.25);
226 // now stop any other animations the NPC is playing (sit, etc)
227 list animToStop=llGetAnimationList(dancerID);
228
229 DEBUG(llDumpList2String(animToStop,"-"));
230
231 integer stop=llGetListLength(animToStop);
232
233 DEBUG("List L = " + (string) stop);
234
235 key dontStop=llGetInventoryKey(dance);
236 DEBUG("key dont stop = " + (string) dontStop);
237
238 while(stop-- > 0)
239 {
240 if(llList2Key(animToStop,stop)!= dontStop) {
241 string tostop = llList2Key(animToStop,stop);
242 osAvatarStopAnimation(dancerID,tostop);
243 DEBUG("Stopping animation:" + tostop);
244 }
245 }
246
247 if(RADIUS > 0.0)
248 llSensorRepeat("","",AGENT,RADIUS,PI,RATE);
249
250 llSetTimerEvent(danceTimer); // set the timer for advancing to next dance
251 }
252 playNextDance()
253 {
254 DEBUG("playNextDance()");
255
256 // play the next dance
257 osAvatarStopAnimation(dancerID,llList2String(danceList,danceIndex));
258 DEBUG("Stopping animation " + llList2String(danceList,danceIndex));
259
260 danceIndex++;
261 if(danceIndex==llGetListLength(danceList))
262 danceIndex=0; // cycle back to beginning when reaching the end
263
264 DEBUG("Starting animation " + llList2String(danceList,danceIndex));
265 osAvatarPlayAnimation(dancerID,llList2String(danceList,danceIndex));
266
267 llSetTimerEvent(danceTimer); // set the timer for advancing to next dance
268
269 }
270 default
271 {
273 {
274 DEBUG("Reboot");
275 removeDancer(); // V2 kill any old dancers
276
277 // ensure sit target set
278 if(offSet==ZERO_VECTOR)
279 offSet.z+=0.0001;
280
281 // V2, allow defined rotations
282 llSitTarget(offSet,llEuler2Rot(rot * DEG_TO_RAD)) ;
283
284 // update the animations list
285 updateDanceList();
286
288
289 // rez dancer automatically if set to do so
290 if(active ) {
291 rezDancer();
292 }
293 }
294 }
295 timer()
296 {
297 DEBUG("Tick");
298 // time to advance to next dance...make sure there is a dancer first
299 if((dancerID==NULL_KEY) || (llAvatarOnSitTarget()!=dancerID)) {
300 DEBUG("No Dancer!");
301 llSetTimerEvent(0.0); // kill timer if NPC unrezzed
302 } else {
303 playNextDance();
304 }
305 }
306 on_rez(integer start)
307 {
308 // always reset on rez
310 }
311 changed(integer change)
312 {
313 // reset script if owner changes or region restarts
314 if(change & CHANGED_OWNER)
316 else if(change & CHANGED_REGION_START) // Opensim changed the variable to RE start
318 // handle changes in inventory that might affect operation
319 else if(change & CHANGED_INVENTORY)
320 {
321 DEBUG("Inventory Changed");
322 // safety check on deleting notecard during use
323 if((llGetInventoryType(npcCard)!=INVENTORY_NOTECARD) && (dancerID==NULL_KEY))
324 {
325 llOwnerSay("You have deleted the dancer notecard. Removing the dancer");
326 removeDancer();
327 return;
328 }
329 // else see if it's a change in animations
331 if(!anims && (dancerID!=NULL_KEY))
332 {
333 // user deleted the last animation...kill active dancer
334 llOwnerSay("There are no animations in the poseball...removing your dancer");
335 removeDancer();
336 }
337 else if(anims!=llGetListLength(danceList))
338 {
339 DEBUG("Update Dance List");
340 updateDanceList();
341 if(dancerID!=NULL_KEY) {
342 startDancing();
343 }
344 }
345 }
346 // handle changes in link...will usually be triggered by the NPC sitting or being removed
347 else if(change & CHANGED_LINK)
348 {
349 DEBUG("Inventory Changed Link");
350
351 osAvatarStopAnimation(dancerID,"sit");
352
353 // start dancing when an npc sits
354 if(dancerID!=NULL_KEY && llAvatarOnSitTarget()==dancerID)
355 startDancing();
356 // can ignore npc standing (derez) because key reset is handled by the remove routine
357 // also ignoring any non-npc who sits here
358 }
359 }
361 {
362 // only owner can play with this
363 if(PRIVATE) {
365 return;
366 }
367 // first, clone owner if no appearance card has been stored
369 {
370 llOwnerSay("One moment while your appearance is saved for the npc to use");
371 osOwnerSaveAppearance(npcCard);
372 llSleep(2.0);
373 }
374 // if no dancer, rez one
375 if(dancerID==NULL_KEY)
376 {
377 BootDancer();
378 }
379 // else there's a dancer so this touch means we want to remove it
380 else {
381 removeDancer();
384 }
385 }
386
388 {
389 BootDancer();
390 }
391
392 no_sensor()
393 {
394 DEBUG("No Sensor");
395 if(dancerID) {
396 removeDancer();
397 }
398 }
399 }

Back to the Best Free Tools in Second Life and OpenSim.