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
Teleport PortRingCreator_version_13  

PortRingCreator_version_13

PortRingCreator version 1.3.lsl

Category: Teleport
By : neo Rebus
Created: 2010-01-10 Edited: 2010-01-10
Worlds: Second Life

the Zip file

Download all files for PortRingCreator_version_13
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. PortRingCreator_version_13_1.lsl
1
2 // PortRingCreator - Create a PortRing from a set of Porter objects and
3 // a dropped-in notecard.
4 // version 1.3.0, 1 August 2004, by Neo Rebus
5 //
6 // COPYRIGHT 2004 BY NEO REBUS - SEE LICENSE AT END
7 //
8 // This script will create a PortRing structure. Currently, it must
9 // all be within the same sim!
10 //
11 // The object containing this script must also contain the three Porter
12 // objects - one for Back, one for Next, and one for Base (obviously,
13 // each must have a different name).
14 //
15 // The owner can drop a notecard onto the object. This script will
16 // detect that, read the notecard, process it, delete it, then create
17 // the porters.
18 //
19 // General algorithm:
20 //
21 // When a notecard is dropped in, parse the notecard into the
22 // gxPortRingInfo and gxPortRingStations global lists. When
23 // finished, the first three entries should be strings containing
24 // the names of the three Porter objects - back, forward, base,
25 // respectively, followed by the spacing between 'porters in a
26 // set, and then by vector, rotation pairs, the first for the base
27 // location, the rest
28 // for each station.
29 //
30 // Delete the notecard.
31 //
32 // Using the "CreatePorterSet" function, create the base 'porter
33 // and the 'porters for each station.
34 //
35 // The CreatePorterSet(list axPorters) algorithm:
36 // axPorters is a strided list consisting of sets of:
37 // [ "porterName", <destVector>, <destRotation>, "descriptiveName" ]
38 //
39 // Teleport to the 'porter location plus 2m in Z direction, and
40 // orient to the correct rotation.
41 //
42 // Calculate the relative offset of the first 'porter: <spacing>
43 // meters in the positive Y direction.
44 //
45 // Loop through axPorters:
46 // Rez the requested 'porter in its location and correct
47 // orientation. Send a message with the destVector and
48 // destRotation in a CSV to the private channel given in
49 // the start code.
50 //
51 ////////////////////////////////////////////////////////////////////////
52 //
53 // REVISION HISTORY
54 //
55 // version 1.3.0, 1 August 2004, by Neo Rebus
56 // Added in RINGSTYLE option, equal to LINEAR or LOOP; this
57 // determines if the first and last stations should "wrap around"
58 // to each other.
59 // version 1.2.1, 1 August 2004, by Neo Rebus
60 // Added a check for a vector of <0,0,0> to make sure that invalid
61 // vectors don't pass the error checking.
62 // version 1.2.0, 25 July 2004, by Neo Rebus
63 // Added OPTIONS line to notecard format.
64 // Added BASEPORTERS option to control what base 'porters get
65 // created: FIRSTONLY, FIRSTANDLAST, or ALL
66 // version 1.1.0, 25 July 2004, by Neo Rebus
67 // Allow station/base names in the control card; pass those on to
68 // the PortRing Porter script to set the sit text.
69 // version 1.0.1, 25 July 2004, by Neo Rebus
70 // New version of f_TeleportTo, that only lifts up when necessary.
71 // version 1.0.0, 24 July 2004, by Neo Rebus
72 // First version. Limited to a single sim.
73 //
74 ////////////////////////////////////////////////////////////////////////
75 //
76 // A NOTE ABOUT VARIABLE NAMES
77 //
78 // I use a form of "polish notation", where variable names are prefixed
79 // by their scope and type. The first letter of a variable name is its
80 // scope:
81 //
82 // p - parameter (a global that is set by the program maintainer and
83 // referenced but not changed by the program itself)
84 // g - global
85 // f - function
86 // s - state (a global that is only used in a particular state)
87 // l - local
88 // a - argument (in the formal argument list for a function)
89 //
90 // The second letter is the variable's type:
91 //
92 // b - boolean (an integer that holds TRUE or FALSE)
93 // f - float
94 // i - integer
95 // r - rotation
96 // s - string
97 // v - vector
98 // x - list ('x' is used instead of 'l' to avoid llXYZ names)
99 // _ - void (only for functions)
100 //
101 // The rest of the name is in MultipleCaps notation.
102 //
103 ////////////////////////////////////////////////////////////////////////
104 //
105 // CONSTANTS
106 //
107 // cxHeadingToRotation
108 // A list used to translate a heading to a rotation
109
110 list cxHeadingToRotation = [
111 "E", <0.00000, 0.00000, 0.00000, 1.00000>,
112 "ENE", <0.00000, 0.00000, 0.19509, 0.98079>,
113 "NE", <0.00000, 0.00000, 0.38268, 0.92388>,
114 "NNE", <0.00000, 0.00000, 0.55557, 0.83147>,
115 "N", <0.00000, 0.00000, 0.70711, 0.70711>,
116 "NNW", <0.00000, 0.00000, 0.83147, 0.55557>,
117 "NW", <0.00000, 0.00000, 0.92388, 0.38268>,
118 "WNW", <0.00000, 0.00000, 0.98079, 0.19509>,
119 "W", <0.00000, 0.00000, 1.00000, -0.00000>,
120 "WSW", <0.00000, 0.00000, 0.98078, -0.19509>,
121 "SW", <0.00000, 0.00000, 0.92388, -0.38268>,
122 "SSW", <0.00000, 0.00000, 0.83147, -0.55557>,
123 "S", <0.00000, 0.00000, 0.70711, -0.70711>,
124 "SSE", <0.00000, 0.00000, 0.55557, -0.83147>,
125 "SE", <0.00000, 0.00000, 0.38268, -0.92388>,
126 "ESE", <0.00000, 0.00000, 0.19509, -0.98078>
127 ] ;
128
129 ////////////////////////////////////////////////////////////////////////
130 //
131 // PARAMETERS
132 //
133 // piPrivateChannel
134 // The first channel number to use for passing information to the
135 // 'porters.
136
137 integer piPrivateChannel = 1850896466 ;
138
139 ////////////////////////////////////////////////////////////////////////
140 //
141 // GLOBAL VARIABLES
142 //
143 // gsNotecardName
144 // The name of the notecard we're parsing.
145 //
146 // giNotecardLine
147 // The line number in the notecard we're parsing.
148 //
149 // gxPortRingInfo
150 // A list of:
151 // string porterBackName
152 // string porterForwardName
153 // string porterBaseName
154 // float porterSpacing
155 //
156 // gxPortRingStations
157 // A list of:
158 // vector baseLocation
159 // rotation baseRotation
160 // vector stationLocation
161 // rotation stationRotation
162 // ... add'l stations ...
163 //
164 // gxPortRingStationNames
165 // A list of:
166 // string stationName
167 // ... add'l stations ...
168 //
169 // gxOptions
170 // A list of:
171 // string optionName
172 // string optionValue
173 // string possibleValues
174 // Initialized to the option names and default option values.
175 // option names must be in all caps and start with a ",".
176 // possibleValues is a CSV of the possible values. If empty,
177 // any value is allowed.
178
179 string gsNotecardName ;
180
181 integer giNotecardLine ;
182
183 list gxPortRingInfo ;
184 list gxPortRingStations ;
185 list gxPortRingStationNames ;
186
187 list gxOptions = [
188 ",BASEPORTERS", "FIRSTONLY", "FIRSTONLY,FIRSTANDLAST,ALL" ,
189 ",RINGSTYLE", "LINEAR", "LINEAR,LOOP"
190 ] ;
191
192 ////////////////////////////////////////////////////////////////////////
193 //
194 // FUNCTIONS
195 //
196
197 ////////////////////////////////////////////////////////////////////////
198 //
199 // f_TeleportTo(vector avDestination)
200 // teleport to avDestination, in the same sim as the object.
201 //
202 // record PHANTOM status, and set PHANTOM to true.
203 // Move UP to 250m, move to avDestination (at 250m), then move down
204 // to a height above gronud equal to avDestination's Z value.
205
206 f_TeleportTo(vector avDestination)
207 {
208 integer liOldPhantom = llGetStatus(STATUS_PHANTOM);
209 llSetStatus(STATUS_PHANTOM, TRUE);
210
211 vector lvTemp;
212 vector lvDest;
213 float lfHeight;
214
215 lvDest = avDestination;
216 lvDest.z = 0;
217 lvTemp = llGetPos();
218 lfHeight = lvTemp.z;
219 lvTemp.z = 0;
220
221 while(llVecDist(lvTemp, lvDest) > 0.1)
222 {
223 vector lvDelta = lvDest - lvTemp;
224 if(llVecMag(lvDelta) > 8)
225 {
226 lvDelta = llVecNorm(lvDelta) * 8;
227 }
228 if(llGround(lvDelta) > (lfHeight - 1.0))
229 {
230 lfHeight = llGround(lvDelta) + 1.0;
231 } else {
232 lvTemp += lvDelta ;
233 }
234 llSetPos( <lvTemp.x, lvTemp.y, lfHeight> );
235 }
236
237 lvDest = avDestination;
238 lvDest.z += llGround(ZERO_VECTOR);
239
240 while(llVecDist(llGetPos(), lvDest) > 0.1)
241 {
242 llSetPos(lvDest);
243 }
244
245 llSetStatus(STATUS_PHANTOM, liOldPhantom);
246 }
247
248 ////////////////////////////////////////////////////////////////////////
249 //
250 // f_CreatePorterSet(vector avDest, rotation arRot, list axPorters)
251 // axPorters is a strided list consisting of sets of:
252 // [ "porterName", <destVector>, <destRotation>, "descriptiveName" ]
253 //
254 // Teleport to the 'porter location plus 2m in Z direction, and
255 // orient to the correct rotation.
256 //
257 // Calculate the relative offset of the first 'porter: <spacing>
258 // meters in the Y direction.
259 //
260 // Loop through axPorters:
261 // Rez the requested 'porter in its location.
262 // Send a message with the destVector and destRotation
263 // in a CSV to the private channel given in the start code.
264 //
265
266 f_CreatePorterSet(vector avDest, rotation arRot, list axPorters)
267 {
268 f_TeleportTo(avDest + <0,0,2>);
269 llSetRot(arRot);
270
271 integer liNumPorters = llGetListLength(axPorters) / 4;
272 float lfSpacing = llList2Float(gxPortRingInfo, 3);
273 float lfOffset = (lfSpacing * 0.5) * (float)(liNumPorters - 1);
274
275 integer i;
276 for (i = 0; i < liNumPorters; i++)
277 {
278 vector lvPorterLocation = llGetPos() + <0, lfOffset, -2> * llGetRot() ;
280 llList2String(axPorters, i*4), // the name of object to rez
281 lvPorterLocation, // the location at which to rez
282 ZERO_VECTOR, // the velocity
283 llGetRot(), // the rotation
284 piPrivateChannel + i // the start code
285 );
286 llSleep(1.0);
287 vector lvDest = llList2Vector(axPorters, i*4+1);
288 rotation lrRot = llList2Rot(axPorters, i*4+2);
289 string lsName = llList2String(axPorters, i*4+3);
290 lvDest += <-2,0,0> * lrRot;
291 llWhisper(piPrivateChannel + i, "Porter:Destination:" + llList2CSV( [ lvDest, lrRot, lsName ] ));
292 lfOffset -= lfSpacing;
293 }
294 }
295
296 ////////////////////////////////////////////////////////////////////////
297 //
298 // Default state:
299 //
300 // Immediately switch to state WaitingForNotecard.
301
302 default
303 {
304
305 on_rez(integer liStartCode)
306 {
308 }
309
311 {
312 state WaitingForNotecard ;
313 }
314
315 }
316
317 ////////////////////////////////////////////////////////////////////////
318 //
319 // WaitingForNotecard state:
320 //
321 // on changed(), if CHANGED_INVENTORY, check if we have a notecard.
322 // if so, get the notecard name and switch to ParsingNotecard state.
323
324 state WaitingForNotecard
325 {
326 on_rez(integer liStartCode)
327 {
329 }
330
331 changed(integer aiWhat)
332 {
333 if(aiWhat == CHANGED_INVENTORY)
334 {
336 if(liNotecardCount > 0)
337 {
338 gsNotecardName = llGetInventoryName(INVENTORY_NOTECARD, liNotecardCount - 1);
339 state ParsingNotecard ;
340 }
341 }
342 }
343 }
344
345 ////////////////////////////////////////////////////////////////////////
346 //
347 // ParsingNotecard state:
348 //
349 // On entry, read the next notecard line.
350 // On exit, delete the notecard.
351 //
352 // On dataserver, fetch the line. If EOF, switch to state
353 // CreatingPortRing. If not blank or comment, parse the information
354 // out and add it to the gxPortRingInfo list.
355
356 state ParsingNotecard
357 {
358 on_rez(integer liStartCode)
359 {
361 }
362
364 {
365 llWhisper(0, "Parsing notecard " + gsNotecardName);
366 gxPortRingInfo = [ ] ;
367 gxPortRingStations = [ ] ;
368 gxPortRingStationNames = [ ] ;
369 llGetNotecardLine(gsNotecardName, 0);
370 giNotecardLine = 1;
371 llSetTimerEvent(10.0);
372 }
373
375 {
376 llSetTimerEvent(0.0);
377 llRemoveInventory(gsNotecardName);
378 }
379
380 timer()
381 {
382 llWhisper(0, "Still parsing...");
383 }
384
385 dataserver(key akRequestID, string asLine)
386 {
387 string lsError = "";
388
389 if(asLine == EOF)
390 {
391 state CreatingPortRing;
392 }
393
394 if((asLine != "") && (llGetSubString(asLine, 0, 1) != "//"))
395 {
396 list lxLineInfo = llCSV2List(asLine);
397 string lsLineType = llList2String(lxLineInfo, 0);
398 if("PORTERS" == lsLineType)
399 {
400 if(llGetListLength(gxPortRingInfo) != 0)
401 {
402 lsError = "Invalid notecard format - only one PORTERS line allowed";
403 } else {
404 //llWhisper(0, "Parsed line " + (string)giNotecardLine + ": " + asLine);
405 gxPortRingInfo += llList2List(lxLineInfo, 1, 3);
406 gxPortRingInfo += [ (float)llList2String(lxLineInfo, 4) ];
407 }
408 } else if("OPTIONS" == lsLineType)
409 {
410 integer liNumOptions = llGetListLength(lxLineInfo) - 1;
411 integer i;
412 for (i = 1; i <= liNumOptions; i++)
413 {
414 string lsOptionName = llList2String(lxLineInfo, i);
415 string lsOptionValue;
416 integer liIndex = llSubStringIndex(lsOptionName, "=");
417 if(liIndex > -1)
418 {
419 lsOptionValue = llGetSubString(lsOptionName, liIndex + 1, -1);
420 lsOptionName = llGetSubString(lsOptionName, 0, liIndex - 1);
421 } else {
422 lsOptionValue = "";
423 }
424 lsOptionName = llToUpper(lsOptionName);
425 lsOptionValue = llToUpper(lsOptionValue);
426 liIndex = llListFindList( gxOptions, [ "," + lsOptionName ] );
427 if(liIndex >= 0)
428 {
429 list lxAllowedValues = llCSV2List( llList2String(gxOptions, liIndex + 2) );
430 if("" == lsOptionValue)
431 {
432 lsOptionValue = llList2String(lxAllowedValues, 0);
433 }
434 if((llGetListLength(lxAllowedValues) == 0) || (llListFindList(lxAllowedValues, [lsOptionValue]) > -1))
435 {
436 gxOptions = llListInsertList( llDeleteSubList(gxOptions, liIndex + 1, liIndex + 1), [ lsOptionValue ], liIndex + 1);
437 } else {
438 lsError = "Invalid notecard format - invalid value " + lsOptionValue + " for option " + lsOptionName;
439 }
440 } else {
441 lsError = "Invalid notecard format - unknown option " + lsOptionName;
442 }
443 }
444 } else if("BASE" == lsLineType)
445 {
446 if(llGetListLength(gxPortRingInfo) == 0)
447 {
448 lsError = "Invalid notecard format - first entry must be PORTERS";
449 } else if(llGetListLength(gxPortRingStations) != 0)
450 {
451 lsError = "Invalid notecard format - only one BASE line allowed";
452 } else {
453 vector lvPosition = (vector)(llList2String(lxLineInfo, 1));
454 string lsHeading = llList2String(lxLineInfo, 2);
455 string lsName = llList2String(lxLineInfo, 3);
456 integer liIdx = llListFindList(cxHeadingToRotation, [ lsHeading ]);
457 if(llVecMag(lvPosition) < 1.0)
458 {
459 lsError = "Invalid notecard format - illegal vector " + llList2String(lxLineInfo, 1);
460 } else if(liIdx < 0)
461 {
462 lsError = "Invalid notecard format - unknown heading " + lsHeading;
463 } else {
464 //llWhisper(0, "Parsed line " + (string)giNotecardLine + ": " + asLine);
465 gxPortRingStations += [
466 lvPosition,
467 llList2Rot(cxHeadingToRotation, liIdx + 1)
468 ] ;
469 if(lsName == "")
470 {
471 lsName = "Base";
472 }
473 gxPortRingStationNames += [ lsName ] ;
474 }
475 }
476 } else if("STATION" == lsLineType)
477 {
478 if(llGetListLength(gxPortRingInfo) == 0)
479 {
480 lsError = "Invalid notecard format - first entry must be PORTERS";
481 } else if(llGetListLength(gxPortRingStations) == 0)
482 {
483 lsError = "Invalid notecard format - BASE must occur before STATION lines";
484 } else {
485 vector lvPosition = (vector)(llList2String(lxLineInfo, 1));
486 string lsHeading = llList2String(lxLineInfo, 2);
487 integer liIdx = llListFindList(cxHeadingToRotation, [ lsHeading ]);
488 string lsName = llList2String(lxLineInfo, 3);
489 if(liIdx < 0)
490 {
491 lsError = "Invalid notecard format - unknown heading " + lsHeading;
492 } else {
493 //llWhisper(0, "Parsed line " + (string)giNotecardLine + ": " + asLine);
494 gxPortRingStations += [
495 lvPosition,
496 llList2Rot(cxHeadingToRotation, liIdx + 1)
497 ] ;
498 if(lsName == "")
499 {
500 integer num = llGetListLength(gxPortRingStationNames);
501 lsName = "Station " + (string)num;
502 }
503 gxPortRingStationNames += [ lsName ] ;
504 }
505 }
506 } else {
507 lsError = "Invalid notecard format - found unknown line type " + lsLineType;
508 }
509 }
510
511 if(lsError != "")
512 {
513 llWhisper(0, "ERROR: " + lsError);
514 llWhisper(0, (string)giNotecardLine + ": " + asLine);
515 state WaitingForNotecard ;
516 } else {
517 llGetNotecardLine(gsNotecardName, giNotecardLine);
518 giNotecardLine += 1;
519 }
520 }
521
522 }
523
524 ////////////////////////////////////////////////////////////////////////
525 //
526 // CreatingPortRing state:
527 //
528 // Call f_CreatePorterSet for the base and each station.
529 //
530 // For the base, the porter list will be a single 'porter set for
531 // "forward" pointing to station #1.
532 //
533 // For each station, the porter list will contain back (if not the
534 // first station), base, and forward (if not the last station).
535
536 state CreatingPortRing
537 {
538 on_rez(integer liStartCode)
539 {
541 }
542
544 {
545 llWhisper(0, "Creating PortRing...");
546
547 integer i;
548 integer liNumStations = (llGetListLength(gxPortRingStations) / 2) - 1;
549 vector lvStartingLocation;
550 vector lvBaseLocation;
551 rotation lrBaseRotation;
552 vector lvStationLocation;
553 rotation lrStationRotation;
554 vector lvNextStationLocation;
555 rotation lrNextStationRotation;
556 vector lvPreviousStationLocation;
557 rotation lrPreviousStationRotation;
558 string lsBackPorter;
559 string lsForwardPorter;
560 string lsBasePorter;
561 list lxPorters;
562 string lsBaseName;
563 string lsPreviousStationName;
564 string lsStationName;
565 string lsNextStationName;
566
567 lvStartingLocation = llGetPos();
568 lvStartingLocation.z -= llGround(ZERO_VECTOR);
569
570 // initialize BASE and first STATION values [as NEXT station]
571 lvBaseLocation = llList2Vector(gxPortRingStations, 0);
572 lrBaseRotation = llList2Rot(gxPortRingStations, 1);
573 lsBaseName = llList2String(gxPortRingStationNames, 0);
574 lvNextStationLocation = llList2Vector(gxPortRingStations, 2);
575 lrNextStationRotation = llList2Rot(gxPortRingStations, 3);
576 lsNextStationName = llList2String(gxPortRingStationNames, 1);
577 lsBackPorter = llList2String(gxPortRingInfo, 0);
578 lsForwardPorter = llList2String(gxPortRingInfo, 1);
579 lsBasePorter = llList2String(gxPortRingInfo, 2);
580
581 i = llListFindList(gxOptions, [",RINGSTYLE"]);
582 string lsRingStyleOption = llList2String(gxOptions, i+1);
583
584 // construct BASE 'porters, based on BASEPORTERS option.
585 i = llListFindList(gxOptions, [",BASEPORTERS"]);
586 string lsBasePortersOption = llList2String(gxOptions, i+1);
587
588 lxPorters = [
589 lsForwardPorter,
590 lvNextStationLocation,
591 lrNextStationRotation,
592 lsNextStationName
593 ];
594
595 if("ALL" == lsBasePortersOption)
596 {
597 for (i = 2; i <= liNumStations; i++)
598 {
599 lvStationLocation = llList2Vector(gxPortRingStations, i * 2);
600 lrStationRotation = llList2Rot(gxPortRingStations, i * 2 + 1);
601 lsStationName = llList2String(gxPortRingStationNames, i);
602 lxPorters += [
603 lsForwardPorter,
604 lvStationLocation,
605 lrStationRotation,
606 lsStationName
607 ];
608 }
609 } else if("FIRSTANDLAST" == lsBasePortersOption)
610 {
611 lvStationLocation = llList2Vector(gxPortRingStations, liNumStations * 2);
612 lrStationRotation = llList2Rot(gxPortRingStations, liNumStations * 2 + 1);
613 lsStationName = llList2String(gxPortRingStationNames, liNumStations);
614 lxPorters += [
615 lsForwardPorter,
616 lvStationLocation,
617 lrStationRotation,
618 lsStationName
619 ];
620 }
621
622 //llWhisper(0, "BASE : " + (string)lvBaseLocation + " @ " + (string)lrBaseRotation);
623 f_CreatePorterSet(lvBaseLocation, lrBaseRotation, lxPorters);
624
625 // then create stations
626 for (i = 1; i <= liNumStations; i++)
627 {
628
629 lvPreviousStationLocation = lvStationLocation;
630 lrPreviousStationRotation = lrStationRotation;
631 lsPreviousStationName = lsStationName;
632 lvStationLocation = lvNextStationLocation;
633 lrStationRotation = lrNextStationRotation;
634 lsStationName = lsNextStationName;
635
636 // construct lxPorters for BACK (if appropriate), BASE, FORWARD (if appropriate)
637 lxPorters = [ ] ;
638 if(i > 1)
639 {
640 lxPorters += [
641 lsBackPorter,
642 lvPreviousStationLocation,
643 lrPreviousStationRotation,
644 lsPreviousStationName
645 ];
646 } else if("LOOP" == lsRingStyleOption)
647 {
648 lvPreviousStationLocation = llList2Vector(gxPortRingStations, liNumStations * 2);
649 lrPreviousStationRotation = llList2Rot(gxPortRingStations, liNumStations * 2 + 1);
650 lsPreviousStationName = llList2String(gxPortRingStationNames, liNumStations);
651 lxPorters += [
652 lsBackPorter,
653 lvPreviousStationLocation,
654 lrPreviousStationRotation,
655 lsPreviousStationName
656 ];
657 }
658 lxPorters += [
659 lsBasePorter,
660 lvBaseLocation,
661 lrBaseRotation,
662 lsBaseName
663 ];
664 if(i < liNumStations)
665 {
666 lvNextStationLocation = llList2Vector(gxPortRingStations, i * 2 + 2);
667 lrNextStationRotation = llList2Rot(gxPortRingStations, i * 2 + 3);
668 lsNextStationName = llList2String(gxPortRingStationNames, i + 1);
669 lxPorters += [
670 lsForwardPorter,
671 lvNextStationLocation,
672 lrNextStationRotation,
673 lsNextStationName
674 ];
675 } else if("LOOP" == lsRingStyleOption)
676 {
677 lvNextStationLocation = llList2Vector(gxPortRingStations, 2);
678 lrNextStationRotation = llList2Rot(gxPortRingStations, 3);
679 lsNextStationName = llList2String(gxPortRingStationNames, 1);
680 lxPorters += [
681 lsForwardPorter,
682 lvNextStationLocation,
683 lrNextStationRotation,
684 lsNextStationName
685 ];
686 }
687
688 //llWhisper(0, "STATION " + (string)i + " : " + (string)lvStationLocation + " @ " + (string)lrStationRotation);
689 f_CreatePorterSet(lvStationLocation, lrStationRotation, lxPorters);
690 }
691
692 f_TeleportTo(lvStartingLocation);
693
694 state WaitingForNotecard;
695 }
696 }
697
698 ////////////////////////////////////////////////////////////////////////
699 //
700 // LICENSE FOR USE
701 //
702 // This code is copyright (c) 2004 by Johnson Earls.
703 // All rights reserved.
704 //
705 // Permission to use and redistribute this source code, with or without
706 // modifications, is granted under the following conditions:
707 //
708 // 1) This code may be used, in whole or in part, in other code, so
709 // long as the author is credited by SL name (Neo Rebus) or FL
710 // name (Johnson Earls).
711 // 2) This code, including portions of this code that are
712 // incorporated into other works, may be redistributed as long as
713 // it is accompanied by the author's original copyright notice,
714 // and a pointer ot the full original souce code. For example:
715 // Portions of this code are copyright (c) 2004 by Johnson
716 // Earls, used under license. Original code available at
717 // http://www.badgeometry.com/wiki/LibraryPortRingCreator
718 //
719 ////////////////////////////////////////////////////////////////////////
720 // END //

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