Added files

This commit is contained in:
Fred Beckhusen
2015-12-12 16:58:38 -06:00
parent 767e53f17d
commit 1ec08494b4
191 changed files with 25371 additions and 47 deletions

View File

@@ -4,7 +4,7 @@
// :AUTHOR:Ferd Frederix // :AUTHOR:Ferd Frederix
// :KEYWORDS:NPC, Puppeteer // :KEYWORDS:NPC, Puppeteer
// :CREATED:2015-10-12 18:07:40 // :CREATED:2015-10-12 18:07:40
// :EDITED:2015-10-12 17:07:40 // :EDITED:2015-12-05 19:25:52
// :ID:27 // :ID:27
// :NUM:1832 // :NUM:1832
// :REV:4.6 // :REV:4.6
@@ -17,7 +17,7 @@
// Should be worn as a HUD to record. // Should be worn as a HUD to record.
// Put it on the ground and click Sensor or Start NPC when done. // Put it on the ground and click Sensor or Start NPC when done.
// :CODE: // :CODE:
// This is Rev 4.5 09/26/2015 // This is Rev 4.6 12/04/2015
// Revision History // Revision History
// Rev 1.1 10-2-2014 @Sit did not work. Minor tweaks to casting for lslEditor // Rev 1.1 10-2-2014 @Sit did not work. Minor tweaks to casting for lslEditor
@@ -54,6 +54,7 @@
// @teleport works for relative and absolute modes // @teleport works for relative and absolute modes
// Rev 4.4 09-26-2015 if it could not find the (deleted) NPC, it could not restart // Rev 4.4 09-26-2015 if it could not find the (deleted) NPC, it could not restart
// Rev 4.5 09-29-2015 remove wait for STATE == 0 // Rev 4.5 09-29-2015 remove wait for STATE == 0
// Rev 4.6 12-4-2015 fixed wanderhold did not wander correctly.
//*******************************************************************// //*******************************************************************//
// Instructions on how to use this are at http://www.outworldz.com/opensim/posts/NPC/ // Instructions on how to use this are at http://www.outworldz.com/opensim/posts/NPC/
@@ -181,10 +182,10 @@
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// DEBUG // // DEBUG //
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
integer debug = FALSE; // set to TRUE or FALSE for debug chat on various actions integer debug = TRUE; // set to TRUE or FALSE for debug chat on various actions
integer LSLEditor = FALSE; // set to to TRUE to working in LSLEditor, FALSE for in-world. integer LSLEditor = FALSE; // set to to TRUE to working in LSLEditor, FALSE for in-world.
// you must also include the NPC commands found in the other script since LSLEditor does not support OpenSim // you must also include the NPC commands found in the other script since LSLEditor does not support OpenSim
integer iTitleText = TRUE; // set to TRUE to see debug info in text above the controller integer iTitleText = FALSE; // set to TRUE to see debug info in text above the controller
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// TUNABLE CONFIGURATION // // TUNABLE CONFIGURATION //
@@ -192,7 +193,7 @@ integer iTitleText = TRUE; // set to TRUE to see debug info in text above the
integer keyNum = -1; // (namaka) special number for link message to broadcast the NPC key integer keyNum = -1; // (namaka) special number for link message to broadcast the NPC key
integer allowListener = TRUE; // set to TRUE to anable a command listener. Usually, this is setto FALSE integer allowListener = TRUE; // set to TRUE to anable a command listener. Usually, this is setto FALSE
integer link_Channel = 4223; // some random number you want to talk to this gadget on. Best if large and negative integer link_Channel = 4223; // some random number you want to talk to this gadget on. Best if large and negative
float TIMER = 2; // faster = less jerky stopping. How often the system checks the distance traveled. Fastest you can go is 0.5 seconds float TIMER = 1; // faster = less jerky stopping. How often the system checks the distance traveled. Fastest you can go is 0.5 seconds
float QUICK = 1; // when we need to move to the next state, we use a QUICK timer float QUICK = 1; // when we need to move to the next state, we use a QUICK timer
string Appearance = "!Appearance"; // The name of the recorded Appearance notecard string Appearance = "!Appearance"; // The name of the recorded Appearance notecard
string Notecard = "!Path"; // The name of the recorded routes string Notecard = "!Path"; // The name of the recorded routes
@@ -1644,6 +1645,7 @@ default
// Wandering requires us to re-wander when we reach a destination // Wandering requires us to re-wander when we reach a destination
else if (WanderHold == STATE) { else if (WanderHold == STATE) {
StateWander(); StateWander();
return;
} }
else if (DoProcess == STATE) { else if (DoProcess == STATE) {
TimerEvent(QUICK); TimerEvent(QUICK);

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -0,0 +1,3 @@
<Solution name="Give all inventory items in a folder when close by">
<Project name="Give all inventory items in a folder when close by" path="Give all inventory items in a folder when close by\Give all inventory items in a folder when close by.prj" active="true"/>
</Solution>

View File

@@ -0,0 +1,10 @@
<Project name="Give all inventory items in a folder when close by" guid="47643d58-cfd1-4fb6-aea1-277c935847bb">
<Object name="Object" guid="dfefe270-c8f3-46d3-a706-bcbd19cfd927" active="true">
<Snapshot name="dragon lady5;2;5.jpg" guid="43d895e0-a601-461c-94d4-6a977cef6220">
</Snapshot>
<Snapshot name="dragon;4;4;5.jpg" guid="73685177-2a5b-4500-a85f-d740672ea814">
</Snapshot>
<Script name="Script for Board.lsl" guid="eb71690d-a6f8-4520-9fbb-57abde9fae58">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,171 @@
// :SHOW:
// :CATEGORY:Presentation
// :NAME:Give all inventory items in a folder when close by
// :AUTHOR:Lum Pfohl
// :KEYWORDS:
// :CREATED:2015-11-24 20:25:32
// :EDITED:2015-11-24 19:25:32
// :ID:1086
// :NUM:1833
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// LumVision-Presentation Script v 0.2
// :CODE:
// Mods by Ferd Frederix to support GIFS
//
// LumVision-Presentation Script v 0.2
//
// Written by Lum Pfohl December 11, 2007
//
// January 02, 2008 - Added code to precache the next texture after a short time delay
// set to TRUE if you want debug messages written to chat screen
integer __debug = FALSE;
string __version_id = "Presentation Script v 0.3";
// global variables
integer interval;
integer currentTexture = 0;
integer totalTextures = 0;
list textureList =[];
integer messageChannel = 999888;
list dynMenu =["Back", "Version", "Forward", "Reset"];
gif()
{
string t = llList2String(textureList, currentTexture);
list gif = llParseString2List(t,[";"],[]);
string aname = llList2String(gif,0);
integer X = (integer) llList2String(gif,1);
integer Y = (integer) llList2String(gif,2);
float FPS = (float) llList2String(gif,3);
float product = X * Y;
// Set the new prim texture
llSetTexture(llList2String(textureList, currentTexture), 0);
if (X) {
llSetTextureAnim( ANIM_ON | LOOP, ALL_SIDES, X, Y, 0.0, product, FPS);
} else {
llSetTextureAnim( LOOP, ALL_SIDES, 1,1, 0.0, 1 , FPS);
}
}
default {
state_entry() {
// read in the textures in the prim and store it
integer typeCount = llGetInventoryNumber(INVENTORY_TEXTURE);
integer j;
for (j = 0; j < typeCount; ++j) {
string invName = llGetInventoryName(INVENTORY_TEXTURE, j);
if (__debug) {
llWhisper(0, "Inventory " + invName);
}
textureList += invName;
++totalTextures;
}
if (__debug) {
llWhisper(0, "Found " + (string) totalTextures + " textures");
}
llSetTexture(llList2String(textureList, 0), 0);
gif();
// initialize the channel on which the vendor will talk to the owner via dialog
messageChannel = (integer) llFrand(2000000000.0);
llListen(messageChannel, "", NULL_KEY, "");
currentTexture = 0;
}
on_rez(integer start_param) {
llResetScript();
}
touch_start(integer total_number) {
if (llDetectedKey(0) == llGetOwner()) {
llDialog(llDetectedKey(0), "What do you want to do?", dynMenu, messageChannel);
}
}
// listen for for dialog box messages and respond to them as appropriate
listen(integer channel, string name, key id, string message) {
if (id != llGetOwner()) {
return;
}
if (message == "Version") {
llWhisper(0, __version_id);
return;
}
if (message == "Reset") {
llResetScript();
}
if (message == "Back" && currentTexture > 0) {
--currentTexture;
} else if (message == "Forward") {
++currentTexture;
} else {
llDialog(llGetOwner(), "What do you want to do?", dynMenu, messageChannel);
return;
}
// If there are textures to apply, do so now. Otherwise - quietly
// do nothing.
if (totalTextures > 0) {
// Ensure that we do not go out of bounds with the index
if (currentTexture >= totalTextures) {
currentTexture = 0;
}
if (currentTexture < 0 ) {
currentTexture = 0;
}
gif();
// set up so that in 3 seconds, we display the next image on a different face (hidden)
llSetTimerEvent(3.00);
llDialog(llGetOwner(), "What do you want to do?", dynMenu, messageChannel);
}
}
timer() {
// Cancel any further timer events
llSetTimerEvent(0.00);
// set the next texture (as a pre-cache) on the reverse face
integer nextTexture = currentTexture + 1;
if (nextTexture >= totalTextures) {
nextTexture = 0;
}
llSetTexture(llList2String(textureList, nextTexture), 1);
}
changed(integer what)
{
if (what & CHANGED_INVENTORY)
llResetScript();
}
}

View File

@@ -0,0 +1,12 @@
default
{
state_entry()
{
llSay(0, "Hello, Avatar!");
}
touch_start(integer total_number)
{
llSay(0, "Touched: "+(string)total_number);
}
}

View File

@@ -0,0 +1,39 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Collider for All in One NPC Controller
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :REV:2.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Triggers the NPC controller to play the Greet notecard when collided.
// :CODE:
string message = "@notecard=Greet";
Reset() {
llSetStatus(STATUS_PHANTOM, FALSE); // rev 2.0
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default{
state_entry(){
Reset();
}
collision_start(integer n){
if (osIsNpc(llDetectedKey(0))){
return;
}
llMessageLinked(2,0,message,"");
}
on_rez(integer p){
llResetScript();
}
changed(integer what){
if (what & CHANGED_REGION_START){
llResetScript();
}
}
}

View File

@@ -0,0 +1,23 @@
//:AUTHOR: Ferd Frederix
//:DESCRIPTION:
// Button Script for console
//:CODE:
string E = "<1,0,0>";
string NE = "<1,1,>";
string N = "<0,1,0>";
string NW = "<-1,1,0>";
string W = "<-1,0,0>";
string SW = "<-1,-1,0>";
string S = "<0,-1,0>";
string WE = "<1,-1,0>";
// chose a direction for one of 8 buttons.
default
{
touch_start(integer total_number)
{
llMessageLinked(LINK_SET,0,N,"");
}
}

View File

@@ -0,0 +1,39 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Collider for All in One NPC Controller
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :REV:2.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Triggers the NPC controller to play the Greet notecard when collided.
// :CODE:
string message = "@notecard=!Path";
Reset() {
llSetStatus(STATUS_PHANTOM, FALSE); // rev 2.0
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default{
state_entry(){
Reset();
}
collision_start(integer n){
if (osIsNpc(llDetectedKey(0))){
return;
}
llMessageLinked(LINK_SET,1,message,""); // 1 ios for doorway only
}
on_rez(integer p){
llResetScript();
}
changed(integer what){
if (what & CHANGED_REGION_START){
llResetScript();
}
}
}

View File

@@ -0,0 +1,55 @@
integer busy ;
integer Helmet_Channel = 576;
key NamakasKey;
float MaxBeam = 2.0; // how far the helmet beam happens
vector currPos(); // Namakas current position;
vector centerPoint = <128,128,32>; // the center of where Namaka can walk
list avatarPos = [<0,1,1>,<2,2,2>,<3,3,3> ]; // all 6 avatars are here
default
{
state_entry()
{
}
link_message(integer sender_number, integer number, string message, key id)
{
// -1 is Namakas key
// 0 is for NPC direction commands
// 1 is for doorway
// 2 is the helment beam channel
if (number == -1){
NamakasKey = id;
} else if (number == 0){
if (! busy) {
llMessageLinked(LINK_SET,1,message);
}
} else if (number == 1) {
vector direction = (vector) message;
} else if (number == 2){
// GO
llShout(Helmet_Channel,"BOOM");
integer i;
integer j = llGetListLength(avatarPos);
for (i = 0; i < j; i++)
{
float dist = llVecDist(llList2Vector(avatarPos,i),centerPoint);
if (dist > MaxBeam) {
ChangeNPC();
ToDo --;
if (ToDo == 0) {
Win();
}
}
}
}
}
}

View File

@@ -0,0 +1,14 @@
//:AUTHOR: Ferd Frederix
//:DESCRIPTION:
// Button Script for console
//:CODE:
// chose a direction for one of 8 buttons.
default
{
touch_start(integer total_number)
{
llMessageLinked(LINK_SET,2,"go","");
}
}

View File

@@ -0,0 +1,10 @@
dylan|1|@animate=SwayInBreeze|2
dylan|2|@animate=avatar_type|2
dylan|8|@say=I think this is the place where we can transform back to our original selves
namaka|2|@animate=avatar_type|3
namaka|1|@say=you spoke too soon, my love, there is no exit from this area.
dylan|1|@animate=avatar_type|10
dylan|2|@say=We must ask you again to help us. Perhaps pressing that button will do something.

View File

@@ -0,0 +1,224 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Sequencer and Collider for All in One NPC Controller
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :REV:1.0
// :WORLD:Opensim
// :DESCRIPTION:
// Sequencer script for NPC animator for HyperGrid Story nine sim. It sequences multiple NPCs in order thru a scenarios
// each 'things' entry is the NPC number, a (float) time to take between sending commands ( 0 is not allowed, but a small number is()
///and a @command that is sent to the NPC.
// :CODE:
// Notes: Link messages arte as follows
// Rev: 2 fixes the Linux bug for collisions.
//
integer debug = 1; // set to TRUE or FALSE for debug chat on various actions
// list of NPCs and their linked prim numbers
list npcName = ["namaka",2,"dylan",3,"npc1",4,"npc2",5,"npc3",6,"npc4",7,"npc5",8,"npc6",9];
integer CommandChannel = 23;
// DEBUG(string) will chat a string or display it as hovertext if debug == TRUE
DEBUG(string str) {
if (debug ==1 )
llSay(0, llGetScriptName() + ":" + str);
if (debug ==2 )
llSetText(str,<1,1,1>,1.0);
}
integer osIsNpc(key id){
return FALSE;
}
string osGetNotecard(string name) {
// sample notecard for testing
string str = "NPC #| seconds | Command\n"
+"npc1|0|@pause=1\n"
+"sylan|0|@animate=avatar_jumpforjoy|5\n"
+"namaka|0|@say=Hello! What happened to you two?\n"
+"Derf|0|@say=error\n"
+"dylan|2|@animate=avatar_type|2\n"
+"dylan|8|@say=I think we can transform back to our original selves, at last.\n";
return str;
}
integer SENSE = FALSE; // sensor for an avatar
float RATE = 5; // every 5 seconds
integer COLLIDE = TRUE; // if they collide, trigger the sequence
float RANGE = 96; // a very short range as this goes into a ring around the avatar
integer Rezzed;
list things ;
// CODE follows
Send(string who, string cmd)
{
DEBUG("Sending to " + who + "(" + (string) lookup(who) + ") the command " + cmd);
llMessageLinked(lookup(who),0,cmd,"");
}
integer lookup(string Name)
{
integer i = llListFindList(npcName,[Name]);
if (i != -1)
return llList2Integer(npcName,i+1);
return 0;
}
// For rezzing in
RezIn()
{
DEBUG("Rezz In = @reset");
llMessageLinked(LINK_SET,0,"@reset","");
}
DoIt()
{
string note = osGetNotecard("Sequence");
list stuff= llParseString2List(note,["\n"],[]);
DEBUG("stuff:" + llDumpList2String(stuff,":"));
integer i;
integer j = llGetListLength(stuff);
for (i=0; i < j; i++)
{
string noteline = llList2String(stuff,i);
DEBUG("noteline:" + noteline);
list line = llParseString2List(noteline,["|"],[]);
string primName = llList2String(line,0);
float sleepTime = llList2Integer(line,1);
string atCmd = llList2String(line,2);
string param1= llList2String(line,3);
string param2= llList2String(line,4);
DEBUG("prim:" + primName);
DEBUG("num:" + (string) lookup(primName));
DEBUG("time:" + (string) sleepTime);
DEBUG("atCmd:" +atCmd);
if (lookup(primName) && llSubStringIndex(atCmd,"@") == 0)
{
things += lookup(primName);
things += sleepTime;
things += atCmd+"|" + param1 + "|" + param2;
}
}
DEBUG("Things:" + llDumpList2String(things,":"));
}
Speak() {
integer prim = llList2Integer(things,0);
float time = llList2Float(things,1);
string msg = llList2String(things,2);
DEBUG("Prim:" + (string) prim + " time:" + (string) time + " Msg:" + msg);
if (llStringLength(msg)) {
things = llDeleteSubList(things,0,2);
DEBUG("LINK:" +(string) prim + ":" + msg);
llMessageLinked(prim,0, msg,"");
if (time > 0) {
llSetTimerEvent(time);
} else {
llSetTimerEvent(0.1);
}
} else {
DEBUG("Done");
Rezzed = 0;
llSetTimerEvent(0);
if (SENSE)
llSensorRepeat("","",AGENT,RANGE,PI,RATE);
}
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
RezIn();
llSetTimerEvent(0);
if (SENSE)
llSensorRepeat("","",AGENT,RANGE,PI,RATE);
llListen(CommandChannel,"","","");
}
touch_start(integer p) {
DEBUG("touched");
if (llGetOwner() == llDetectedKey(0))
{
Send("Claire","@say=touched");
}
}
listen(integer channel, string name, key id, string message)
{
DEBUG(message);
list vars = llParseString2List(message,["|"],[]);
string num = llList2String(vars,0);
string cmd = llList2String(vars,1);
Send(num, cmd);
}
sensor(integer n) {
DEBUG("Sensed");
if (! osIsNpc(llDetectedKey(0))) {
DEBUG("Sensed avatar");
llSensorRemove();
RezIn();
}
}
timer()
{
Speak();
}
collision_start(integer n) {
DEBUG("Collided with " + llKey2Name(llDetectedKey(0)));
if (! osIsNpc(llDetectedKey(0)))
{
DoIt();
Speak();
}
}
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,265 @@
//HYPERGRID STORY NINE
// List NPC Listener channels
//sara=11 sammy=12 claire=13 jolinda=14 tiny=15 tiny2=16 fireworks=20
integer gListener; // Listener for handling different channels
integer gSimpleMenuChannel; // The channel used for the menu
float gTimerInterval = 1; // Keep this at 1 for your sanity.
list gTimeoutList;
float gTimeElapsed=0;
integer gAutofire=FALSE;
//============================================================================
vector gFacecolor=<1.0,0.0,0.0>; //RED
integer gNewTime;
integer gOldTime;
//==Function that returns a random number for our menu handler channel
integer randomchannel() {
return((integer)(llFrand(99999.0)*-1));
}
menu(key id, integer channel, string title, list buttons) {
llListenRemove(gListener);
gListener = llListen(channel,"",id,"");
llDialog(id,title,buttons,channel);
// TimerEvent for killing the menu listener
settimeout("untouched", 30); //call untouched timeout
}
simplemenu(key id) {
gSimpleMenuChannel = randomchannel();
menu(id,gSimpleMenuChannel,"Select an option",["FIREWORKS","SARA","SAMMY","CLAIRE","JOLINDA","TINY","TINY2","LeadNPC","Finale!","CeaseFire"]);
}
settimeout(string timereventid, float time) {
if(gTimeoutList == [])
llSetTimerEvent(gTimerInterval);
integer identifyerIndex = llListFindList(gTimeoutList, [timereventid]);
if (identifyerIndex != -1)
gTimeoutList = llDeleteSubList(gTimeoutList, identifyerIndex - 1, identifyerIndex);
if (time != 0) {
gTimeoutList += time + gTimeElapsed;
gTimeoutList += timereventid;
}
gTimeoutList = llListSort(gTimeoutList, 2, TRUE);
}
timeout(string timereventid)
{
if (timereventid == "untouched")
{
llSay(0, "I have been untouched for 30 seconds, killing menu listener!");
llListenRemove(gListener); // kill the listener after 30 seconds inactivity
}
else if (timereventid == "countdown2execute")
{
float seconds2count = 1800;
llSay(0, "I have counted down " + (string)seconds2count + " seconds, repeat countdown and start the show");
settimeout("countdown2execute", seconds2count); //call it again to loop.
}
else if (timereventid == "autofire")
{
if(gAutofire)
{
llSay(0,"should fire every 5 seconds.");
llRegionSay(20,"Go");
settimeout("autofire", 5);
}
}
if (timereventid == "stopautofire")
{
gAutofire=FALSE;
}
}
timertick()
{
gTimeElapsed += gTimerInterval;
integer i;
integer numTimers = llGetListLength(gTimeoutList);
for (i = 0; i < numTimers; i += 2)
{
float triggerTime = llList2Float(gTimeoutList, i);
if (triggerTime <= gTimeElapsed)
{
string timereventid = llList2String(gTimeoutList, i + 1);
gTimeoutList = llDeleteSubList(gTimeoutList, i, i + 1);
timeout(timereventid);
if (timereventid=="countdown2execute")
{
displaycountdowntext((integer)gTimeElapsed);
getdigit((integer)gTimeElapsed);
}
if (gTimeoutList == [])
llSetTimerEvent(0);
}
else
{
return;
}
}
}
displaydigit(integer n, string d){
list Facelist; //list depends on your mesh digital readout face number.
integer i;
if(n==0) Facelist=[ 1,1,1,1,0,1,1 ]; //index @0 | 7 faces per digit
if(n==1) Facelist=[ 0,0,1,0,0,1,0 ];
if(n==2) Facelist=[ 1,1,0,1,1,1,0 ];
if(n==3) Facelist=[ 1,1,1,0,1,1,0 ];
if(n==4) Facelist=[ 0,0,1,0,1,1,1 ];
if(n==5) Facelist=[ 1,1,1,0,1,0,1 ];
if(n==6) Facelist=[ 0,1,1,1,1,0,1 ];
if(n==7) Facelist=[ 1,0,1,0,0,1,0 ];
if(n==8) Facelist=[ 1,1,1,1,1,1,1 ];
if(n==9) Facelist=[ 1,0,1,0,1,1,1 ];
integer l = llGetLinkNumber() != 0;
integer x = llGetNumberOfPrims() + l;
for (; l < x; ++l){
if (llGetLinkName(l) == d){
for (i=0;i<7;i++){
llSetLinkPrimitiveParamsFast(l,[PRIM_COLOR,i,gFacecolor,llList2Float(Facelist,i)]);
}
}
}
}
getdigit(integer time){
string dOne;
string dTen;
string dHundred;
string dThousand;
integer i;
if (time<10){
dOne=(string)time;
dTen="0";
dHundred="0";
dThousand="0"; // add your digits here
}else if(time<100){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,0,0);
dHundred="0";
dThousand="0";
}else if(time<1000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,1,1);
dHundred=llGetSubString((string)time,0,0);
dThousand="0";
}else if(time<10000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,2,2);
dHundred=llGetSubString((string)time,1,1);
dThousand=llGetSubString((string)time,0,0);
}
displaydigit((integer)dOne, "one");
displaydigit((integer)dTen, "ten");
displaydigit((integer)dHundred, "hundred");
displaydigit((integer)dThousand, "thousand");
}
displaycountdowntext(integer time){
gNewTime = time;
if (gOldTime < gNewTime){
llSetText("Elapsed Ticker: " + (string)gNewTime + " ticks",<1,1,.6>,1.0);
gOldTime = gNewTime;
}
}
default
{
state_entry()
{
float seconds2count = 3600;
settimeout("countdown2execute", seconds2count);
}
touch_start(integer num)
{
simplemenu(llDetectedKey(0));
}
listen (integer channel, string name, key id, string message)
{
if (message == "FIREWORKS") {
llSay(0,"You selected option FIREWORKS");
llRegionSay(20,"Go");
//do something else here
}
else if (message == "SARA")
{
llSay(0,"You selected option SARA");
llRegionSay(11,"@go");
//do something else here
}
else if (message == "SAMMY")
{
llSay(0,"You selected option SAMMY");
llRegionSay(12,"@go");
//do something else here
}
else if (message == "CLAIRE")
{
llSay(0,"You selected option CLAIRE");
llRegionSay(13,"@go");
//do something else here
}
else if (message == "JOLINDA")
{
llSay(0,"You selected option JOLINDA");
llRegionSay(14,"@go");
//do something else here
}
else if (message == "TINY")
{
llSay(0,"You selected option TINY");
llRegionSay(15,"@go");
//do something else here
}
else if (message == "TINY2")
{
llSay(0,"You selected option TINY2");
llRegionSay(16,"@go");
//do something else here
}
else if (message == "LeadNPC")
{
llSay(0,"You selected option LeadNPC");
llRegionSay(10,"@go");
//do something else here
}
else if (message == "Finale!")
{
llSay(0,"You selected option Finale!");
gAutofire=TRUE;
settimeout("autofire", 1);
settimeout("stopautofire", 90);
//do something else here
}
else if (message == "CeaseFire")
{
llSay(0,"You selected option CeaseFire");
gAutofire=FALSE;
//do something else here
}
simplemenu(id); // refresh menu
}
timer()
{
timertick();
integer MaxTicks = 1800; //Ticks to countdown from
//limit the ticker to maximum ticks
if(gTimeElapsed >= MaxTicks){
gTimeElapsed=0;
}
integer CountDown = MaxTicks - (integer)gTimeElapsed;
integer mm = (CountDown / 60) * 100;
integer ss = (CountDown % 60);
integer cc = mm + ss;
displaycountdowntext((integer)gTimeElapsed);
getdigit((integer)cc);
}
}

View File

@@ -0,0 +1,395 @@
//:Name: HYPERGRID STORY NINE
//:Author: Shin Ingen
//:REV:1.0
//:DESCRIPTION:
// Timer controller
//:CODE:
// lots of mods by Ferd
//
integer debug = 2;
// Link Numbers of the NPC controller
integer namaka =2;
integer dylan =3;
integer npc1 =4;
integer npc2 =5;
integer npc3 =6;
integer npc4 =7;
integer npc5 =8;
integer npc6 =9;
// List of NPC Listener channels
integer gFireworksChannel =20;
integer gTeleportChannel = 21;
integer CommandChannel = 23;
integer gSimpleMenuChannel = 999; // The channel used for the menu
integer MaxTicks = 60; // Show length
// The repeat the show timer
list kDance1 = ["Dance1",1]; // Dance
list kDance2 = ["Dance2",10]; // Dance
list kDance3 = ["Dance3",20]; // Dance
list kDance4 = ["Dance4",30]; // Dance
list kDance5 = ["Dance5",40]; // Dance
list kDance6 = ["Dance6",50]; // Dance
list kFireworksRepRate = ["Shoot", 2]; // rep rate for finale
// the following are calculated based on the current timer tick
list kFireworksStartsAt = ["StartFireworks", 99999]; // rep rate for finale
list kRaiseTeleport = ["BeamMeUp",99999]; // raise the teleports
list kStopAutoFire = ["EndFireworks",99999]; // and stops here
SendMessageLinked(integer npc, string cmd)
{
llRegionSay(CommandChannel,(string) npc + "|" + cmd);
}
DoCmd(string message, integer channel)
{
if (channel == CommandChannel) {
Process(message);
}
if (message == "ShowTime") {
DEBUG("Running");
ShowTime();
}
else if (message == "Finale!")
{
kFireworksStartsAt = ["StartFireworks", gTimeElapsed+1]; // rep rate for finale
kRaiseTeleport = ["BeamMeUp",gTimeElapsed+25]; // raise the teleports
kStopAutoFire = ["EndFireworks",gTimeElapsed+30]; // and stops here
settimeout(kFireworksStartsAt);
settimeout(kStopAutoFire);
settimeout(kRaiseTeleport);
}
else if (message == "Stop")
{
llSay(0,"You selected option Stop");
gTimeoutList = [];
}
}
// this is a list of all the cycling show bits
ShowTime()
{
DEBUG("Starting Countdown");
gTimeElapsed=0;
settimeout(kDance1);
settimeout(kDance2);
settimeout(kDance3);
settimeout(kDance4);
settimeout(kDance5);
settimeout(kDance6);
DEBUG(llDumpList2String(gTimeoutList,":"));
}
Process(string timereventid) {
if (llList2String(kDance1,0) == timereventid)
{
DEBUG("Dance1");
;
SendMessageLinked(dylan,"@appearance=Dylan");
SendMessageLinked(namaka,"@appearance=Namaka");
SendMessageLinked(npc1,"@appearance=Crispen Enpeacee");
SendMessageLinked(npc2,"@appearance=Alessandra Enpeacee");
SendMessageLinked(npc3,"@appearance=Sammy Enpeacee");
SendMessageLinked(npc4,"@appearance=Jolinda Enpeacee");
SendMessageLinked(npc5,"@appearance=Claire Enpeacee");
SendMessageLinked(npc6,"@appearance=Marianne Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance1");
}
else if (llList2String(kDance2,0) == timereventid)
{
DEBUG("Dance2");
SendMessageLinked(LINK_SET,"@appearance=Alessandra Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance2");
}
else if (llList2String(kDance3,0) == timereventid)
{
DEBUG("Dance3");
SendMessageLinked(LINK_SET,"@appearance=Sammy Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance3");
}
else if (llList2String(kDance4,0)== timereventid)
{
DEBUG("Dance4");
SendMessageLinked(LINK_SET,"@appearance=Jolinda Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance4");
}
else if (llList2String(kDance5,0)== timereventid)
{
DEBUG("Dance5");
SendMessageLinked(LINK_SET,"@appearance=Claire Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance5");
}
else if (llList2String(kDance6,0)== timereventid)
{
DEBUG("Dance6");
SendMessageLinked(LINK_SET,"@appearance=MarianneEnpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance6");
}
else if (llList2String(kFireworksStartsAt,0) == timereventid)
{
DEBUG("Shoot!");
SendMessageLinked(LINK_SET,"@appearance=Dragon");
SendMessageLinked(LINK_SET,"@notecard=Fireworks");
llRegionSay(gFireworksChannel,"Go");
settimeout(kFireworksRepRate);
}
else if (llList2String(kFireworksRepRate,0) == timereventid)
{
DEBUG("Fireworks Start");
llRegionSay(gFireworksChannel,"Go");
SendMessageLinked(npc1,"@appearance=Crispen Enpeacee");
SendMessageLinked(npc2,"@appearance=Alessandra Enpeacee");
SendMessageLinked(npc3,"@appearance=Sammy Enpeacee");
SendMessageLinked(npc4,"@appearance=Jolinda Enpeacee");
SendMessageLinked(npc5,"@appearance=Claire Enpeacee");
SendMessageLinked(npc6,"@appearance=Marianne Enpeacee");
SendMessageLinked(dylan,"@appearance=Dylan");
SendMessageLinked(namaka,"@appearance=Namaka");
SendMessageLinked(LINK_SET,"@notecard=Final");
settimeout(kFireworksRepRate);
}
else if (llList2String(kStopAutoFire,0) == timereventid)
{
DEBUG("Fireworks End");
deletetimeout(kFireworksRepRate);
settimeout(kRaiseTeleport);
}
else if (llList2String(kRaiseTeleport,0) == timereventid)
{
SendMessageLinked(LINK_SET,"@notecard=Teleport");
DEBUG("Teleports Up");
llRegionSay(gTeleportChannel,"Up");
}
}
integer busy;
integer gListener; // Listener for handling different channels
list gTimeoutList;
float gTimeElapsed=0;
//============================================================================
vector gFacecolor=<1.0,0.0,0.0>; //RED
DEBUG(string msg)
{
if (debug ==1)
llSay(0,llGetScriptName() + ":" + msg);
if (debug ==2)
llSetText(msg, <1,0,0>,1.0);
}
menu(key id, integer channel, string title, list buttons) {
llListenRemove(gListener);
gListener = llListen(channel,"",id,"");
llDialog(id,title,buttons,channel);
}
simplemenu(key id) {
menu(id,gSimpleMenuChannel,"Select an option",["ShowTime","Finale","Stop"]);
}
deletetimeout(list events) {
string timereventid = llList2String(events,0);
DEBUG("Deleteing timer event " + timereventid);
integer identifyerIndex = llListFindList(gTimeoutList, [timereventid]);
if (identifyerIndex != -1)
gTimeoutList = llDeleteSubList(gTimeoutList, identifyerIndex - 1, identifyerIndex);
}
settimeout(list events)
{
// unpack the list
string timereventid = llList2String(events,0);
integer time = llList2Integer(events,1);
DEBUG("Adding " + timereventid);
integer identifyerIndex = llListFindList(gTimeoutList, [timereventid]);
if (identifyerIndex != -1)
gTimeoutList = llDeleteSubList(gTimeoutList, identifyerIndex - 1, identifyerIndex);
if (time != 0) {
gTimeoutList += time;
gTimeoutList += timereventid;
}
llSetTimerEvent(1.0);
}
timertick() {
gTimeElapsed ++;
//DEBUG((string) gTimeElapsed );
integer i;
integer numTimers = llGetListLength(gTimeoutList);
//DEBUG((string) (numTimers/2) + " timers");
// scan over all queued timers
for (i = 0; i < numTimers; i += 2)
{
integer triggerTime = llList2Integer(gTimeoutList, i);
//DEBUG("TriggerTime = " + (string)triggerTime);
if (triggerTime == gTimeElapsed) {
string timereventid = llList2String(gTimeoutList, i + 1);
//DEBUG("matched " + timereventid);
gTimeoutList = llDeleteSubList(gTimeoutList, i, i + 1); // they are one-shots, so delete the event that just happened.
Process(timereventid); // process the callback
if (gTimeoutList == []) {
DEBUG("Show over! Starting back up");
ShowTime();
}
}
}
}
displaydigit(integer n, string d){
list Facelist; //list depends on your mesh digital readout face number.
integer i;
if(n==0) Facelist=[ 1,1,1,1,0,1,1 ]; //index @0 | 7 faces per digit
if(n==1) Facelist=[ 0,0,1,0,0,1,0 ];
if(n==2) Facelist=[ 1,1,0,1,1,1,0 ];
if(n==3) Facelist=[ 1,1,1,0,1,1,0 ];
if(n==4) Facelist=[ 0,0,1,0,1,1,1 ];
if(n==5) Facelist=[ 1,1,1,0,1,0,1 ];
if(n==6) Facelist=[ 0,1,1,1,1,0,1 ];
if(n==7) Facelist=[ 1,0,1,0,0,1,0 ];
if(n==8) Facelist=[ 1,1,1,1,1,1,1 ];
if(n==9) Facelist=[ 1,0,1,0,1,1,1 ];
integer l = llGetLinkNumber() != 0;
integer x = llGetNumberOfPrims() + l;
for (; l < x; ++l){
if (llGetLinkName(l) == d){
for (i=0;i<7;i++){
llSetLinkPrimitiveParamsFast(l,[PRIM_COLOR,i,gFacecolor,llList2Float(Facelist,i)]);
}
}
}
}
getdigit(integer time){
string dOne;
string dTen;
string dHundred;
string dThousand;
if (time<10){
dOne=(string)time;
dTen="0";
dHundred="0";
dThousand="0"; // add your digits here
}else if(time<100){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,0,0);
dHundred="0";
dThousand="0";
}else if(time<1000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,1,1);
dHundred=llGetSubString((string)time,0,0);
dThousand="0";
}else if(time<10000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,2,2);
dHundred=llGetSubString((string)time,1,1);
dThousand=llGetSubString((string)time,0,0);
}
displaydigit((integer)dOne, "one");
displaydigit((integer)dTen, "ten");
displaydigit((integer)dHundred, "hundred");
displaydigit((integer)dThousand, "thousand");
//DEBUG(dThousand + dHundred + ":" + dTen + dOne);
}
StopAll()
{
DEBUG("Stopped");
llSetTimerEvent(0);
}
default
{
state_entry()
{
llListen(CommandChannel,"","","");
getdigit(0);
}
touch_start(integer num)
{
if ( llGetOwner() == llDetectedKey(0)) {
if (! busy) {
simplemenu(llDetectedKey(0));
busy++;
} else {
busy = FALSE;
StopAll();
}
}
}
link_message(integer sender_number, integer number, string message, key id)
{
DEBUG("LINK MESSAGE\n" + message);
DoCmd(message, number);
}
listen (integer channel, string name, key id, string message)
{
// !!! add parser for killing the NPC
DEBUG("LISTEN\n" + message);
DoCmd(message, channel);
}
timer()
{
timertick();
//limit the ticker to maximum ticks
if(gTimeElapsed >= MaxTicks){
gTimeElapsed=0;
}
integer CountDown = MaxTicks - (integer)gTimeElapsed;
integer mm = (CountDown / 60) * 100;
integer ss = (CountDown % 60);
integer cc = mm + ss;
getdigit((integer)cc);
}
}

View File

@@ -0,0 +1,3 @@
<Solution name="HyperGrid Story Nine">
<Project name="Nine" path="Nine\Nine.prj" active="true"/>
</Solution>

View File

@@ -0,0 +1,50 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1834
// :REV:2.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Triggers the NPC controller to play the Greet notecard when collided.
// :CODE:
string message = "@notecard=Greet";
Reset() {
llSetStatus(STATUS_PHANTOM, FALSE); // rev 2.0
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default{
state_entry(){
Reset();
}
collision_start(integer n){
if (osIsNpc(llDetectedKey(0))){
return;
}
llMessageLinked(2,0,message,"");
llSetTimerEvent(10);
}
timer()
{
Reset();
llSetTimerEvent(0);
}
on_rez(integer p){
llResetScript();
}
changed(integer what){
if (what & CHANGED_REGION_START){
llResetScript();
}
}
}

View File

@@ -0,0 +1,103 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:NPC, controller, cyber helmet
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1836
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// NPC helmet controller
// Accepts a single link message to make the cyber being helmet flash for a second or two.
// worn by the NPC
// :CODE:
// TUNABLES
integer debug = 0;
// GLOBALS
integer counter = 0;
// FUNCTIONS
DEBUG(string msg)
{
if (debug & 1)
llSay(0,llGetScriptName() + ":" + msg);
if (debug & 2)
llSetText(msg, <1,0,0>,1.0);
}
NpcSaySomething(){
list sayings = ["The helmet begins to glow","A beam of light appears","The helmet begins to hum","The cyberbeing helmet is activated", "bzzz", "Zap","KaPow!"];
key NpcKey = llGetOwner();
DEBUG("Owner Key = " + (string) NpcKey);
llSay(0, llList2String(sayings,counter++));
if (counter > llGetListLength(sayings)) {
counter = 0;
}
}
Go()
{
NpcSaySomething();
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,.2, PRIM_SIZE, <2,2,2>,PRIM_COLOR,ALL_SIDES,<1,1,1>,0.5 ]);
llSetTimerEvent(2);
}
integer Helmet_Channel = 576;
default
{
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
state_entry()
{
llSetText("", <1,0,0>,1.0);
llListenRemove(listener);
llSetTextureAnim(ANIM_ON | SMOOTH | LOOP , ALL_SIDES, 1, 1, 1.0, 1.0, 1.0);
}
link_message(integer total_number, integer Num, string text, key id)
{
if ( text =="BOOM")
Go();
}
timer()
{
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0.2, PRIM_SIZE, <1.5,1.5,1> ] );
llSleep(0.25);
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0.2, PRIM_SIZE, <1.2,1.2,1> ] );
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0, PRIM_SIZE, <1,1,1> ] );
llSleep(0.25);
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0, PRIM_SIZE, <1,1,1>,PRIM_COLOR,ALL_SIDES,<1,1,1>,0 ] );
llSetTimerEvent(0);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,347 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:NPC, controller, console
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1838
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// NPC console controller
// Accepts button input from 8 buttons in a compass rose configuration
// Controls a pait of NPCS to xap 6 other NPCs.
// :CODE:
//vector osNpcGetPos(key id) { return <128,128,20>; }
// TUNABLES
integer debug = 0;
integer CommandChannel = 23;
integer BUSY;
string errorbeep = "back-in-time";
string footsteps = "footstepmuffled";
string click = "coins_bag_2_3";
string sex="Sex";
string effect="magic-string-spell-2";
integer gFireworksChannel =20;
integer STATE = 0;
float LASTDIST = 1;
integer counter = 0;
list FarAway = ["She is too far away","Move her closer to the dancers", "Move her near the dancers and press the center button.","What button did you just push?","Is she stuck?", "I hope this is working"];
integer counter1 = 0;
list Instructions = ["She is moving","Move her next to the dancers", "Try the center button.","Try the other direction","I think you have to get near a dancer", "Move her close to the dancers and press the center button", "Keep going", " This looks good"];
float MAXDIST = 15;
float MaxBeam = 3.0; // how far the helmet beam happens
vector centerPoint = <213.89366, 129.07689, 39.56485>;
// first three are root, namaka, and dylan
list avatarDancePos= [ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR,ZERO_VECTOR];
list avatars;
// Link Numbers of the NPC controller
integer namaka =2;
integer dylan =3;
integer npc1 =4;
integer npc2 =5;
integer npc3 =6;
integer npc4 =7;
integer npc5 =8;
integer npc6 =9; // MaryAnne
// GLOBALS
integer busy ;
key NamakaKey;
key DylanKey ;
// npc counters
integer FIRST = 0;
integer LAST = 6;
integer currNpcNum;
// FUNCTIONS
DEBUG(string msg)
{
if (debug ==1 || debug ==3)
llOwnerSay(llGetScriptName() + ":" + msg);
if (debug ==2 || debug ==3) {
llSetText(msg, <1,0,0>,1.0);
llSleep(0.25);
}
}
string NpcSayInstructions()
{
if (counter1 ++ >= llGetListLength(Instructions))
counter1 = 0;
return llList2String(Instructions,counter1);
}
string NpcSayTooFar()
{
if (counter++ >= llGetListLength(FarAway))
counter = 0;
return llList2String(FarAway,counter);
}
Command(integer Npc,string msg)
{
//DEBUG("Command:" +(string) Npc +":" + msg);
llMessageLinked(Npc,0,msg,"");
}
ChangeNpcToDemon(integer npc)
{
DEBUG("Change to demon " + (string) npc);
llMessageLinked(npc,100,"BOOM",""); // tell the effect to play
llMessageLinked(LINK_SET,200,"BANG",""); // tell the spiral effect to play
Command(npc,"@notecard=!Changed");
}
Win()
{
DEBUG("Win");
llRegionSay(gFireworksChannel,"Go");
STATE=1;
DEBUG("FIREWORKS");
llSetTimerEvent(1);
}
InitAllNpc()
{
DEBUG("Init all Npc");
currNpcNum = FIRST;
llMessageLinked(LINK_SET,99,"reset","");
busy = FALSE;
STATE = 0;
avatars = [0,0,0,0,1,1,1,1,1,1]; // 0 is skipped, 1 = root, 2 - namaka
llShout(CommandChannel,"0006");
BUSY = FALSE;
}
default
{
state_entry()
{
DEBUG("Reset");
busy = FALSE;
llSetText("",<1,1,1>,1.0);
InitAllNpc();
}
timer()
{
llShout(CommandChannel,(string) (180 - STATE));
llSetTimerEvent(1);
if (STATE == 15 || STATE== 20 || STATE == 25) {
llRegionSay(gFireworksChannel,"Go");
}
if (STATE==30)
{
Command(namaka,"@notecard=dragon");
Command(dylan,"@notecard=dragon");
}
if (STATE == 180)
{
InitAllNpc();
llSetTimerEvent(0);
}
STATE++;
}
link_message(integer sender_number, integer number, string message, key id)
{
if (BUSY)
return;
// DEBUG("Num:" + (string) number + " str:" + message);
// --10 is the link num and pos of the dancer
// -2 is dylans key
// -1 is Namakas key
// 4 is for NPC direction commands
// 1 is for doorway
// 2 is the helmet beam channel
if (number == -10) {
list x = llParseString2List(message,["|"],[]);
integer linknum = (integer) llList2String( x,0);
vector v = (vector) llList2String( x,1);
avatarDancePos = llListReplaceList(avatarDancePos,[v],linknum,linknum);
//DEBUG("Npc Count = " + (string) llGetListLength(avatarDancePos));
}
else if (number == -2){ // -2 is Dylans key fromt the modified NPC controller script
DylanKey = id;
//DEBUG("Dylan Key set to " + (string) id);
} else if (number == -1){ // -1 is Namakas key
NamakaKey = id;
//DEBUG("Namaka Key set to " + (string) id);
} else if (number == 4){ // 4 is for NPC direction commands
llMessageLinked(LINK_SET,0," ",""); // stimulate back a NPC key message
vector direction = (vector) message;
direction *= 2.5;
DEBUG((string) direction);
llTriggerSound(click,1.0);
//DEBUG("Key: " + (string) NamakaKey);
list stuff = llGetObjectDetails(NamakaKey, [OBJECT_POS]);
vector namakaPos = llList2Vector(stuff,0);
//vector namakaPos = osNpcGetPos(NamakaKey);
// DEBUG("NPC at " + (string) namakaPos);
vector newNpcPos = namakaPos;
newNpcPos.z = 0;
centerPoint.z = 0;
//DEBUG("Roam dist:" + (string) llVecDist(newNpcPos, centerPoint));
llTriggerSound(footsteps,1.0);
// Move the npc some direction
if (llVecDist(newNpcPos, centerPoint) > MAXDIST) {
DEBUG("Went too far");
llTriggerSound(errorbeep,1.0);
string toSay = NpcSayTooFar();
Command(dylan,"@animate=avatar_type|3");
Command(dylan,"@say=" + toSay);
// string newPos2 = (string) (namakaPos + (direction *-2));
// DEBUG("Reversing to @walk=" + newPos2);
Command(namaka,"@teleport=<207, 126, 41>" );
Command(dylan,"@teleport=<198.4, 130, 41.5>" );
return;
}
string newPos = (string) (namakaPos + direction + <0,0,0.2>);
//DEBUG("Moving to @walk=" + newPos);
Command(namaka,"@walk=" + newPos);
} else if (number == 1) { // 1 is for doorway
if (busy) {
DEBUG("Busy");
return;
}
InitAllNpc();
busy++;
} else if (number == 2){ // 2 is the helmet beam channel
DEBUG(llDumpList2String(avatars,":"));
llTriggerSound(effect,1.0);
llMessageLinked(LINK_SET,0," ",""); // stimulate back a NPC key message
LASTDIST = 99;
integer i;
integer j = llGetListLength(avatarDancePos);
for (i = 0; i < j; i++)
{
if (llList2Integer(avatars,i) != 0)
{
//DEBUG("I:" + (string) i);
// get Namakas position and compare it to all the npcs
vector npcPos = llList2Vector(avatarDancePos,i);
npcPos.z = 0;
list stuff = llGetObjectDetails(NamakaKey, [OBJECT_POS]);
vector namakaPos = llList2Vector(stuff,0);
if (namakaPos == ZERO_VECTOR)
{
DEBUG("Oops");
return;
}
namakaPos.z = 0;
//DEBUG("namakaPos:" + (string) namakaPos);
//DEBUG("npcPos:" + (string) npcPos);
float dist = llVecDist(npcPos,namakaPos);
//DEBUG("dist:" + (string) dist);
if (dist < LASTDIST)
{
LASTDIST = dist;
}
if (dist < MaxBeam)
{
llSetText("Distance\n" + (string) dist,<0,1,0>,1.0);
Command(dylan,"@say=Something is happening!" );
ChangeNpcToDemon(i); //1 = root, 2 = namake, 3 = dylan
avatars= llListReplaceList(avatars,[0],i,i);
integer k;
integer l = llGetListLength(avatars);
integer count;
for (k=0; k < l; k++)
{
count += llList2Integer(avatars,k);
}
DEBUG("count:" + (string) count);
llShout(CommandChannel,(string) count);
if (count <2) {
llTriggerSound(sex,1.0);
Win();
BUSY++;
return;
}
llTriggerSound(effect,1.0);
return;
}
}
}
llSetText("Distance\n" + (string) LASTDIST,<0,1,0>,1.0);
string toSay2 = NpcSayInstructions();
Command(dylan,"@animate=avatar_type|3");
Command(dylan,"@say=" + toSay2);
integer d = (integer) LASTDIST;
Command(dylan,"@say=The closest dancer is about " + d + " meters away from her");
}
}
}

View File

@@ -0,0 +1,44 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:NPC, controller, console
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1839
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// NPC console controller button script
// Goes into 8 buttons in a compass rose configuration
// Controls a pair of NPCS to xap 6 othert NPCs.
// each button gets a different config.
// :CODE:
string E = "<1,0,0>";
string NE = "<1,1,>";
string N = "<0,1,0>";
string NW = "<-1,1,0>";
string W = "<-1,0,0>";
string SW = "<-1,-1,0>";
string S = "<0,-1,0>";
string SE = "<1,-1,0>";
// chose a direction for one of 8 buttons.
default
{
touch_start(integer total_number)
{
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_FULLBRIGHT, ALL_SIDES,TRUE]);
llMessageLinked(LINK_SET,4,S,"");
llSetTimerEvent(0.5);
}
timer()
{
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_FULLBRIGHT,ALL_SIDES, FALSE]);
llSetTimerEvent(0);
}
}

View File

@@ -0,0 +1,43 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1840
// :REV:2.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Triggers the NPC controller to play a notecard when collided.
// :CODE:
string message = "@notecard=!Path";
Reset() {
llSetStatus(STATUS_PHANTOM, FALSE); // rev 2.0
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default{
state_entry(){
Reset();
}
collision_start(integer n){
if (osIsNpc(llDetectedKey(0))){
return;
}
llMessageLinked(LINK_SET,1,message,""); // 1 ios for doorway only
}
on_rez(integer p){
llResetScript();
}
changed(integer what){
if (what & CHANGED_REGION_START){
llResetScript();
}
}
}

View File

@@ -0,0 +1,32 @@
// :SHOW:
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1841
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// Button Script for console
// :CODE:
// The Go button at the center
default
{
touch_start(integer total_number)
{
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_FULLBRIGHT, ALL_SIDES,TRUE]);
llMessageLinked(LINK_SET,2,"Red","");
llSetTimerEvent(0.5);
}
timer()
{
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_FULLBRIGHT,ALL_SIDES, FALSE]);
llSetTimerEvent(0);
}
}

View File

@@ -0,0 +1,90 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:NPC, controller, cyber helmet
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1842
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// NPC helmet controller
// Accepts a single chatted command to msake the cyber being helmet flash for a second or two.
// worn by the NPC
// :CODE:
// TUNABLES
integer debug = 1;
// GLOBALS
integer counter = 0;
// FUNCTIONS
DEBUG(string msg)
{
if (debug & 1)
llSay(0,llGetScriptName() + ":" + msg);
if (debug & 2)
llSetText(msg, <1,0,0>,1.0);
}
Go()
{
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,.2, PRIM_SIZE, <0.5,0.5,2>,PRIM_COLOR,ALL_SIDES,<1,1,1>,0.5 ]);
llSetTimerEvent(2);
}
default
{
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
state_entry()
{
llSetText("", <1,0,0>,1.0);
llListenRemove(listener);
llSetTextureAnim(ANIM_ON | SMOOTH | LOOP , ALL_SIDES, 1, 1, 1.0, 1.0, 1.0);
}
link_message(integer total_number, integer Num, string text, key id)
{
if ( text =="BANG")
Go();
}
timer()
{
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0.2, PRIM_SIZE, <0.5,0.5,2> ] );
llSleep(0.25);
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0.2, PRIM_SIZE, <0.4,0.4,2> ] );
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0, PRIM_SIZE, <0.2,0.2,2> ] );
llSleep(0.25);
llSetLinkPrimitiveParamsFast(llGetLinkNumber(),[PRIM_GLOW,ALL_SIDES,0, PRIM_SIZE, <0.1,0.1,2>,PRIM_COLOR,ALL_SIDES,<1,1,1>,0 ] );
llSetTimerEvent(0);
}
}

View File

@@ -0,0 +1,116 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Ferd Frederix
// :KEYWORDS:NPC, controller, cyber helmet
// :CREATED:2015-11-24 20:25:33
// :EDITED:2015-11-24 19:25:33
// :ID:1087
// :NUM:1843
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// NPC helmet controller
// Accepts a single chatted command to msake the cyber being helmet flash for a second or two.
// rezzed in world and not worn
// :CODE:
// TUNABLES
integer debug = 0;
// GLOBALS
integer counter = 0;
integer listener;
// FUNCTIONS
DEBUG(string msg)
{
if (debug & 1)
llSay(0,llGetScriptName() + ":" + msg);
if (debug & 2)
llSetText(msg, <1,0,0>,1.0);
}
NpcSaySomething(){
list sayings = ["The helmet begins to glow","A beam of light appears","The helmet begins to hum","The cyberbeing helmet is activated", "bzzz", "Zap","KaPow!"];
key NpcKey = llGetOwner();
DEBUG("Owner Key = " + (string) NpcKey);
llSay(0, llList2String(sayings,counter++));
if (counter > llGetListLength(sayings)) {
counter = 0;
}
}
Go()
{
NpcSaySomething();
llSetLinkPrimitiveParamsFast(0,[PRIM_GLOW,ALL_SIDES,.2, PRIM_SIZE, <2,2,2>,PRIM_COLOR,ALL_SIDES,<1,1,1>,0.5 ]);
llSetTimerEvent(2);
}
integer Helmet_Channel = 576;
default
{
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
state_entry()
{
llSetText("", <1,0,0>,1.0);
llListenRemove(listener);
listener= llListen(Helmet_Channel, "","","BOOM"); // listen for boom command
llSetTextureAnim(ANIM_ON | SMOOTH | LOOP , ALL_SIDES, 1, 1, 1.0, 1.0, 1.0);
llSensorRepeat("Namaka ♥", NULL_KEY, AGENT, 25.0, PI,5);
}
listen(integer channel, string name, key id, string msg)
{
Go();
}
touch_start(integer total_number)
{
Go();
}
sensor(integer n)
{
llSetRegionPos(llDetectedPos(0) + <0,0,1>);
}
no_sensor()
{
llSetRegionPos(<200, 128, 48>); // sop we can find this blasted thing
}
timer()
{
llSetLinkPrimitiveParamsFast(0,[PRIM_GLOW,ALL_SIDES,0.2, PRIM_SIZE, <1.5,1.5,1> ] );
llSleep(0.25);
llSetLinkPrimitiveParamsFast(0,[PRIM_GLOW,ALL_SIDES,0.2, PRIM_SIZE, <1.2,1.2,1> ] );
llSetLinkPrimitiveParamsFast(0,[PRIM_GLOW,ALL_SIDES,0, PRIM_SIZE, <1,1,1> ] );
llSleep(0.25);
llSetLinkPrimitiveParamsFast(0,[PRIM_GLOW,ALL_SIDES,0, PRIM_SIZE, <1,1,1>,PRIM_COLOR,ALL_SIDES,<1,1,1>,0 ] );
llSetTimerEvent(0);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
<Project name="Nine" guid="6ea39920-3832-4f36-89e9-7f366d7af710">
<Object name="Collider" guid="dfdcdbf3-fd7d-461e-937e-43b91ec487a5" active="true">
<Script name="Collider.lsl" guid="caee2bdc-f277-4ea1-902e-dcca67edfa54">
</Script>
</Object>
<Object name="Dancer Ball" guid="1b551ab0-ee50-4f3f-b5e4-b990a888f8ed">
<Script name="NPC 9.3.lsl" guid="625f3fa2-d5b7-485f-82de-71dfd8925dca">
</Script>
<Script name="Effect.lsl" guid="701f0a90-4723-4478-9783-b33dbd466325">
</Script>
</Object>
<Object name="Dylan" guid="2e49a070-13d7-4714-943f-a6432ebde059">
<Script name="NPC Custom for Dylan.lsl" guid="5a78854a-91cf-45cc-a873-202e1f4ba667">
</Script>
</Object>
<Object name="Event Horizon Controller" guid="13053ade-18dc-434c-8282-284f9c6a482a">
<Sound name="back-in-time.wav" guid="f06411a4-5b8c-4bb3-bf3e-9bbb5df3e9d7">
</Sound>
<Sound name="coins_bag_2_3.wav" guid="57721f3a-a654-4f0a-b462-9566a8307cac">
</Sound>
<Script name="Controller.lsl" guid="13b713c7-c975-472c-99a9-16dac5b92289">
</Script>
<Script name="Direction button.lsl" guid="684d2e2b-9f86-4dd4-91cd-c3de7c26af81">
</Script>
<Script name="Doorway.lsl" guid="4b7c8656-fdbc-42d9-9e56-52b366baaf48">
</Script>
<Sound name="footstepmuffled.wav" guid="96c5413c-8924-45cf-8b00-9319d7429c8b">
</Sound>
<Script name="Go.lsl" guid="9d5c5537-7954-408a-99e7-7c95d8a3efca">
</Script>
<Sound name="magic-string-spell-2.wav" guid="bab747f5-97b6-4770-9c4d-3e916c22c53d">
</Sound>
<Script name="Light effect Bar.lsl" guid="24dc96ee-bfd3-42ed-a60a-4da3b8a0d365">
</Script>
</Object>
<Object name="Helmet" guid="0e621c2d-d0ef-433a-9749-d3f8affe8658">
<Script name="Script.lsl" guid="a098c895-5b17-4db0-9396-c94d48bf919c">
</Script>
</Object>
<Object name="Namaka" guid="5cfb272d-7cd7-4b01-9707-91f6bf8cc774">
<Script name="NPC Custom for Namaka.lsl" guid="40a5b685-f067-45b4-bb67-df76a0b8cf3c">
</Script>
</Object>
<Object name="Timer" guid="8ff01a27-18ad-46f0-b856-6520a1d4a565">
<Script name="Shins Script.lsl" guid="3c84f143-8bc6-40c0-8d88-1bc16b182e51">
</Script>
<Script name="Timer.lsl" guid="507c6de9-e77c-456d-98c8-f088641071e0">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,280 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Shin Ingen
// :KEYWORDS:NPC, controller and timer
// :CREATED:2015-11-24 20:25:34
// :EDITED:2015-11-24 19:25:34
// :ID:1087
// :NUM:1845
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Timer script - ended up not being used.
// :CODE:
//HYPERGRID STORY NINE
// List NPC Listener channels
//sara=11 sammy=12 claire=13 jolinda=14 tiny=15 tiny2=16 fireworks=20
integer gListener; // Listener for handling different channels
integer gSimpleMenuChannel; // The channel used for the menu
float gTimerInterval = 1; // Keep this at 1 for your sanity.
list gTimeoutList;
float gTimeElapsed=0;
integer gAutofire=FALSE;
//============================================================================
vector gFacecolor=<1.0,0.0,0.0>; //RED
integer gNewTime;
integer gOldTime;
//==Function that returns a random number for our menu handler channel
integer randomchannel() {
return((integer)(llFrand(99999.0)*-1));
}
menu(key id, integer channel, string title, list buttons) {
llListenRemove(gListener);
gListener = llListen(channel,"",id,"");
llDialog(id,title,buttons,channel);
// TimerEvent for killing the menu listener
settimeout("untouched", 30); //call untouched timeout
}
simplemenu(key id) {
gSimpleMenuChannel = randomchannel();
menu(id,gSimpleMenuChannel,"Select an option",["FIREWORKS","SARA","SAMMY","CLAIRE","JOLINDA","TINY","TINY2","LeadNPC","Finale!","CeaseFire"]);
}
settimeout(string timereventid, float time) {
if(gTimeoutList == [])
llSetTimerEvent(gTimerInterval);
integer identifyerIndex = llListFindList(gTimeoutList, [timereventid]);
if (identifyerIndex != -1)
gTimeoutList = llDeleteSubList(gTimeoutList, identifyerIndex - 1, identifyerIndex);
if (time != 0) {
gTimeoutList += time + gTimeElapsed;
gTimeoutList += timereventid;
}
gTimeoutList = llListSort(gTimeoutList, 2, TRUE);
}
timeout(string timereventid)
{
if (timereventid == "untouched")
{
llSay(0, "I have been untouched for 30 seconds, killing menu listener!");
llListenRemove(gListener); // kill the listener after 30 seconds inactivity
}
else if (timereventid == "countdown2execute")
{
float seconds2count = 1800;
llSay(0, "I have counted down " + (string)seconds2count + " seconds, repeat countdown and start the show");
settimeout("countdown2execute", seconds2count); //call it again to loop.
}
else if (timereventid == "autofire")
{
if(gAutofire)
{
llSay(0,"should fire every 5 seconds.");
llRegionSay(20,"Go");
settimeout("autofire", 5);
}
}
if (timereventid == "stopautofire")
{
gAutofire=FALSE;
}
}
timertick()
{
gTimeElapsed += gTimerInterval;
integer i;
integer numTimers = llGetListLength(gTimeoutList);
for (i = 0; i < numTimers; i += 2)
{
float triggerTime = llList2Float(gTimeoutList, i);
if (triggerTime <= gTimeElapsed)
{
string timereventid = llList2String(gTimeoutList, i + 1);
gTimeoutList = llDeleteSubList(gTimeoutList, i, i + 1);
timeout(timereventid);
if (timereventid=="countdown2execute")
{
displaycountdowntext((integer)gTimeElapsed);
getdigit((integer)gTimeElapsed);
}
if (gTimeoutList == [])
llSetTimerEvent(0);
}
else
{
return;
}
}
}
displaydigit(integer n, string d){
list Facelist; //list depends on your mesh digital readout face number.
integer i;
if(n==0) Facelist=[ 1,1,1,1,0,1,1 ]; //index @0 | 7 faces per digit
if(n==1) Facelist=[ 0,0,1,0,0,1,0 ];
if(n==2) Facelist=[ 1,1,0,1,1,1,0 ];
if(n==3) Facelist=[ 1,1,1,0,1,1,0 ];
if(n==4) Facelist=[ 0,0,1,0,1,1,1 ];
if(n==5) Facelist=[ 1,1,1,0,1,0,1 ];
if(n==6) Facelist=[ 0,1,1,1,1,0,1 ];
if(n==7) Facelist=[ 1,0,1,0,0,1,0 ];
if(n==8) Facelist=[ 1,1,1,1,1,1,1 ];
if(n==9) Facelist=[ 1,0,1,0,1,1,1 ];
integer l = llGetLinkNumber() != 0;
integer x = llGetNumberOfPrims() + l;
for (; l < x; ++l){
if (llGetLinkName(l) == d){
for (i=0;i<7;i++){
llSetLinkPrimitiveParamsFast(l,[PRIM_COLOR,i,gFacecolor,llList2Float(Facelist,i)]);
}
}
}
}
getdigit(integer time){
string dOne;
string dTen;
string dHundred;
string dThousand;
integer i;
if (time<10){
dOne=(string)time;
dTen="0";
dHundred="0";
dThousand="0"; // add your digits here
}else if(time<100){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,0,0);
dHundred="0";
dThousand="0";
}else if(time<1000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,1,1);
dHundred=llGetSubString((string)time,0,0);
dThousand="0";
}else if(time<10000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,2,2);
dHundred=llGetSubString((string)time,1,1);
dThousand=llGetSubString((string)time,0,0);
}
displaydigit((integer)dOne, "one");
displaydigit((integer)dTen, "ten");
displaydigit((integer)dHundred, "hundred");
displaydigit((integer)dThousand, "thousand");
}
displaycountdowntext(integer time){
gNewTime = time;
if (gOldTime < gNewTime){
llSetText("Elapsed Ticker: " + (string)gNewTime + " ticks",<1,1,.6>,1.0);
gOldTime = gNewTime;
}
}
default
{
state_entry()
{
float seconds2count = 3600;
settimeout("countdown2execute", seconds2count);
}
touch_start(integer num)
{
simplemenu(llDetectedKey(0));
}
listen (integer channel, string name, key id, string message)
{
if (message == "FIREWORKS") {
llSay(0,"You selected option FIREWORKS");
llRegionSay(20,"Go");
//do something else here
}
else if (message == "SARA")
{
llSay(0,"You selected option SARA");
llRegionSay(11,"@go");
//do something else here
}
else if (message == "SAMMY")
{
llSay(0,"You selected option SAMMY");
llRegionSay(12,"@go");
//do something else here
}
else if (message == "CLAIRE")
{
llSay(0,"You selected option CLAIRE");
llRegionSay(13,"@go");
//do something else here
}
else if (message == "JOLINDA")
{
llSay(0,"You selected option JOLINDA");
llRegionSay(14,"@go");
//do something else here
}
else if (message == "TINY")
{
llSay(0,"You selected option TINY");
llRegionSay(15,"@go");
//do something else here
}
else if (message == "TINY2")
{
llSay(0,"You selected option TINY2");
llRegionSay(16,"@go");
//do something else here
}
else if (message == "LeadNPC")
{
llSay(0,"You selected option LeadNPC");
llRegionSay(10,"@go");
//do something else here
}
else if (message == "Finale!")
{
llSay(0,"You selected option Finale!");
gAutofire=TRUE;
settimeout("autofire", 1);
settimeout("stopautofire", 90);
//do something else here
}
else if (message == "CeaseFire")
{
llSay(0,"You selected option CeaseFire");
gAutofire=FALSE;
//do something else here
}
simplemenu(id); // refresh menu
}
timer()
{
timertick();
integer MaxTicks = 1800; //Ticks to countdown from
//limit the ticker to maximum ticks
if(gTimeElapsed >= MaxTicks){
gTimeElapsed=0;
}
integer CountDown = MaxTicks - (integer)gTimeElapsed;
integer mm = (CountDown / 60) * 100;
integer ss = (CountDown % 60);
integer cc = mm + ss;
displaycountdowntext((integer)gTimeElapsed);
getdigit((integer)cc);
}
}

View File

@@ -0,0 +1,402 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:HyperGrid Story Nine
// :AUTHOR:Shin Ingen
// :KEYWORDS:NPC, controller and timer
// :CREATED:2015-11-24 20:25:34
// :EDITED:2015-11-24 19:25:34
// :ID:1087
// :NUM:1846
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Timer script - ended up not being used.
// :CODE:
integer debug = 2;
// Link Numbers of the NPC controller
integer namaka =2;
integer dylan =3;
integer npc1 =4;
integer npc2 =5;
integer npc3 =6;
integer npc4 =7;
integer npc5 =8;
integer npc6 =9;
// List of NPC Listener channels
integer gFireworksChannel =20;
integer gTeleportChannel = 21;
integer CommandChannel = 23;
integer gSimpleMenuChannel = 999; // The channel used for the menu
integer MaxTicks = 60; // Show length
// The repeat the show timer
list kDance1 = ["Dance1",1]; // Dance
list kDance2 = ["Dance2",10]; // Dance
list kDance3 = ["Dance3",20]; // Dance
list kDance4 = ["Dance4",30]; // Dance
list kDance5 = ["Dance5",40]; // Dance
list kDance6 = ["Dance6",50]; // Dance
list kFireworksRepRate = ["Shoot", 2]; // rep rate for finale
// the following are calculated based on the current timer tick
list kFireworksStartsAt = ["StartFireworks", 99999]; // rep rate for finale
list kRaiseTeleport = ["BeamMeUp",99999]; // raise the teleports
list kStopAutoFire = ["EndFireworks",99999]; // and stops here
SendMessageLinked(integer npc, string cmd)
{
llRegionSay(CommandChannel,(string) npc + "|" + cmd);
}
DoCmd(string message, integer channel)
{
if (channel == CommandChannel) {
Process(message);
}
if (message == "ShowTime") {
DEBUG("Running");
ShowTime();
}
else if (message == "Finale!")
{
kFireworksStartsAt = ["StartFireworks", gTimeElapsed+1]; // rep rate for finale
kRaiseTeleport = ["BeamMeUp",gTimeElapsed+25]; // raise the teleports
kStopAutoFire = ["EndFireworks",gTimeElapsed+30]; // and stops here
settimeout(kFireworksStartsAt);
settimeout(kStopAutoFire);
settimeout(kRaiseTeleport);
}
else if (message == "Stop")
{
llSay(0,"You selected option Stop");
gTimeoutList = [];
}
}
// this is a list of all the cycling show bits
ShowTime()
{
DEBUG("Starting Countdown");
gTimeElapsed=0;
settimeout(kDance1);
settimeout(kDance2);
settimeout(kDance3);
settimeout(kDance4);
settimeout(kDance5);
settimeout(kDance6);
DEBUG(llDumpList2String(gTimeoutList,":"));
}
Process(string timereventid) {
if (llList2String(kDance1,0) == timereventid)
{
DEBUG("Dance1");
;
SendMessageLinked(dylan,"@appearance=Dylan");
SendMessageLinked(namaka,"@appearance=Namaka");
SendMessageLinked(npc1,"@appearance=Crispen Enpeacee");
SendMessageLinked(npc2,"@appearance=Alessandra Enpeacee");
SendMessageLinked(npc3,"@appearance=Sammy Enpeacee");
SendMessageLinked(npc4,"@appearance=Jolinda Enpeacee");
SendMessageLinked(npc5,"@appearance=Claire Enpeacee");
SendMessageLinked(npc6,"@appearance=Marianne Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance1");
}
else if (llList2String(kDance2,0) == timereventid)
{
DEBUG("Dance2");
SendMessageLinked(LINK_SET,"@appearance=Alessandra Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance2");
}
else if (llList2String(kDance3,0) == timereventid)
{
DEBUG("Dance3");
SendMessageLinked(LINK_SET,"@appearance=Sammy Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance3");
}
else if (llList2String(kDance4,0)== timereventid)
{
DEBUG("Dance4");
SendMessageLinked(LINK_SET,"@appearance=Jolinda Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance4");
}
else if (llList2String(kDance5,0)== timereventid)
{
DEBUG("Dance5");
SendMessageLinked(LINK_SET,"@appearance=Claire Enpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance5");
}
else if (llList2String(kDance6,0)== timereventid)
{
DEBUG("Dance6");
SendMessageLinked(LINK_SET,"@appearance=MarianneEnpeacee");
SendMessageLinked(LINK_SET,"@notecard=Dance6");
}
else if (llList2String(kFireworksStartsAt,0) == timereventid)
{
DEBUG("Shoot!");
SendMessageLinked(LINK_SET,"@appearance=Dragon");
SendMessageLinked(LINK_SET,"@notecard=Fireworks");
llRegionSay(gFireworksChannel,"Go");
settimeout(kFireworksRepRate);
}
else if (llList2String(kFireworksRepRate,0) == timereventid)
{
DEBUG("Fireworks Start");
llRegionSay(gFireworksChannel,"Go");
SendMessageLinked(npc1,"@appearance=Crispen Enpeacee");
SendMessageLinked(npc2,"@appearance=Alessandra Enpeacee");
SendMessageLinked(npc3,"@appearance=Sammy Enpeacee");
SendMessageLinked(npc4,"@appearance=Jolinda Enpeacee");
SendMessageLinked(npc5,"@appearance=Claire Enpeacee");
SendMessageLinked(npc6,"@appearance=Marianne Enpeacee");
SendMessageLinked(dylan,"@appearance=Dylan");
SendMessageLinked(namaka,"@appearance=Namaka");
SendMessageLinked(LINK_SET,"@notecard=Final");
settimeout(kFireworksRepRate);
}
else if (llList2String(kStopAutoFire,0) == timereventid)
{
DEBUG("Fireworks End");
deletetimeout(kFireworksRepRate);
settimeout(kRaiseTeleport);
}
else if (llList2String(kRaiseTeleport,0) == timereventid)
{
SendMessageLinked(LINK_SET,"@notecard=Teleport");
DEBUG("Teleports Up");
llRegionSay(gTeleportChannel,"Up");
}
}
integer busy;
integer gListener; // Listener for handling different channels
list gTimeoutList;
float gTimeElapsed=0;
//============================================================================
vector gFacecolor=<1.0,0.0,0.0>; //RED
DEBUG(string msg)
{
if (debug ==1)
llSay(0,llGetScriptName() + ":" + msg);
if (debug ==2)
llSetText(msg, <1,0,0>,1.0);
}
menu(key id, integer channel, string title, list buttons) {
llListenRemove(gListener);
gListener = llListen(channel,"",id,"");
llDialog(id,title,buttons,channel);
}
simplemenu(key id) {
menu(id,gSimpleMenuChannel,"Select an option",["ShowTime","Finale","Stop"]);
}
deletetimeout(list events) {
string timereventid = llList2String(events,0);
DEBUG("Deleteing timer event " + timereventid);
integer identifyerIndex = llListFindList(gTimeoutList, [timereventid]);
if (identifyerIndex != -1)
gTimeoutList = llDeleteSubList(gTimeoutList, identifyerIndex - 1, identifyerIndex);
}
settimeout(list events)
{
// unpack the list
string timereventid = llList2String(events,0);
integer time = llList2Integer(events,1);
DEBUG("Adding " + timereventid);
integer identifyerIndex = llListFindList(gTimeoutList, [timereventid]);
if (identifyerIndex != -1)
gTimeoutList = llDeleteSubList(gTimeoutList, identifyerIndex - 1, identifyerIndex);
if (time != 0) {
gTimeoutList += time;
gTimeoutList += timereventid;
}
llSetTimerEvent(1.0);
}
timertick() {
gTimeElapsed ++;
//DEBUG((string) gTimeElapsed );
integer i;
integer numTimers = llGetListLength(gTimeoutList);
//DEBUG((string) (numTimers/2) + " timers");
// scan over all queued timers
for (i = 0; i < numTimers; i += 2)
{
integer triggerTime = llList2Integer(gTimeoutList, i);
//DEBUG("TriggerTime = " + (string)triggerTime);
if (triggerTime == gTimeElapsed) {
string timereventid = llList2String(gTimeoutList, i + 1);
//DEBUG("matched " + timereventid);
gTimeoutList = llDeleteSubList(gTimeoutList, i, i + 1); // they are one-shots, so delete the event that just happened.
Process(timereventid); // process the callback
if (gTimeoutList == []) {
DEBUG("Show over! Starting back up");
ShowTime();
}
}
}
}
displaydigit(integer n, string d){
list Facelist; //list depends on your mesh digital readout face number.
integer i;
if(n==0) Facelist=[ 1,1,1,1,0,1,1 ]; //index @0 | 7 faces per digit
if(n==1) Facelist=[ 0,0,1,0,0,1,0 ];
if(n==2) Facelist=[ 1,1,0,1,1,1,0 ];
if(n==3) Facelist=[ 1,1,1,0,1,1,0 ];
if(n==4) Facelist=[ 0,0,1,0,1,1,1 ];
if(n==5) Facelist=[ 1,1,1,0,1,0,1 ];
if(n==6) Facelist=[ 0,1,1,1,1,0,1 ];
if(n==7) Facelist=[ 1,0,1,0,0,1,0 ];
if(n==8) Facelist=[ 1,1,1,1,1,1,1 ];
if(n==9) Facelist=[ 1,0,1,0,1,1,1 ];
integer l = llGetLinkNumber() != 0;
integer x = llGetNumberOfPrims() + l;
for (; l < x; ++l){
if (llGetLinkName(l) == d){
for (i=0;i<7;i++){
llSetLinkPrimitiveParamsFast(l,[PRIM_COLOR,i,gFacecolor,llList2Float(Facelist,i)]);
}
}
}
}
getdigit(integer time){
string dOne;
string dTen;
string dHundred;
string dThousand;
if (time<10){
dOne=(string)time;
dTen="0";
dHundred="0";
dThousand="0"; // add your digits here
}else if(time<100){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,0,0);
dHundred="0";
dThousand="0";
}else if(time<1000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,1,1);
dHundred=llGetSubString((string)time,0,0);
dThousand="0";
}else if(time<10000){
dOne=llGetSubString((string)time,-1,-1);
dTen=llGetSubString((string)time,2,2);
dHundred=llGetSubString((string)time,1,1);
dThousand=llGetSubString((string)time,0,0);
}
displaydigit((integer)dOne, "one");
displaydigit((integer)dTen, "ten");
displaydigit((integer)dHundred, "hundred");
displaydigit((integer)dThousand, "thousand");
//DEBUG(dThousand + dHundred + ":" + dTen + dOne);
}
StopAll()
{
DEBUG("Stopped");
llSetTimerEvent(0);
}
default
{
state_entry()
{
llListen(CommandChannel,"","","");
getdigit(0);
}
touch_start(integer num)
{
if ( llGetOwner() == llDetectedKey(0)) {
if (! busy) {
simplemenu(llDetectedKey(0));
busy++;
} else {
busy = FALSE;
StopAll();
}
}
}
link_message(integer sender_number, integer number, string message, key id)
{
DEBUG("LINK MESSAGE\n" + message);
DoCmd(message, number);
}
listen (integer channel, string name, key id, string message)
{
// !!! add parser for killing the NPC
DEBUG("LISTEN\n" + message);
DoCmd(message, channel);
}
timer()
{
timertick();
//limit the ticker to maximum ticks
if(gTimeElapsed >= MaxTicks){
gTimeElapsed=0;
}
integer CountDown = MaxTicks - (integer)gTimeElapsed;
integer mm = (CountDown / 60) * 100;
integer ss = (CountDown % 60);
integer cc = mm + ss;
getdigit((integer)cc);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 MiB

View File

@@ -0,0 +1,3 @@
<Solution name="HyperGrid Story One">
<Project name="HyperGrid Story One" path="HyperGrid Story One\HyperGrid Story One.prj" active="true"/>
</Solution>

View File

@@ -0,0 +1,14 @@
<Project name="HyperGrid Story One" guid="38ccddb1-2f3d-4bfb-845c-27bb53d8d9c1">
<Object name="Object" guid="e60a43cc-2f18-4711-830e-621d6370682b" active="true">
<Notecard name="!Story" guid="45a5c0b0-46e9-4189-beed-f49c8e742db8">
</Notecard>
<Notecard name="Dylan" guid="34af076a-751a-4725-88b3-b9e464755fbd">
</Notecard>
<Notecard name="Namaka" guid="c5ba88e6-e7b9-4e55-9a4c-7f5f5084d8bf">
</Notecard>
<Notecard name="NPC00A Ruth Enpeace" guid="3794e81c-503b-43b7-8ee0-2d36ac2d34f3">
</Notecard>
<Script name="Sequencer.lsl" guid="ac603208-fa45-4a6b-a95e-ca944714f0b9">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,23 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story One
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1089
// :NUM:1852
// :REV:3.0
// :WORLD:Opensim
// :DESCRIPTION:
// Sample NPC Card
// :CODE:
1,1,"@spawn=Namaka ♥|<127, 126, 23>|Namaka"
2,1,"@spawn=Dylan ♥|<127, 129, 23>|Dylan"
1,1,"@sit=dancerock"
2,2,"@sit=dancerock"
1,1,"@say=Hi, I am Namaka"
2,5,"@say=I am Dylan!... and now we leave"
1,1,"@delete"
2,1,"@delete"

View File

@@ -0,0 +1,145 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story One
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1089
// :NUM:1853
// :REV:3.0
// :WORLD:Opensim
// :DESCRIPTION:
// Sample NPC Card
// :CODE:
<llsd>
<map>
<key>serial</key>
<integer>0</integer>
<key>height</key>
<real>1.6691286563873291</real>
<key>wearables</key>
<array>
<array>
<map>
<key>item</key>
<uuid>0d67c6b9-90a6-4430-b124-5d3865253563</uuid>
<key>asset</key>
<uuid>501d4ff3-7669-4f2b-3de8-6077183b4314</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>3d56f323-beb2-4a4f-9b33-bedd01ef6d87</uuid>
<key>asset</key>
<uuid>9aa403be-7096-d638-d7b5-ab2739926664</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>3cc100b5-efb9-4357-84de-d53c763a9fe1</uuid>
<key>asset</key>
<uuid>9fe42dc9-32b9-863b-bbe3-2ed225aaa4dc</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>657b06b0-ec8b-4f13-8fcc-8cab56e76145</uuid>
<key>asset</key>
<uuid>2ba00144-a1c5-4c60-b70b-54f888d57104</uuid>
</map>
</array>
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array>
<map>
<key>item</key>
<uuid>f0d962ee-8899-4853-b643-5f1e8414f386</uuid>
<key>asset</key>
<uuid>9942fa1d-a7e6-0dee-2345-9b2449a137fb</uuid>
</map>
</array>
<array />
</array>
<key>textures</key>
<array>
<uuid>46697265-7374-6f72-6d00-000000000000</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>837d151d-b151-4f28-bd64-d64315dcd787</uuid>
<uuid>b74b9a80-b354-4a55-9a11-b04ddf9ad824</uuid>
<uuid>8e200c7a-6b01-43df-9196-1f9ad1df19b6</uuid>
<uuid>46a5b8b7-5f50-4799-8b0b-27f56cceb424</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c3632e30-d73b-4d09-a96e-2024652f9562</uuid>
</array>
<key>visualparams</key>
<binary encoding="base64">ADNV/wB/Hpk/AP//P3UBAJyEIEwAP0S8LIhRR316nv/L/wB/AAB/AAAAAAAAAAB6QnWEia1/AAAArABKAAAAAAAAAABehFWHAF4Asq0AAImZbVV/fw84AGTY1szMzDMZWUzMAIIAAMSLf+NjVAB/cn9/f4mHe0SMf10vT4JJoD8AAAAAf38AAAAAfwCfAAAAAEdJSTVxa3xwQgBTAFR6ANbMxgAAaJN/4v/G////////////zAD//////////////wD//////wCCf/8ZZP////9UAAAAMwD///8AABkAGRczABkXMwAAGQAZFzMAABkAGRczABkXMwAZFzMAfw==</binary>
<key>attachments</key>
<array>
<map>
<key>point</key>
<integer>17</integer>
<key>item</key>
<uuid>06817d22-cc5c-4964-83a5-da7f9917c3d3</uuid>
<key>asset</key>
<uuid>07f0840d-9dc5-4011-8524-15918532ba04</uuid>
</map>
<map>
<key>point</key>
<integer>29</integer>
<key>item</key>
<uuid>4d02b390-6aea-4c35-aae2-02c36034340d</uuid>
<key>asset</key>
<uuid>546bdf75-8b2a-4365-9724-ede209e5b694</uuid>
</map>
<map>
<key>point</key>
<integer>2</integer>
<key>item</key>
<uuid>17d0f3ce-76f7-429a-8d88-ecdf67014c1b</uuid>
<key>asset</key>
<uuid>3ca39d60-c6c5-40be-817d-cc60ecb60cdb</uuid>
</map>
<map>
<key>point</key>
<integer>23</integer>
<key>item</key>
<uuid>78959931-fcc8-40cf-a2b7-9bc694da2152</uuid>
<key>asset</key>
<uuid>895b3226-52df-4967-97cc-fc798799363f</uuid>
</map>
<map>
<key>point</key>
<integer>1</integer>
<key>item</key>
<uuid>7bdd00a1-1936-4638-b363-9bfba9d9e203</uuid>
<key>asset</key>
<uuid>94e3709f-e90b-4395-b94f-9c9940cba790</uuid>
</map>
</array>
</map>
</llsd>

View File

@@ -0,0 +1,111 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story One
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1089
// :NUM:1855
// :REV:3.0
// :WORLD:Opensim
// :DESCRIPTION:
// Sample NPC Card
// :CODE:
<llsd>
<map>
<key>serial</key>
<integer>0</integer>
<key>height</key>
<real>1.6885325908660889</real>
<key>wearables</key>
<array>
<array>
<map>
<key>item</key>
<uuid>98bc81c9-7ff5-40df-924f-9d17eac6ede0</uuid>
<key>asset</key>
<uuid>66c41e39-38f9-f75a-024e-585989bfab73</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>162d13a2-f3bb-42d2-910f-330b8eb7f902</uuid>
<key>asset</key>
<uuid>77c41e39-38f9-f75a-024e-585989bbabbb</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>bd8d42c6-f40f-4906-879c-aae4cfe5f33d</uuid>
<key>asset</key>
<uuid>d342e6c0-b9d2-11dc-95ff-0800200c9a66</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>436a7dea-3484-42b3-812b-7d307b353d4f</uuid>
<key>asset</key>
<uuid>4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>2afd4704-daae-4c78-8f7b-a79d7c1514d9</uuid>
<key>asset</key>
<uuid>00000000-38f9-1111-024e-222222111110</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>f937460d-207b-4e82-b6c0-7789afc0aebc</uuid>
<key>asset</key>
<uuid>00000000-38f9-1111-024e-222222111120</uuid>
</map>
</array>
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array />
</array>
<key>textures</key>
<array>
<uuid>46697265-7374-6f72-6d00-000000000000</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>84711871-c585-4be0-8ec5-0d8998769be0</uuid>
<uuid>cbd23982-104f-4719-9366-feda92ce5d12</uuid>
<uuid>47ec3452-f2f5-4d25-9b00-5b9a3867c1ab</uuid>
<uuid>9de5ef41-40a3-4997-a006-153188aecca7</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>9dfd63c3-f823-49ef-90dd-313fbd040ab6</uuid>
</array>
<key>visualparams</key>
<binary encoding="base64">IT1VFzp/P1U/KgBVPyRVX5k/IgA/bViEP4hRVWeIfwDLAAB/AAAAAAB/AAD/f3J/Yz9/jH9/AAAAvwBoAAAAAAAAAAAAkdiFAH8Af6oAAH9/bVV/fz9VKmTY1szMzDMZWUzMAH8AAJBVf4R/VQB/f39/f387f1V/f2ovT39/zAKNQgAAf38AAAAAfwCfAACyfyRVg39/f5lfAIxKG39/ANbMxgAAPx5/pdHGf3+ZzDMz////zAD//////////////wD//////wB/f/8ZZP////9UAAAAM4T///8AAAAAAAAzABkXMwAAAAAZFzMAAAAAGRczABkXMwAZFzMAfw==</binary>
<key>attachments</key>
<array />
</map>
</llsd>

View File

@@ -0,0 +1,129 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story One
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1089
// :NUM:1854
// :REV:3.0
// :WORLD:Opensim
// :DESCRIPTION:
// Sample NPC Card
// :CODE:
<llsd>
<map>
<key>serial</key>
<integer>0</integer>
<key>height</key>
<real>1.7412686347961426</real>
<key>wearables</key>
<array>
<array>
<map>
<key>item</key>
<uuid>44fc1681-6782-4053-87d8-435ebf69aca9</uuid>
<key>asset</key>
<uuid>1e6cec92-51dd-f06e-a96e-6e54fe7e38f5</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>90a7592b-c5a4-4e85-9bd5-f1243d9b7fd2</uuid>
<key>asset</key>
<uuid>a87582b6-ad37-0a21-ac7b-2ffa5e75df77</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>726b9feb-15ea-4016-adf5-1de384c90529</uuid>
<key>asset</key>
<uuid>597937e4-c9a2-1cb6-a7aa-5875cc636ef9</uuid>
</map>
</array>
<array>
<map>
<key>item</key>
<uuid>f72f2605-631c-4fed-8bba-060690dac8ee</uuid>
<key>asset</key>
<uuid>c7f3d2f2-8c72-9491-b9a5-541fc40f537c</uuid>
</map>
</array>
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array />
<array>
<map>
<key>item</key>
<uuid>a46584db-c771-4753-9727-baa9106c6a38</uuid>
<key>asset</key>
<uuid>85d86e68-d863-2855-5a93-8159ea32f17a</uuid>
</map>
</array>
<array />
</array>
<key>textures</key>
<array>
<uuid>46697265-7374-6f72-6d00-000000000000</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>3a367d1c-bef1-6d43-7595-e88c1e3aadb3</uuid>
<uuid>3a367d1c-bef1-6d43-7595-e88c1e3aadb3</uuid>
<uuid>3a367d1c-bef1-6d43-7595-e88c1e3aadb3</uuid>
<uuid>3a367d1c-bef1-6d43-7595-e88c1e3aadb3</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>c228d1cf-4b5d-4ba8-84f4-899a0796aa97</uuid>
<uuid>3a367d1c-bef1-6d43-7595-e88c1e3aadb3</uuid>
</array>
<key>visualparams</key>
<binary encoding="base64">PzXWfzFEET1eRBG7cAAApXo6ZwAAfV6cP/8APYRWIwDL/wCRAAB/AAB/AAAAf3J/Yz9/jH9/AAAAvwAACgAAAAAAAAAAkdiFADoA2GgAAI5Rd1V/fwwZAGTY1szMzDMZWUzMAFQAAJ5OT9F/PQB/Qn9/f3A7LkJ/f2FRT14KWT8AAAAAf38AAAAAfwCfAACyfzNVg166SXp9AABMAIJmANbMxgAARCZo4v/G////////////zAD//////////////wD//////wB/Qv8ZZP////9UAAAAMwD///8AABkAGRczABkXMwAAGQAZFzMAABkAGRczABkXMwAZFzMAfw==</binary>
<key>attachments</key>
<array>
<map>
<key>point</key>
<integer>9</integer>
<key>item</key>
<uuid>7ff842f2-0ef7-4805-bb04-ec3a61152205</uuid>
<key>asset</key>
<uuid>3ef0463a-248c-43d8-bdc4-83bcf16e3edf</uuid>
</map>
<map>
<key>point</key>
<integer>9</integer>
<key>item</key>
<uuid>b497f9c0-b3ba-41a3-9c3c-f943bf6c5f08</uuid>
<key>asset</key>
<uuid>62c1f804-57e4-4af8-a43f-7b46bd442c75</uuid>
</map>
<map>
<key>point</key>
<integer>30</integer>
<key>item</key>
<uuid>4ebc9791-d7e4-4acf-8b1c-34ae471428a1</uuid>
<key>asset</key>
<uuid>8a6a4219-db7d-4171-a335-7c7bbd084af1</uuid>
</map>
</array>
</map>
</llsd>

View File

@@ -0,0 +1,395 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story One
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1089
// :NUM:1856
// :REV:3.0
// :WORLD:Opensim
// :DESCRIPTION:
// Sample sequencer script for NPC animator. It sequences multiple NPCs in order thru a scenarios
// each 'things' entry is the NPC number, a (float) time to take between sending commands ( 0 is not allowed, but a small number is()
///and a @command that is sent to the NPC.
// :CODE:
// Rev: 2 fixes the Linux bug for collisions.
//
// Rev: 3 Neo Cortex: modified to become a standalone sequencer for Scene one
//
// Rev: 4 Aine Caoimhe: added support for custom appearance change slave scripts for finale sequence with 2 new commands:
// @dumpkeys must be called when all NPCs have been rezzed (ie when npcList has been populated with their keys)
// this relays the key data to the slave scripts which are numbered from 01 to 12
// @slaveap=target|appearance_notecard_name where:
// target 1 = namaka (for final one)
// target 2 = mirror namakas (for final one)
// target 3 = all namaka (for all the other ones for her)
// target -1 = dylan (for the final one)
// target -2 = mirror dylans (for the final one)
// target -3 = all dylans (for all the ones for him)
// in both of the above commands you can use any non-zero npc number but it's ignored so I'd just use 1 each time
// it will respect a time delay value if you set one
// example:
// after all NPCs have been rezzed you need to call (but you only need to do it once):
// things += [1,0,"@dumpkeys"];
// then to have all of the dylans change to appearance notecard "dylan scene 2" with no delay after it you would do:
// things += [1,0,"@slaveap=-3|dylan scene 2"];
string myStoryNotecard = "!Story";
integer debug = FALSE;
integer LSLEditor = FALSE; // set to to TRUE to working in LSLEditor, FALSE for in-world.
integer iTitleText = TRUE; // set to TRUE to see debug info in text above the controller
integer SENSE = FALSE; // sensor for an avatar
float RATE = 5; // every 5 seconds
float RANGE = 2; // a very short range as this goes into a ring around the avatar
integer COLLIDE = TRUE; // if they collide, trigger the sequence
integer isRunning = FALSE; // used to stop collision from firing twice
list npcList = [ (key) "00000000-0000-0000-0000-000000000000", "empty npc0", // this one is ignored
(key) "00000000-0000-0000-0000-000000000000", "empty npc1",
(key) "00000000-0000-0000-0000-000000000000", "empty npc2",
(key) "00000000-0000-0000-0000-000000000000", "empty npc3",
(key) "00000000-0000-0000-0000-000000000000", "empty npc4",
(key) "00000000-0000-0000-0000-000000000000", "empty npc5",
(key) "00000000-0000-0000-0000-000000000000", "empty npc6",
(key) "00000000-0000-0000-0000-000000000000", "empty npc7",
(key) "00000000-0000-0000-0000-000000000000", "empty npc8",
(key) "00000000-0000-0000-0000-000000000000", "empty npc9",
(key) "00000000-0000-0000-0000-000000000000", "empty npc10",
(key) "00000000-0000-0000-0000-000000000000", "empty npc11",
(key) "00000000-0000-0000-0000-000000000000", "empty npc12"];
list myObjects = [];
list myObjectKeys = [];
integer myObjectsInitialized = FALSE;
string npcAction = "";
string npcParams = "";
key npcKey = "";
integer NPCOptions = OS_NPC_CREATOR_OWNED; // only the owner of this box can control this NPC.
key oldCollider; //remember who collided last
key newCollider;
// CODE follows
// For rezzing in
RezIn()
{
things = [1,5,"@stop"];
things += [2,5,"@stop"];
things += [3,10,"@stop"];
Speak();
}
DoIt()
{
things = myStory;
isRunning = TRUE;
llVolumeDetect(FALSE);
llSleep(0.1);
}
list things ;
list myStory;
// DEBUG(string) will chat a string or display it as hovertext if debug == TRUE
DEBUG(string str) {
if (debug && ! LSLEditor)
llOwnerSay( str); // Send the owner debug info
if (debug && LSLEditor)
llSay(0, str); // Send to the Console in LSLEDitor
if (iTitleText) {
llSetText(str,<1.0,1.0,1.0>,1.0); // show hovertext
}
}
list ListStridedUpdate(list dest, list src, integer start, integer end, integer stride) {
return llListReplaceList(dest, src, start * stride, ((end + 1) * stride) - 1 );
}
spawn(integer who,string msg) {
DEBUG("spawning " + msg);
list data = llParseString2List(msg, ["|"], []);
//DEBUG((string) data);
list npcName = llParseString2List(llList2String(data,0), [" "], []);
npcKey = osNpcCreate(llList2String(npcName, 0), llList2String(npcName, 1), llList2Vector(data,1), llList2String(data, 2), NPCOptions);
npcList=ListStridedUpdate(npcList,[npcKey,npcName],who,who,2);
//DEBUG("npcList " + (string) npcList);
}
delete(integer who) {
DEBUG(llList2String(npcList,who*2+1) + " is removed");
osNpcRemove (llList2Key(npcList,who*2));
npcList=ListStridedUpdate(npcList,[(key) "00000000-0000-0000-0000-000000000000","removed NPC"],who,who,2);
//llSay(0, "npcList " + (string) npcList);
}
say(integer who,string msg) {
DEBUG(llList2String(npcList,who*2+1) + " says " + msg);
osNpcSay(llList2Key(npcList,who*2),0, msg);
}
sit(integer who,string msg) {
DEBUG(llList2String(npcList,who*2+1) + " sits on " + (string) msg);
// look up object named "msg" in myObjects, get key from myObjectsKeys, make "who" NPC sit on it
osNpcSit(llList2Key(npcList,who*2), llList2Key(myObjectKeys,llListFindList(myObjects,[msg])), OS_NPC_SIT_NOW);
}
touchit(integer who,string msg) {
DEBUG(llList2String(npcList,who*2+1) + " touches " + (string) msg);
// look up object named "msg" in myObjects, get key from myObjectsKeys, make "who" NPC touch it
osNpcTouch(llList2Key(npcList,who*2),llList2Key(myObjectKeys,llListFindList(myObjects,[msg])), LINK_THIS);
}
stand(integer who) {
DEBUG(llList2String(npcList,who*2+1) + " stands");
osNpcStand(llList2Key(npcList,who*2));
list anToStop=llGetAnimationList(llList2Key(npcList,who*2));
integer stop=llGetListLength(anToStop);
while (--stop>-1) { osAvatarStopAnimation(llList2Key(npcList,who*2),llList2Key(anToStop,stop)); }
osNpcPlayAnimation(llList2Key(npcList,who*2),"Stand");
}
walk(integer who,vector pos) {
DEBUG(llList2String(npcList,who*2+1) + " walks to " + (string) pos);
osNpcMoveToTarget(llList2Key(npcList,who*2),pos,OS_NPC_NO_FLY);
osNpcPlayAnimation(llList2Key(npcList,who*2),"Walk");
}
animate(integer who, string ani) {
DEBUG(llList2String(npcList,who*2+1) + " plays " + (string) ani);
osNpcPlayAnimation(llList2Key(npcList,who*2),ani);
}
appearance(integer who, string app) {
DEBUG(llList2String(npcList,who*2+1) + " changes appearance to " + (string) app);
osNpcLoadAppearance(llList2Key(npcList,who*2),app);
}
rotate(integer who,float rot) {
DEBUG(llList2String(npcList,who*2+1) + " rotates " + (string) rot);
osNpcSetRot(llList2Key(npcList,who*2),llEuler2Rot(<0,0,rot> * DEG_TO_RAD));
}
// <<<< Added by Aine
dumpKeys() {
llMessageLinked(LINK_THIS,0,"NPC_UUID_LIST",llDumpList2String(llList2ListStrided(npcList,0,-1,2),"|"));
}
slaveap(string com) {
list parse=llParseString2List(com,["|"],[]);
llMessageLinked(LINK_THIS,llList2Integer(parse,0),"NPC_CHANGE_APPEARANCE",llList2String(parse,1));
}
// <<<< End added by Aine
Speak() {
integer npc = llList2Integer(things,0);
float time = llList2Float(things,1);
string msg = llList2String(things,2);
DEBUG("npc:" + (string) npc + " time:" + (string) time + " Msg:" + msg);
if (npc) {
things = llDeleteSubList(things,0,2);
// llMessageLinked(npc,0, msg,""); // <<<<< Aine: I don't see any need for having this here still since this script is handling it
list data = llParseString2List(msg, ["="], []);
npcAction = llToLower(llStringTrim(llList2String(data, 0), STRING_TRIM));
DEBUG("Action:" + npcAction);
npcParams = llStringTrim(llList2String(data, 1), STRING_TRIM);
DEBUG("Params:" + npcParams);
if (npcAction == "@say") {
say(npc,npcParams);
} else if (npcAction == "@spawn") {
spawn(npc,npcParams);
} else if (npcAction == "@delete") {
delete(npc);
} else if (npcAction == "@sit") {
sit(npc,npcParams);
} else if (npcAction == "@touch") {
touchit(npc,npcParams);
} else if (npcAction == "@stand") {
stand(npc);
} else if (npcAction == "@walk") {
walk(npc,npcParams);
} else if (npcAction == "@animate") {
animate(npc,npcParams);
} else if (npcAction == "@appearance") {
appearance(npc,npcParams);
} else if (npcAction == "@rotate") {
rotate(npc,npcParams);
// >>>> Added by Aine
} else if (npcAction == "@dumpkeys") {
dumpKeys();
} else if (npcAction == "@slaveap") {
slaveap(npcParams);
} // >>>> end of add by Aine
if (time > 0) {
llSetTimerEvent(time);
} else {
llOwnerSay("Whooops, time = 0!");
DEBUG("npc:" + (string) npc + " time:" + (string) time + " Msg:" + msg);
llSetTimerEvent(0);
}
} else {
DEBUG("Done");
isRunning = FALSE;
Reset();
llSetTimerEvent(0);
if (SENSE)
llSensorRepeat("","",AGENT,RANGE,PI,RATE);
}
}
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE); // Rev 2
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
DEBUG("entering state default");
if (! myObjectsInitialized){
state initial;
}
llSetText("",<1,1,1>,1.0);
Reset();
llSetTimerEvent(0);
if (SENSE)
llSensorRepeat("","",AGENT,RANGE,PI,RATE);
}
sensor(integer n) {
DEBUG("Bumped");
if (! osIsNpc(llDetectedKey(0))) {
DEBUG("Sensed avatar");
llSensorRemove();
RezIn();
}
}
timer()
{
Speak();
}
collision_start(integer n) {
newCollider = llKey2Name(llDetectedKey(0));
DEBUG("Collided with " + llKey2Name(llDetectedKey(0)));
if (! osIsNpc(llDetectedKey(0)))
{
if ( newCollider != oldCollider) {
DoIt();
oldCollider = llKey2Name(llDetectedKey(0));
Speak();
}
}
}
collision_end(integer num_detected) {
DEBUG(llDetectedName(0) + " has stopped colliding with me!");
if (! isRunning && (newCollider == oldCollider) ) {
oldCollider = NULL_KEY;
}
}
touch_start(integer n) {
DEBUG("Touched by " + llKey2Name(llDetectedKey(0)));
if (isRunning) {
//insert restart code here
}
if (! osIsNpc(llDetectedKey(0))) {
DoIt();
Speak();
}
}
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START|CHANGED_INVENTORY)
{
llResetScript();
}
}
}
state initial
{
state_entry()
{
DEBUG("entering state initial");
myStory = [];
list myStoryLines = llParseString2List(osGetNotecard(myStoryNotecard), ["\n"], []);
DEBUG("text = " + (string) myStoryLines);
DEBUG("lines = " + (string) llGetListLength(myStoryLines));
integer i;
for (i=0; i<llGetListLength(myStoryLines); i++) {
string myStoryLine = llList2String(myStoryLines,i);
integer npc = (integer) llGetSubString(myStoryLine,0,llSubStringIndex(myStoryLine,","));
string rest = llGetSubString(myStoryLine,llSubStringIndex(myStoryLine,",")+1,-1);
float time = llGetSubString(rest,0,llSubStringIndex(rest,","));
string msg = llGetSubString(rest,llSubStringIndex(rest,",")+2,-2);
//now parse for sit and touch events to find the names of the objects needed
list data = llParseString2List(msg, ["="], []);
npcAction = llToLower(llStringTrim(llList2String(data, 0), STRING_TRIM));
DEBUG("Action:" + npcAction);
npcParams = llStringTrim(llList2String(data, 1), STRING_TRIM);
DEBUG("Params:" + npcParams);
if (npcAction == "@sit") {
myObjects += npcParams;
} else if (npcAction == "@touch") {
myObjects += npcParams;
}
DEBUG("npc: " + (string) npc + " time: " + (string) time + " msg: " + msg);
myStory += [npc, time, msg];
}
DEBUG("Story read, initializing objects: " + llDumpList2String(myObjects," "));
if (llGetListLength(myObjects) == 0) {
DEBUG("myObjects is empty upon entering state initial");
myObjectsInitialized = TRUE;
state default;
}
llSensor(llList2String(myObjects,0),"",ACTIVE|PASSIVE,96,PI);
DEBUG("initially looking for: " + llList2String(myObjects,0));
}
//sensor is used to scan surrounding for named prims
sensor(integer num) {
myObjectKeys = myObjectKeys + llDetectedKey(0);
DEBUG("myObjectKeys: " + llDumpList2String(myObjectKeys," "));
myObjects = llDeleteSubList(myObjects,0,0);
if (llGetListLength(myObjects) == 0) {
myObjectsInitialized = TRUE;
state default;
} else {
llSensor(llList2String(myObjects,0),"",ACTIVE|PASSIVE,96,PI);
DEBUG("now looking for: " + llList2String(myObjects,0));
}
}
no_sensor(){
DEBUG ("no target prim located");
}
}

View File

@@ -0,0 +1,3 @@
<Solution name="HyperGrid Story One">
<Project name="HyperGrid Story One" path="HyperGrid Story One/HyperGrid Story One.prj" active="true"/>
</Solution>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -0,0 +1,18 @@
<Project name="EndGame" guid="454a9e2f-f46e-4462-b24f-5cc537611cfd">
<Object name="Mortar and Pestel" guid="89597588-b0d6-41ca-856a-35d4c8867759">
<Snapshot name="End Game Photo.png" guid="2e9e63f6-07e5-4b86-b56b-4c85e481f871">
</Snapshot>
<Script name="Game prim script 5.5.lsl" guid="eedd3191-bd6e-4a0b-89f8-8c8b8205ec80">
</Script>
<Script name="Modified Hypergate to level four.lsl" guid="791a02a2-3fb5-4180-b893-da2dcbccdd86">
</Script>
<Notecard name="readme.txt" guid="ddb97516-2a50-4b4a-aa1e-669a9ff1235c">
</Notecard>
</Object>
<Object name="Sensor" guid="d0e17e2e-59b5-44c4-9fcc-0b230465397a">
<Script name="NotASensor.lsl" guid="333df8bc-125e-4888-b136-96fa15584848">
</Script>
<Script name="Sensor.lsl" guid="3e8611e2-ddff-46f1-9b13-78f55981a5bb">
</Script>
</Object>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -0,0 +1,201 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Game Prim Script for5 Game sequence Web site.
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:5.5
// :WORLD:OpenSim, Second life
// :DESCRIPTION:
// A chat system and controller based on a web site notecards replacement system
// :CODE:
// fred@mitsi.com
// Game Prim script
// v 5.5 NPC uses the server to send text to a NPC
// LOGIN URL = http://www.outworldz.com/game
string Version = "5.5"; // helps spot old scripts at the web site
// fiddly bits
integer debug = FALSE; // if TRUE, should be in Spanish
// SET ONE OR MORE OF THESE
integer COLLIDE = FALSE; // set to TRUE if you want them to collide with the prim
integer TOUCH = TRUE; // set to TRUE if they can touch it to trigger this
integer SIT = FALSE; // set to TRUE if this goes into a SEAT
integer CollideObjects = FALSE; // set to TRUE to allow things to bump this prim (unlikely)
integer SPEACHOPTION = 3; // Set to 0 for chat, 1 for IM
vector OFFSET = <0,0,0>; // offset to rez items with channel = 2. <0,0,2> will rez the object 2 meters above the prim. Max = 10 meters.
// not fiddly bits
list stack; // place to store HTTP traffic
integer HTTPSTRIDE = 2; // 3 items in a stack = 2 here as it starts option 0
Ping(string AvatarName,key AvatarKey)
{
string Language = llEscapeURL(llGetAgentLanguage(AvatarKey));
if (debug) llSay(0,"Language: " + Language);
string Me = llEscapeURL(llGetObjectName());
string Them = llEscapeURL(AvatarKey);
string Theirname = llEscapeURL(AvatarName);
string url = "http://www.outworldz.com/cgi/llgame.plx"
+ "?PrimName=" + (string) Me
+ "&Ver=" + Version
+ "&AvatarKey=" + (string)Them
+ "&Language=" + Language;
if (AvatarKey != NULL_KEY)
url += "&Avatar=" + (string)Theirname ;
if (debug ) llOwnerSay(url);
stack += AvatarKey;
stack += Theirname;
stack += llHTTPRequest(url, [], "");
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * The real start of the universe.
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
default
{
state_entry()
{
llSetTimerEvent(1);
if (COLLIDE == TRUE)
{
llSetAlpha(0,ALL_SIDES);
llVolumeDetect(FALSE);
llVolumeDetect(TRUE);
}
else {
llVolumeDetect(FALSE);
llSetAlpha(1,ALL_SIDES);
}
}
timer()
{
llSetTimerEvent(3600); // hourly
Ping("Ping", NULL_KEY);
}
// save the Web server data for this prim
http_response(key request_id, integer status, list metadata, string body)
{
if (debug) llSay(0,"Response Body:" + body);
integer where = llListFindList(stack, [request_id]) ;
if (where > -1)
{
stack = llDeleteSubList(stack,where-HTTPSTRIDE,where); // key, name, request ID
if (llGetListLength(stack) > 10 * HTTPSTRIDE ) // 10 at a time, the rest can go phooey
stack = llDeleteSubList( stack, 0, HTTPSTRIDE ); // kill off 1st element, is old
// $status|$display|$sound|$Channel|$ChannelText|$AvatarKey
list my_detail = llParseString2List( body,["|"],[]);
if (debug) llSay(0,"Dump:" + llDumpList2String(my_detail,","));
string statusType = llList2String(my_detail,0);
string storyText = llList2String(my_detail,1);
string SoundUUID = llList2String(my_detail,2);
integer ActionChannel = (integer) llList2String(my_detail,3);
string ActionText = llList2String(my_detail,4);
string AvatarKey = llList2String(my_detail,5);
if (statusType == "ACK" && llStringLength(AvatarKey) > 1 )
{
// play sound, if any
if (llStringLength(SoundUUID) > 1 ) {
if (debug) llSay(0,"Playing sound " + SoundUUID);
llTriggerSound(SoundUUID,1.0);
}
// They had the requirements, or there was no dependency, and there was text in the Channel
if (ActionChannel && llStringLength(storyText) > 1)
{
if (debug) llSay(0,"Sending Region command " + storyText + " on channel " + (string) ActionChannel);
llRegionSay(ActionChannel,storyText); // pass it to other scripts.
}
}
}
}
collision_start(integer total_number)
{
if (COLLIDE) {
if (debug)
llSay(0," prim collided ");
integer i;
for (; i < total_number; i++)
{
if (debug) llSay(0,"Collided by " + (string) llDetectedKey(i));
// if (! osIsNpc(llDetectedKey(i)))
// {
if (CollideObjects)
{
list reject = llGetObjectDetails(llDetectedKey(i), [OBJECT_CREATOR]);
key x = llList2Key(reject,0);
if (x == NULL_KEY)
Ping(llDetectedName(i), llDetectedKey(i));
} else {
Ping(llDetectedName(i), llDetectedKey(i));
}
// }
}
}
}
touch_start(integer total_number)
{
if (TOUCH) {
if (debug)
llSay(0," prim touched ");
integer i;
for (; i < total_number; i++)
{
if (debug) llSay(0,"Touched by " + (string) llDetectedKey(i));
Ping(llDetectedName(i), llDetectedKey(i));
}
}
}
changed(integer mask)
{
if (mask & CHANGED_INVENTORY)
{
llResetScript();
}
if ((mask & CHANGED_LINK) && SIT)
{
key avatarKey = llAvatarOnSitTarget(); // see if they sat down
if (avatarKey != NULL_KEY)
{
Ping(llKey2Name(avatarKey), avatarKey);
}
}
if (mask & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,92 @@
// :SHOW:1
// :CATEGORY:Hypergate
// :NAME:Hypergate when you fall in
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:5.5
// :WORLD:OpenSim, Second life
// :DESCRIPTION:
// requires oSTeleport functions to be enabled
// :CODE:
//hop://www.outworldz.com:9000/Hypergrid Story Five/191/160/22
// Hypergate script by Ferd Frederix
vector LandingPoint ; // from the desscription
string DestName = "Hypergrid Story Five"; // Where you want the Avatar to arrive at
vector LookAt = <0.0,0.0,-1.0>; // which way you want them facing.
list LastFewAgents;
string TargetAddress ; // In-Grid Teleport (Region Na
PerformTeleport( key AgentToTP )
{
integer CurrentTime = llGetUnixTime();
integer AgentIndex = llListFindList( LastFewAgents, [ AgentToTP ] ); // Is the agent we're teleporting already in the list?
if (AgentIndex != -1) // If yes, check to make sure it's been > 5 seconds
{
integer PreviousTime = llList2Integer( LastFewAgents, AgentIndex+1 ); // Get the last time they were teleported
if (PreviousTime >= (CurrentTime - 5)) return; // Less than five seconds ago? Exit without teleporting
LastFewAgents = llDeleteSubList( LastFewAgents, AgentIndex, AgentIndex+1); // Delete the agent from the list
}
LastFewAgents += [ AgentToTP, CurrentTime ]; // Add the agent and current time to the list
osTeleportAgent( AgentToTP, TargetAddress, LandingPoint, LookAt ); // Teleport agent to their target
LastFewAgents = llDeleteSubList( LastFewAgents, 20, 100); // Delete the agent from the list
}
RESET_VOL_DET()
{
llVolumeDetect( 0 ); // turn off volume detection
llVolumeDetect( 1 ); // turn it back on again
}
default
{
on_rez(integer int)
{
llResetScript();
}
state_entry()
{
llSetTextureAnim(FALSE, ALL_SIDES, 0, 0, 0.0, 0.0, 1.0);
LandingPoint = (vector) llGetObjectDesc();
TargetAddress = DestName;
RESET_VOL_DET();
}
link_message(integer n, integer v,string text, key id ) // total_number is the number of avatars detected.
{
// llOwnerSay("link:" + (string) v);
if (v == -1 ) {
// llOwnerSay("Teleport");
llSetTimerEvent(30);
}
}
timer()
{
llSay(0, "You follow the cyberbeings into another dimension..... to " + DestName);
TargetAddress = DestName;
// PerformTeleport( llDetectedKey( 0 ));
llSetTimerEvent(0);
}
changed(integer change) // something changed, take action
{
if(change & CHANGED_OWNER)
{
llOwnerSay("Owner Changed, Resetting Script");
llResetScript();
}
else if (change & CHANGED_REGION_START) // that bit is set during a region restart
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,16 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Game Prim notes
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:5.5
// :WORLD:OpenSim, Second life
// :DESCRIPTION:
// A chat system and controller based on a web site notecards replacement system
// :CODE:
A touch-sequence game set up by the scripts in the www.Outworldz.com/game web site.
The "Game prim script" has been modified to make the NPC say the things instead of an IM
These scripts in this folder are common to all game prims. Almost all the setup is done by naming each prim differently and editing the web site

View File

@@ -0,0 +1,82 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Does not use a Sensor to delete or start a NPC
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Sensor
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// A part of a controller set for NPC's
// When an avatar (the owner is not counted) gets close to this, it sends a @go command to the controller. This will make it continue from an @stop.
// when no one is around, it sends a @stop to remove the NPC. It sends these once per avatar presence.
// Does not use a laggy sensor. Will not detect the owner.
// :CODE:
integer debug = FALSE; // set to TRUE or FALSE for debug chat on various actions
integer iTitleText = FALSE; // set to TRUE or FALSE for debug hovertext above the prim
float distance = 75; // keep this distance short - in my case, we are on a broad plain and we need to notice the avatar from a long distance, but not often.
float time = 10; // keep this big - the smaller, the laggier it gets
// toggle if a person is there or not so we can detect the edge condition
integer isPersonDetected = FALSE;
// send a link message once, when no one is detected
nobodyHome() {
if (isPersonDetected) {
llMessageLinked(LINK_SET,1,"@stop","");
}
isPersonDetected = FALSE;
}
// send a link message once, when someone is detected
somebodyHome() {
if (! isPersonDetected)
llMessageLinked(LINK_SET,1,"@go","");
isPersonDetected = TRUE;
}
default {
state_entry(){
llSetTimerEvent(time);
}
timer(){
list avatarsInRegion = osGetAvatarList();
// A srided list of the UUID, position, and name of each avatar in the region except the owner.
integer i;
integer present;
for (i = 0; i < llGetListLength(avatarsInRegion)/3;i++)
{
key avatarUUID = llList2Key(avatarsInRegion,i);
if (! osIsNpc(avatarUUID)) {
vector avatarLoc = llList2Vector(avatarsInRegion,i+1); // location
float dist = llVecDist(llGetPos(),avatarLoc);
if (dist < distance)
present++;
}
}
if (present)
somebodyHome();
else
nobodyHome();
}
on_rez(integer p) {
llResetScript();
}
changed(integer what){
if (what & CHANGED_REGION_START){
llResetScript();
}
}
}

View File

@@ -0,0 +1,57 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Sensor to delete or start a NPC
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Sensor
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// A part of a controller set for NPC's
// When an avatar gets near this (75 meters, a looong way, it sends a @pause command to the controller. This will make it continue from an @stop.
// when no one is araound, it sends a @delete to remove the NPC. It sends these once per avatar presence.
// :CODE:
float distance = 75; // keep this distance short - in my case, we are on a broad plain and we need to notice the avatar from a long distance, but not often.
float time = 30; // keep this long.
// toggle if a person is there or not so we can detect the edge condition
integer isperson = FALSE;
default
{
state_entry()
{
llSensorRepeat("","",AGENT,distance,PI, time);
}
sensor(integer n)
{
if (! isperson)
llMessageLinked(LINK_SET,1,"@pause=1","");
isperson = TRUE;
}
no_sensor()
{
if (isperson)
llMessageLinked(LINK_SET,1,"@delete","");
isperson = FALSE;
}
on_rez(integer p) {
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,58 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Collider for All in One NPC Controller
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :REV:2.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Triggers the NPC controller to play the Greet notecard when collided.
// :CODE:
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE);
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
Reset();
llSetTimerEvent(3600);
}
collision_start(integer n)
{
if (osIsNpc(llDetectedKey(0)))
{
return;
}
llMessageLinked(LINK_SET,0,"@notecard=Greet","");
}
on_rez(integer p)
{
llResetScript();
}
timer()
{
Reset();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,16 @@
<Project name="Fairy Helpers" guid="1953b14c-75bb-4963-a1fe-aecfeb81446a">
<Object name="Collision Prim" guid="0bab4179-159a-4f25-8bd0-5fe2a9d0321a">
<Script name="Collider.lsl" guid="b093265e-0760-43ff-996a-245e3e1b6911">
</Script>
</Object>
<Object name="NPC Root Prim" guid="edf69c84-938d-404e-a0eb-e25d2bbb2bd9">
<Notecard name="!Appearance" guid="26033da8-a66f-4f12-88d5-223b55f603e9">
</Notecard>
<Notecard name="!Path" guid="3f6bbb56-fb52-4335-8a06-10c987a2b11a">
</Notecard>
<Notecard name="Greet" guid="d13b481a-5ed2-4271-aa65-a4fe4db4ccb4">
</Notecard>
<Script name="NPC Controller - All In One Rev 4.0.lsl" guid="e78372c7-2d18-40d7-86b5-6da0c3871970">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,10 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Placeholder
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// A Placeholder for a notecard
// :CODE:

View File

@@ -0,0 +1,15 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:A fairy notecard
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// A notecard to hold fairy info. They rez in, stop and await more commands
// :CODE:
@spawn=Dune Twinkleflash|<204.20844, 84.20403, 26.89724>
@pause=1
@stop

View File

@@ -0,0 +1,20 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Greet Notecard
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// A greeter notecard
// :CODE:
This notecard plays in an endless loop when someone is sent back by falling into the water, or by walking down the path.
The collider issues a @notecard=Greet each bump
@walk=<218.33400, 84.96158, 21.94824>
@animate=avatar_type|4
@say=Hello! Need some help? Watch for the rat. They are smarter than most of the people who go past me.
@pause=3
@walk=<204.20844, 84.20403, 26.89724>
@stop

View File

@@ -0,0 +1,6 @@
<Project name="Falling Bridge" guid="d5790790-da56-4a65-9c8c-1e6d8c83a148">
<Object name="Falling Part" guid="6797a35d-aac4-4cbc-bf0b-472521684204">
<Script name="FallingWalkway.lsl" guid="36917aac-1110-4501-991a-45772f649ef6">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,53 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Falling walkway script
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Bridge
// :REV:2.0
// :WORLD:OpenSim
// :DESCRIPTION:
// A part of a bridge or walkway that falls when walked on.
// Put in a walkway and reset it. When an avatar walks on it, it will move downward 2 meters for one minute, then restore.
// Place Hypergate water below the prim for them to fall into.
// :CODE:
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE);
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
vector initPos;
default
{
state_entry()
{
initPos = llGetPos();
Reset();
}
collision_start(integer num) {
if (osIsNpc(llDetectedKey(0)))
return;
vector newPos = initPos;
newPos.z -= 2;
llSetPos(newPos);
llSetTimerEvent(60);
}
timer()
{
Reset();
llSetPos(initPos);
llSetTimerEvent(0);
}
changed(integer what) {
if (what & CHANGED_REGION_START)
llResetScript();
}
}

View File

@@ -0,0 +1,9 @@
<Solution name="HyperGrid Story Three">
<Project name="EndGame" path="EndGame\EndGame.prj"/>
<Project name="Fairy Helpers" path="Fairy Helpers\Fairy Helpers.prj"/>
<Project name="Falling Bridge" path="Falling Bridge\Falling Bridge.prj"/>
<Project name="Hypergrid Water" path="Hypergrid Water\Hypergrid Water.prj"/>
<Project name="Landing Zone" path="Landing Zone\Landing Zone.prj" active="true"/>
<Project name="RockFall" path="RockFall\RockFall.prj"/>
<Project name="Tree Greeter" path="Tree Greeter\Tree Greeter.prj"/>
</Solution>

View File

@@ -0,0 +1,6 @@
<Project name="Hypergrid Water" guid="fed98eae-4106-4308-b55d-31156a6f5a7a">
<Object name="Water prim" guid="5d5b9433-44fb-4788-8155-011ef141023b">
<Script name="HG water.lsl" guid="dc716fab-7e33-4533-a833-db8f1dc119a6">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,84 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Hypergate water by Ferd Frederix
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Water, Game, Hypergate
// :REV:2.0
// :WORLD:OpenSim
// :DESCRIPTION:
// teleport a game player back a step when they violate a game rule.
// Useful when placed under water, or over their heads to stop flying, and next to obstacles to keep them from going around it.
// To use, put the destination coordinate vector in the Description of the prim. When collided, they get tp'ed away.
// Requires osTeleportAgent to be enabled
// :CODE:
// Rev 2.0 with Linux reset bug patched
string msg = "You fell in!";
vector LandingPoint; // Where you want the Avatar to arrive at comes from the description
vector LookAt = <0.0,0.0,-1.0>; // which way you want them facing.
list LastFewAgents;
string TargetAddress ; // In-Grid Teleport (Region Na
PerformTeleport( key AgentToTP )
{
integer CurrentTime = llGetUnixTime();
integer AgentIndex = llListFindList( LastFewAgents, [ AgentToTP ] ); // Is the agent we're teleporting already in the list?
if (AgentIndex != -1) // If yes, check to make sure it's been > 5 seconds
{
integer PreviousTime = llList2Integer( LastFewAgents, AgentIndex+1 ); // Get the last time they were teleported
if (PreviousTime >= (CurrentTime - 5)) return; // Less than five seconds ago? Exit without teleporting
LastFewAgents = llDeleteSubList( LastFewAgents, AgentIndex, AgentIndex+1); // Delete the agent from the list
}
LastFewAgents += [ AgentToTP, CurrentTime ]; // Add the agent and current time to the list
osTeleportAgent( AgentToTP, TargetAddress, LandingPoint, LookAt ); // Teleport agent to their target
llSleep(1.0);
llResetScript();
}
RESET_VOL_DET()
{
llSetStatus(STATUS_PHANTOM, FALSE); // Rev 2.
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
on_rez(integer int)
{
llResetScript();
}
state_entry()
{
LandingPoint = (vector) llGetObjectDesc();
TargetAddress = llGetRegionName();
RESET_VOL_DET();
}
collision_start(integer total_number) // total_number is the number of avatars detected.
{
if (osIsNpc(llDetectedKey(0)))
return;
llSay(0, msg);
TargetAddress = llGetRegionName();
PerformTeleport( llDetectedKey(0));
RESET_VOL_DET();
}
changed(integer change) // something changed, take action
{
if(change & CHANGED_OWNER)
{
llResetScript();
}
else if (change & CHANGED_REGION_START) // that bit is set during a region restart
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,200 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Hypergrid Story Three
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Collider
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1090
// :NUM:1857
// :REV:2.0
// :WORLD:Opensim
// :DESCRIPTION:
// Sample sequencer script for NPC animator. It sequeunces multiple NPCs in order thru a scenarios
// each 'things' entry is the NPC number, a (float) time to take between sending commands ( 0 is not allowed, but a small number is()
///and a @command that is sent to the NPC.
// :CODE:
// Notes: Link messages arte as follows
// 1 = Racoon
// 2 = Namaka
// 3 = Dylan
// Rev: 2 fixes the Linux bug for collisions.
integer busy = FALSE;
integer debug = FALSE;
integer SENSE = TRUE;
float RATE = 5;
integer COLLIDE = TRUE;
float RANGE = 2;
list things ;
RezIn()
{
things = [1,5,"@stop"];
things += [2,5,"@stop"];
things += [3,10,"@stop"];
Speak();
}
DoIt()
{
things = [-1,1,"@pause=1"];
things += [1,1,"@animate=avatar_jumpforjoy|1"];
things += [1,1,"@say=Hello! What happened to you two?"];
things += [1,1,"@run=<123.70119, 124.20567, 37.52779>"];
things += [1,1,"@walk=<124.75295, 125.30030, 37.52779>"];
// rezpoint
things += [2,1,"@walk=<125.02877, 121.68277, 37.39204>"];
things += [2,1,"@animate=SwayInBreeze|2"];
things += [2,2,"@animate=avatar_type|2"];
things += [2,2,"@say=We are cyber beings that were transformed into these appearances."];
things += [3,1,"@walk=<122.39304, 121.43833, 37.50384>"];
things += [3,1,"@animate=SwayInBreeze|2"];
things += [3,2,"@animate=avatar_type|3"];
things += [3,1,"@say=Fire and wood do not mix. I cannot be with you, my love, while in this form."];
things += [2,2,"@animate=avatar_type|2"];
things += [2,2,"@say=We must seek help to transform ourselves. I cannot live without you"];
things += [2,2,"@pause=2"];
things += [2,3,"@animate=avatar_type|3"];
things += [2,1,"@say=Now we are on a journey to find our home, and find ourselves again"];
things += [2,2,"@pause=2"];
things += [1,3,"@animate=avatar_type|3"];
things += [1,1,"@say=I see your friends have been changed by magic."];
things += [1,2,"@pause=2"];
things += [1,3,"@animate=avatar_type|3"];
things += [1,1,"@stand"];
things += [1,2,"@say=I can show a place that has potions to cure that."];
things += [1,2,"@animate=avatar_type|2"];
things += [1,2,"@say=But you need be careful here, the swamp is a dangerous place "];
things += [1,1,"@stand"];
things += [1,2,"@animate=avatar_type|2"];
things += [1,1,"@say=I can show you the way. Follow me"];
things += [1,1,"@walk=<119.90541, 124.44883, 37.51564>"];
things += [1,1,"@walk=<121.84517, 124.44883, 37.51564>"];
things += [3,1,"@animate=avatar_type|3"];
things += [3,1,"@whisper=I do not trust this racoon. He has a mask and could mislead us. "];
things += [2,1,"@animate=avatar_type|3"];
things += [2,1,"@say=We must stay here, my love, where we do not burn the woods down."];
things += [2,1,"@animate=avatar_type|2"];
things += [2,1,"@say=Be careful, friend!"];
things += [3,1,"@animate=avatar_type|3"];
things += [3,1,"@say=Thank you for helping us"];
things += [1,1,"@shout=Follow me!"];
Speak();
}
Speak() {
integer prim = llList2Integer(things,0);
float time = llList2Float(things,1);
string msg = llList2String(things,2);
if (debug) llOwnerSay("Prim:" + (string) prim + " time:" + (string) time + " Msg:" + msg);
if (prim) {
things = llDeleteSubList(things,0,2);
llMessageLinked(prim,0, msg,"");
if (time > 0) {
llSetTimerEvent(time);
} else {
llOwnerSay("Whooops, time = 0!");
if (debug) llOwnerSay("Prim:" + (string) prim + " time:" + (string) time + " Msg:" + msg);
llSetTimerEvent(0);
Reset();
busy = FALSE;
}
} else {
if (debug) llOwnerSay("Done");
busy = FALSE;
Reset();
llSetTimerEvent(0);
if (SENSE)
llSensorRepeat("","",AGENT,RANGE,PI,RATE);
}
}
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE);
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
Reset();
llSetTimerEvent(0);
if (SENSE)
llSensorRepeat("","",AGENT,RANGE,PI,RATE);
}
sensor(integer n) {
if (debug) llOwnerSay("Bumped");
if (! osIsNpc(llDetectedKey(0))) {
if (debug) llOwnerSay("Sensed avatar");
llSensorRemove();
RezIn();
}
}
timer()
{
Speak();
}
collision_start(integer n) {
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
if (busy)
return;
if (! osIsNpc(llDetectedKey(0)))
{
DoIt();
}
}
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,70 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story Three
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1090
// :NUM:1858
// :REV:1
// :WORLD:Opensim
// :DESCRIPTION:
// Sample collision script for NPC animator
// :CODE:
integer debug = FALSE;
DoIt()
{
llMessageLinked(1,5, "@walk=<121.16252, 121.84969, 37.72606>","");
llMessageLinked(1,1, "@say=The route is easy and not dangerous. Just follow me. ","");
llMessageLinked(1,1, "@walk=<103, 103, 39>","");
}
Reset()
{
llVolumeDetect(FALSE);
llSetStatus(STATUS_PHANTOM, FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
llSetTimerEvent(3600);
Reset();
}
collision_start(integer n) {
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
if (! osIsNpc(llDetectedKey(0)))
{
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
DoIt();
}
}
timer()
{
Reset();
llSetTimerEvent(3600);
}
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,82 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story Three
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, NPC
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1090
// :NUM:1859
// :REV:2
// :WORLD:Opensim
// :DESCRIPTION:
// Sample collision script for NPC animator. Moves the raccoon to the edge of the cliff
// :CODE:
// Rev: 2 fixes the Linux bug for collisions.
integer debug = FALSE;
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE);
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
DoIt()
{
if (debug) llOwnerSay("Racoon halfway");
llMessageLinked(1,0, "@say=Follow me. The bear will not hurt me.","");
llMessageLinked(1,0, "@walk=<88.10030, 74.18887, 38.53304>","");
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
Reset();
llSetTimerEvent(3600);
}
collision_start(integer n) {
if (! osIsNpc(llDetectedKey(0)))
{
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
DoIt();
}
}
on_rez(integer p)
{
llResetScript();
}
touch_start(integer p)
{
DoIt();
}
timer()
{
Reset();
llSetTimerEvent(3600);
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,74 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story Three
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, NPC
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1090
// :NUM:1860
// :REV:2
// :WORLD:Opensim
// :DESCRIPTION:
// Sample collision script for NPC animator./ Makes the racoon run off the cliff edge
// :CODE:
// Rev: 2 fixes the Linux bug for collisions.
integer debug = FALSE;
DoIt()
{
// llOwnerSay("Racoon edge of cliff");
llMessageLinked(1,0, "@say=Follow me down. I will wait for you there. ","");
llMessageLinked(1,0, "@walk=<82.71397, 39.95649, 21.40128>","");
llMessageLinked(1,0, "@walk=<81.58669, 46.91171, 21.47848>","");
llMessageLinked(1,0, "@delete","");
}
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE);
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
Reset();
llSetTimerEvent(3600);
}
on_rez(integer p)
{
llResetScript();
}
collision_start(integer n) {
if (! osIsNpc(llDetectedKey(0)))
{
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
DoIt();
}
}
timer()
{
Reset();
llSetTimerEvent(3600);
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story Three
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1090
// :NUM:1862
// :REV:1
// :WORLD:Opensim
// :DESCRIPTION:
// Sample collision script for NPC animator
// :CODE:
integer debug = FALSE;
DoIt()
{
llMessageLinked(2,1, "@animate=avatar_type","");
llMessageLinked(2,5, "@say=Be wary of the water, for it is deadly","");
}
Reset()
{
llVolumeDetect(FALSE);
llSetStatus(STATUS_PHANTOM, FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
llSetTimerEvent(3600);
Reset();
}
collision_start(integer n) {
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
if (! osIsNpc(llDetectedKey(0)))
{
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
DoIt();
}
}
timer()
{
Reset();
llSetTimerEvent(3600);
}
on_rez(integer p)
{
llResetScript();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,24 @@
// :SHOW:
// :CATEGORY:NPC
// :NAME:Hypergrid Story Three
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :CREATED:2015-11-24 20:37:06
// :EDITED:2015-11-24 19:37:06
// :ID:1090
// :NUM:1864
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// Notecard for sample NPC Sequence
// :CODE:
@spawn="Trusty" Racoon|<82.40501, 60.73487, 21.49010>
@stop
@pause=10
@walk=<82.40501, 47.29763, 21.49010>
@walk=<82.40501, 49.19700, 21.49010>
@pause=30
@say=Follow me. I see a shack that could have the magic potions you need for your friends.
@walk=<79.46262, 39.34087, 21.64303>
@stop

View File

@@ -0,0 +1,76 @@
// :SHOW:1
// :CATEGORY:NPC
// :NAME:Hypergrid Story Three
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :CREATED:2015-11-24 20:36:34
// :EDITED:2015-11-24 19:36:34
// :ID:1090
// :NUM:1863
// :REV:1
// :WORLD:Opensim
// :DESCRIPTION:
// Sample collision script for NPC animator
// :CODE:
integer debug = FALSE;
DoIt()
{
if (debug) llOwnerSay("Raccoon at bottom");
llMessageLinked(LINK_SET,0, "@walk=<79.46262, 39.34087, 21.64303>","");
}
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE);
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
Reset();
llSetTimerEvent(3600);
}
collision_start(integer n) {
if (! osIsNpc(llDetectedKey(0)))
{
if (debug) llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
DoIt();
}
}
timer()
{
llSetTimerEvent(3600);
Reset();
}
on_rez(integer p)
{
llResetScript();
}
touch_start(integer p)
{
DoIt();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,32 @@
<Project name="Landing Zone" guid="8d988283-5a2a-4bf8-8695-74576bcf26b1">
<Object name="1. Start of Game" guid="afd18458-21b2-4a2d-86bd-fa4c7dc4880a" active="true">
<Script name="Sequence.lsl" guid="913939ab-c4db-44b8-99cf-7323908bb987">
</Script>
</Object>
<Object name="2. Advance Racoon to Tree" guid="19c6753d-7d10-447a-b045-98648dbd911a">
<Script name="Advance to tree .lsl" guid="dc7afd5e-98e9-43a7-ac8b-fcafebe894aa">
</Script>
</Object>
<Object name="3. Advance to Edge" guid="5dc915b1-2989-41dd-a847-5c7b76bcdfff">
<Script name="Advance to Edge.lsl" guid="406bf410-8ff7-4013-b82f-8504f747a9da">
</Script>
</Object>
<Object name="4. Edge of CLiff" guid="d186f14c-e305-406f-a927-fc5225367166">
<Script name="Fall of edge of cliff.lsl" guid="c0f80ea1-f8fb-4b1e-8496-2f5311a25a72">
</Script>
</Object>
<Object name="5. NPC Poseball 1,2,3 etc" guid="3981f3e9-5ad9-4836-bc47-aa4d52cd8d4d">
<Script name="NPC Rev 3.9.lsl" guid="8c7ebbf5-a3e2-4a52-a230-27bea37bfec9">
</Script>
</Object>
<Object name="6. Edge Warning" guid="fa54b57b-fe74-49ec-8e7d-f0a6774b4883">
<Script name="Collision.lsl" guid="6d7aaabc-0112-4bdf-8d9b-05757edf3875">
</Script>
</Object>
<Object name="7. Racoon at Bottom" guid="1ae2ed2c-c96e-4552-a902-f9e249d33d1f">
<Script name="Collider.lsl" guid="4b2b9e6a-3336-47a4-8701-d2b52abc21a7">
</Script>
<Notecard name="!Path" guid="2df46473-c9c0-4482-8e80-cc517b484095">
</Notecard>
</Object>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
Come visit us on the hypergrid at www.outworldz.com:9000
By Ferd Frederix -from the Free Script Library at http://www.outworldz.com
LICENSE:
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
You are free to:
Share — copy and redistribute the material in any medium or format
Adapt — remix, transform, and build upon the material
The licensor cannot revoke these freedoms as long as you follow the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
NonCommercial — You may not use the material for commercial purposes.
ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.

View File

@@ -0,0 +1,2 @@
<Project name="Project" guid="ccc03f68-e66b-4659-9715-e6fc4e4316ad">
</Project>

View File

@@ -0,0 +1,32 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Noatcard for Rock Fall NPCS
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, Sensor
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Controls the path of the rockfall NPC. Requires a All in One NPC controller.
// :CODE:
@spawn=Rhyolite|<75.82667, 53.47481, 31.85062>
@walk=<78.04362, 53.50777, 21.30894>
@stop
@pause=1
@walk=<83.01588, 57.14717, 21.30894>
@animate=avatar_blowkiss|2
//////////// SECOND EXAMPLER NOTECARD
Notecards for each rock differ slightly
@spawn=Vitric Tuff|<85.04330, 49.56506, 31.85062>
@walk=<84.35471, 52.02113, 21.30894>
@stop
@pause=1
@walk=<84.35471, 52.02113, 21.30894>
@animate=avatar_jumpforjoy|2

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -0,0 +1,10 @@
<Project name="RockFall" guid="715fdfa8-4e71-4216-b512-b8dbc38ab35c">
<Object name="Rock Prim" guid="07c7bf84-84b6-405e-a810-7a1dbce286e1">
<Notecard name="Notecard.txt" guid="d31a3aae-4f8f-4a7c-9152-d431b05cc49b">
</Notecard>
</Object>
<Object name="Rockfall Controller" guid="92619ae6-498c-4a14-bed9-7d20f959d770">
<Script name="rock controller.lsl" guid="f126adc0-0662-4cbe-8dc1-78c07c4a7ecb">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,119 @@
// :SHOW:
// :CATEGORY:NPC
// :NAME:All-In one example Sequencer
// :AUTHOR:Ferd Frederix
/// :REV:1
// :WORLD:Opensim
// :DESCRIPTION:
// Sample collision script for NPC sequence for the rock fall game
// :CODE:
list things ;
DoIt()
{
things = [ -1,1,"@pause=1"];
things = [ -1,8,"@sound=tremor"];
things += [ 2,4,"@say=Oooooh a Human fell down and went boom!"];
things += [ 2,0.1,"@rotate=180"];
things += [ 4,4,"@say=No one said rocks would be safe hahahaha!"];
things += [ 2,5,"@say=Anyone want to bet this silly human will never figure out how to get to the end of this?"];
things += [ 3,2,"@say=Not me!"];
things += [ 3,0.1,"@rotate=90"];
things += [ 2,1,"@say=Not me!"];
things += [ 2,0.1,"@rotate=90"];
things += [ 3,2,"@fly=<81.33295, 53.93847, 34.28074>"];
things += [ 3,2,"@fly=<83.37263, 66.61314, 33.87567>"];
things += [ 2,2,"@fly=<81.33295, 53.93847, 34.28074>"];
things += [ 2,2,"@fly=<90.31698, 65.18839, 32.46637>"];
things += [ 4,1,"@say=No way ! Goodbye!"];
things += [ 4,1,"@rotate=270"];
things += [ 4,1,"@rotate=90"];
things += [ 4,2,"@fly=<81.33295, 53.93847, 34.28074>"];
things += [ 4,2,"@fly=<90.31698, 65.18839, 32.46637>"];
things += [ 5,1,"@rotate=270"];
things += [ 5,2,"@rotate=90"];
things += [ 5,2,"@say=I bet this human thinks everything here is worth their trust."];
things += [ 5,2,"@fly=<81.33295, 53.93847, 34.28074>"];
things += [ 5,0.1,"@fly=<90.49598, 68.05671, 35.85766>"];
things += [ 5,4,"@say=Good luck!"];
things += [ -1,0.1,"@delete"];
Speak();
}
Speak() {
integer prim = llList2Integer(things,0);
float time = llList2Float(things,1);
string msg = llList2String(things,2);
//llOwnerSay("Prim:" + (string) prim + " time:" + (string) time + " Msg:" + msg);
if (prim) {
things = llDeleteSubList(things,0,2);
llMessageLinked(prim,0, msg,"");
if (time > 0) {
llSetTimerEvent(time);
} else {
llOwnerSay("Whooops, time = 0!");
llOwnerSay("Prim:" + (string) prim + " time:" + (string) time + " Msg:" + msg);
llSetTimerEvent(0);
}
} else {
llOwnerSay("Done");
Reset();
llSetTimerEvent(0);
}
}
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE); // Rev 2.
llVolumeDetect(FALSE);
llSleep(0.1);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
Reset();
}
timer()
{
Speak();
}
collision_start(integer n) {
//llOwnerSay("Collided with " + llKey2Name(llDetectedKey(0)));
if (! osIsNpc(llDetectedKey(0)))
{
llOwnerSay("Rock fall!");
llTriggerSound("tremor",1.0);
DoIt();
}
}
touch_start(integer p)
{
DoIt();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,51 @@
// :SHOW:
// :CATEGORY:NPC
// :NAME:Collider
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :REV:1
// :WORLD:Open Sim
// :DESCRIPTION:
// Sample collision script for NPC animator
// :CODE:
Reset()
{
llSetStatus(STATUS_PHANTOM, FALSE);
llSleep(0.1);
llVolumeDetect(FALSE);
llVolumeDetect(TRUE);
}
default
{
state_entry()
{
llSetText("",<1,1,1>,1.0);
Reset();
llSetTimerEvent(3600);
}
collision_start(integer n) {
if (!osIsNpc(llDetectedKey(0))) {
llMessageLinked(LINK_SET,0, "@notecard=Hello","");
}
}
timer()
{
llSetTimerEvent(3600);
Reset();
}
changed(integer what)
{
if (what & CHANGED_REGION_START)
{
llResetScript();
}
}
}

View File

@@ -0,0 +1,10 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Placeholder
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// A Placeholder for a notecard
// :CODE:

View File

@@ -0,0 +1,17 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Sample Path notecard for the Rockfall prims
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// :CODE:
@spawn=Wise Tree|<100.15351, 112.22149, 39.33461>
@walk=<100.15351, 112.22149, 39.33461>
@wander=5|1
@pause=3
@wander=5|1
@pause=3

View File

@@ -0,0 +1,24 @@
// :SHOW:1
// :CATEGORY:Gaming
// :NAME:Path notecard
// :AUTHOR:Ferd Frederix
// :KEYWORDS:Game, conteoller
// :REV:1.0
// :WORLD:OpenSim
// :DESCRIPTION:
// Sample path notecard. The controller switches to this when bumped.
// :CODE:
@say=Hello
@walk=<104.10423, 107.79723, 39.33461>
@walk=<105.77486, 109.27833, 39.33461>
@animate=avatar_typing|3
@say=You are aware this is a swamp? That animals cannot be trusted?
@pause=3
@animate=avatar_typing|2
@say=Your friends will be safe. This is a magical land, and the trees and fairies will protect them and you. Try not to fall in the water.
@animate=avatar_jumpforjoy|1
@notecard=!Path

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
<Project name="Tree Greeter" guid="55094840-805e-49fc-8ef8-c4a0124d447a">
<Object name="Collider" guid="ad5cb94b-83fd-4d8c-b092-54caddd0fb2e">
<Script name="Tree Collider.lsl" guid="4fab9bac-1a7e-494a-bbd3-5abcd023fe68">
</Script>
</Object>
<Object name="Root" guid="48644bb0-56c7-4ae5-8751-25d6fbf99b80">
<Notecard name="!Appearance" guid="e8015925-dded-4628-9a20-ec4365c6a58a">
</Notecard>
<Notecard name="!Path" guid="e3a9df23-6d76-442a-998e-13a7cfd80770">
</Notecard>
<Notecard name="Hello" guid="00a20375-636b-4c92-8f1f-ec12d2c4e13b">
</Notecard>
<Script name="NPC Controller - All In One Rev 4.6.lsl" guid="818557cb-081c-40b3-a354-1d72895aa93b">
</Script>
</Object>
</Project>

View File

@@ -4,7 +4,7 @@
// :AUTHOR:Ferd Frederix // :AUTHOR:Ferd Frederix
// :KEYWORDS: // :KEYWORDS:
// :CREATED:2012-09-04 15:30:52.010 // :CREATED:2012-09-04 15:30:52.010
// :EDITED:2015-06-12 16:41:11 // :EDITED:2015-12-05 19:25:59
// :ID:902 // :ID:902
// :NUM:1278 // :NUM:1278
// :REV:1.1 // :REV:1.1

View File

@@ -0,0 +1,3 @@
<Solution name="NPC Manager">
<Project name="NPC Manager" path="NPC Manager\NPC Manager.prj" active="true"/>
</Solution>

View File

@@ -0,0 +1,6 @@
<Project name="NPC Manager" guid="d98a60bd-61ed-4643-8ab7-8527658ef751">
<Object name="Paramour NPC Manager" guid="1a77af4d-c330-459c-a5d2-956f807981e3" active="true">
<Script name="Paramour NPC Manager.lsl" guid="e479526f-9f96-4d45-a446-5f3d323139ad">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,210 @@
// :SHOW:
// :CATEGORY:NPC
// :NAME:NPC Manager
// :AUTHOR:Aine Caoimhe
// :KEYWORDS:
// :CREATED:2015-11-24 20:37:08
// :EDITED:2015-11-24 19:37:08
// :ID:1091
// :NUM:1865
// :REV:1
// :WORLD:OpenSim
// :DESCRIPTION:
// Wear or rez to ground, then touch to be able to globally or selectively remove NPCs from a region
// :CODE:
// Paramour NPC Manager
// by Aine Caoimhe (Mata Hari)(c. LACM) April 2015
// Provided under Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International license.
// Please be sure you read and adhere to the terms of this license: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Wear or rez to ground, then touch to be able to globally or selectively remove NPCs from a region
// OSSL functions required:
// osGetAvatarList()
// osNpcRemove()
// osIsNpc()
//
// USER SETTINGS
float dialogTimeout=60.0; // how long to wait before timing out the dialog if no response received
integer ownerOnlyTouch=TRUE; // TRUE = only owner to can touch to activate, FALSE = anyone can use it
string floatyText="Paramour NPC Manager\n(right-click and take a copy)"; // text to have floating above the object or supply an empty string ( "") for none
vector floatyTextColour=<1.000, 0.906, 0.502>; // LSL vector colour to use for the text (<0.0, 0.0, 0.0> = black, <1.0, 1.0, 1.0> = white)
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// DON'T CHANGE ANYTHING BELOW HERE UNLESS YOU KNOW WHAT YOU'RE DOING
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
list npcList;
integer indNpc;
list globalButtons=["DONE","-","KILL ALL","< PREV","RESCAN","NEXT >"];
integer myChannel;
integer handle;
key user;
showMenu()
{
string txtDia="Select a NPC to remove\nor KILL ALL to remove all NPCs\nor RESCAN to refresh the list\n\nNPCs currently in the region: "+(string)(llGetListLength(npcList)/4-1)+"\n";
list butDia;
integer i=indNpc;
while (llGetListLength(butDia)<6)
{
if ((i*4)>=llGetListLength(npcList)) butDia=butDia+["-"];
else
{
butDia=[]+butDia+[(string)i];
txtDia+="\n"+(string)i+". "+llList2String(npcList,i*4+2)+" at "+llList2String(npcList,i*4+3);
}
i++;
}
butDia=[]+globalButtons+llList2List(butDia,3,5)+llList2List(butDia,0,2);
handle=llListen(myChannel,"",user,"");
llSetTimerEvent(dialogTimeout);
llDialog(user,txtDia,butDia,myChannel);
}
doRemoveNpc(integer ind)
{
if (llGetAgentSize(llList2Key(npcList,ind+1))!=ZERO_VECTOR) osNpcRemove(llList2Key(npcList,ind+1));
llRegionSayTo(user,0,"Removed NPC "+llList2String(npcList,ind+2)+" from location "+llList2String(npcList,ind+3));
npcList=[]+llDeleteSubList(npcList,ind,ind+3);
}
doKillAll()
{
integer i;
integer l=llGetListLength(npcList);
for (i=4;i<l;i+=4)
{
if (llGetAgentSize(llList2Key(npcList,i+1))!=ZERO_VECTOR) osNpcRemove(llList2Key(npcList,i+1));
}
llRegionSayTo(user,0,"All NPCs in the region have now been removed");
finishedUsing();
}
finishedUsing()
{
user=NULL_KEY;
npcList=[];
indNpc=0;
}
stopListening()
{
llSetTimerEvent(0.0);
llListenRemove(handle);
}
doRescan()
{
list inRegion=osGetAvatarList(); // UUUID | POS | NAME
vector myPos=llGetPos();
npcList=["distance","UUID","name","location"];
integer l=llGetListLength(inRegion);
integer i;
for (;i<l;i+=3)
{
if (
osIsNpc(llList2Key(inRegion,i))
)
npcList=[]+npcList+
[
llVecDist(myPos,llList2Vector(inRegion,i+1)),
llList2Key(inRegion,i),
llList2Key(inRegion,i+2),
vec2Int0String(llList2Vector(inRegion,i+1))
];
}
if (llGetListLength(npcList)<=4) indNpc=0;
else
{
npcList=[]+llListSort(npcList,4,TRUE);
indNpc=1;
}
}
checkIndex()
{
if ((indNpc*4)>=llGetListLength(npcList)) indNpc=1;
if (indNpc==-5) indNpc=(integer)(llGetListLength(npcList)/4.0 -6.0);
if (indNpc<1) indNpc=1;
}
string vec2Int0String(vector vConvert)
{
// returns a vector as a string with values rounded to nearest whole number
string r="<"+(string)(llRound(vConvert.x))+", "+(string)(llRound(vConvert.y))+", "+(string)(llRound(vConvert.z))+">";
return r;
}
default
{
state_entry()
{
myChannel=0x80000000|(integer)("0x"+(string)llGetKey());
finishedUsing();
llSetText(floatyText,floatyTextColour,1.0);
}
timer()
{
llRegionSayTo(user,0,"Dialog has timed out. Please touch me again to resume");
stopListening();
finishedUsing();
}
on_rez(integer food)
{
llResetScript();
}
changed (integer change)
{
if (change & CHANGED_REGION_START) llResetScript();
else if (change & CHANGED_OWNER) llResetScript();
else if (change & CHANGED_REGION) llResetScript();
}
touch_start(integer num)
{
key toucher=llDetectedKey(0);
if (toucher!=user)
{
if (user==NULL_KEY)
{
if (ownerOnlyTouch && (toucher!=llGetOwner())) llRegionSayTo(toucher,0,"Sorry, only the owner can use this");
else
{
doRescan();
if (!indNpc) llRegionSayTo(toucher,0,"There are currently no NPCs in this region");
else
{
user=toucher;
showMenu();
}
}
}
else llRegionSayTo(toucher,0,"Sorry, this is already being used by someone else");
}
else showMenu();
}
listen(integer channel, string name, key who, string message)
{
stopListening();
if (message=="DONE") finishedUsing();
else if (message=="KILL ALL") doKillAll();
else if (message=="-") showMenu();
else if (message=="RESCAN")
{
doRescan();
showMenu();
}
else if ((message=="< PREV")||(message=="NEXT >"))
{
if (message=="NEXT >") indNpc+=6;
else indNpc-=6;
checkIndex();
showMenu();
}
else
{
// message is number of the NPC to remove
doRemoveNpc(4*((integer)message));
if (llGetListLength(npcList)<=4)
{
llRegionSayTo(user,0,"There are no more NPCs remaining in the region");
finishedUsing();
}
else
{
checkIndex();
showMenu();
}
}
}
}

View File

@@ -0,0 +1,251 @@
// :SHOW:
// :CATEGORY:NPC
// :NAME:PMAC
// :AUTHOR:Aine Caoimhe
// :KEYWORDS:
// :CREATED:2015-11-24 20:38:40
// :EDITED:2015-11-24 19:38:40
// :ID:1095
// :NUM:1871
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// PARAMOUR MULTI-ANIMATION CONTROLLER (PMAC) v1.02(OSSL)
// :CODE:
// Provided under Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International license.
// Please be sure you read and adhere to the terms of this license: https://creativecommons.org/licenses/by-nc-sa/4.0/
PARAMOUR MULTI-ANIMATION CONTROLLER (PMAC) v1.02
by Aine Caoimhe (c. LACM) January 2015
**** OVERVIEW *****
The Paramour Multi-Animation Controller (PMAC) is a no-poseball script system
intended for use in
almost any piece of furniture that needs to be able to position and animate
multiple avatars at once.
PMAC is designed to offer a high performance alternative to existing systems
such as MLP, nPose, and
xPose. PMAC uses a core engine that leverages the powerful OSSL functions
available only in Opensim
to drastically increase the script's speed and reliability, while at the same
time using only a
fraction of the sim resources of the existing systems.
***** KEY FEATURES *****
* WORKS IN ANYTHING - The PMAC system can be put into anything, from a
single-prim scultpy blanket or
one-piece mesh sofa to an elaborate multi-piece bedroom linkset. You can put it
in a simple pine cube
prim if you feel like it. There's nothing extra to attach and hide or position
nearby. All it takes
is a single prim. The only "requirement" is that PMAC must be in the root prim
of an object.
* NO POSEBALLS - There are no poseballs used at all for PMAC. None to disguise
or hide as part of the
furniture, none that have to be rezzed and sat on, none to get lost inside a
sofa or buried underground
or scattered around a sim...all of the users simply sit on the furniture item
that contains the main
script and PMAC takes care of the rest using a "virtual poseball" approach that
exists within the logic of the script.
* A TRUE MULTI-AVATAR CONTROLLER - PMAC systems can be set up to handle
animations designed for 1 to as
many as 9 avatars with the flexibility to load any preset configuration on the
fly. You could set it up
in a sofa to act like a sit AO when you're lounging around alone, and quickly
turn it into a couples
controller when that special someone comes to visit, and then switch it into a
multi-person handler
when you have even more company...and it's all available virtually instantly
from the menu without
the need to stand up or reset...all adjustments are done on the fly during use.
Now your VL furniture
items can be just as flexible as your RL ones are.
* REGION-FRIENDLY - Most multi-avatar controllers are pretty harsh on a
simulator, eating up valuable
cycles, and memory and other script resources. PMAC's extensive use of OSSL
functions allows it to
drastically reduce this overhead. The core PMAC system is a single script. Yep,
a fully functional
controller for up to 9 avi all done with one low-footprint script. When not in
use, it is completely
dormant and uses virtually no simulator resources at all (just the tiny amount
of memory required for
the script itself). Even when in use, the system's footprint barely changes --
unlike SL systems with
poseball scripts, animation handler scripts, multiple timers, multiple
listeners, high message traffic,
large menu memory consumption, and all the other complications that LSL-based
scripts are subject to.
Even with 9 avatars seated all it uses is a single script and single listener.
The only time it ever uses a timer is on those rare occasions when you're
editing positions or setting up a new system.
* SPEED - The total time to initialize a typical PMAC system is approximately
one second. That's right,
just 1 second! If for some reason you need to reset it you'll be ready to use it
again almost instantly.
Due to its unique OSSL-based menu method, PMAC dialogs pop up right away even
for very extensive set-ups
with hundreds of different animations.
* SYNCH - PMAC uses the tried and true Paramour synch method, keeping up to 9
avatars moving in perfect
unison once their animations are in your viewer's cache.
* FULL NPC INTEGRATION - Want some company but none of your friends are online?
PMAC can rez a NPC
(or two, or three, or up to eight!) to join you instead. When you're done, PMAC
tucks them away again
for next time. You can pick who, where, and when at the touch of a few simple
dialog buttons.
* AUTO-MODE - Don't want to have to change your own animations? Simply engage
PMAC's auto mode and
let the system do it for you, more or less like engaging a sit AO for up to 9
people. Timing can be chosen from a variety of options and changed on the fly;
and you can configure the system to engage it automatically so you can have your
furniture fully useable without ever even needing to see a dialog (but of course
you can simply touch the object to bring up the menu and disengage this at any
time).
* SWAPPING - You can quickly and easily swap positions with anyone else -- even
if they aren't there
and it's just an unoccupied "virtual position".
* AUTO HEIGHT ADJUSTMENTS - PMAC automatically adjusts positions based on each
avatar's height (although admittedly this is a very rudimentary estimate and
depends a lot on how the original animation was created). In many cases this
will be sufficient unless you have a very tall or short avatar.
* ON-THE-FLY POSITION ADJUSTMENTS - The owner can make more detailed adjustments
to animation positioning at any time, rapidly and on the fly, and it remains
temporarily stored in the script's memory.
* NO NOTECARD EDITING FOR USERS - If the owner wishes to persist any position
adjustments to the system's notecards, PMAC facilitates this by handling it all
done with the touch of a single dialog button. No more copy-pasting reams of
text from chat into a notecard and hoping you don't mess something up! Typically
the only time you'll manually open and edit a notecard is when making major
changes such as adding new animations or deleting existing ones.
* EASY CONFIGURATION - PMAC can be fully configured in the script or via an
optional configuration notecard which some users might find a little less
intimidating to do.
* USER ACCESS RESTRICTIONS - The PMAC system has a variety of settings allowing
you to control who can use it, who can access which menus or animations, who can
rez which NPCs, and other similar access-control restrictions.
* POWERFULL ADD-ON COMMAND SYSTEM INTEGRATION - As a design goal, I wanted the
PMAC system to be easy and intuitive enough to just "rez and play" without what
can be a rather nasty learning curve of many other systems. I also felt it was
imperative to optimize PMAC's performance, simulator footprint, and XEngine
demands. As a result, only the most important and commonly-demanded features are
part of the core "out of the box" PMAC system. But I also wanted to offer the
flexibility for more advanced builders and users to enhance its functions,
capabilities and offerings, so PMAC incorporates an integrated and extremely
powerful command system that opens up almost endless possibilities via the use
of scripted add-ons. If PMAC doesn't do something you want it to do, it's very
likely that an add-on can be scripted to do it in conjunction with PMAC's
command system -- at the expense of the additional script(s) overhead. I will
likely create add-ons for the most often-requested extra features; but anyone
with reasonable scripting skills can write their own custom applications for
specialized requirements. The only limits are likely to be your imagination (and
ability to script it).
* FREE - The PMAC system is the culmination of many months of work and almost 5
years of development and testing of various approaches to making the "next
generation" multi-avatar controller, and I'm releasing it to the Opensim
community for free (under Creative Commons Attribution-Non-Commercial-ShareAlike
4.0 International license). Any add-ons I create for it in future will be free,
too, and I sincerely hope that other add-on creators will follow suit and donate
their enhancements to the community as well.
* COMPANION MLP CONVERTER - Thanks to Seth Nygard, existing MLP 2.x systems can
be easily converted to PMAC in a matter of minutes using a supplied conversion
script. Look for the "PMAC Builder's Kit" which contains everything you need to
take an existing MLP system and turn it into a PMAC system.
***** CHANGE LOG *****
v. 1.0 January 2015 (Initial beta release)
v. 1.01 March 2015 (General release)
- NEW: added ability to supply a configuration notecard that will be read on
initialization and override scripted variable values (written by Seth Nygard -
thanks Seth!)
- TWEAK: tweaked Seth's configuration addition to support both his nameset as
well as the actual variable names being supplied
- TWEAK: slight further optimizations of memory use
- TWEAK: system is now made completely inactive if worn
- TWEAK: only owner is now notified when initialization completes
- FIX: minor text tweaks and typo corrections
v 1.02 May 2015 (Update Release)
- BUGFIX/OVERSIGHT: add flag so if an addon rezzes an object core is prevented
from interpreting this as an edit handle being rezzed and entering edit mode
- BUGFIX: fixed a bug in edit mode list wrapping where advancing from the last
animation in a group using "NEXT" would pull the incorrect data for the next
(first) animation.
- TWEAK: set a minimal sit target on root to allow sitting on it from distances
greater than 10m
- TWEAK: When displaying animation number range in dialog menu, display the
actual range instead of possible range
- NEW: added support for the Object-Rezzing prop add-on "NC_PROP" by Neo Cortex
(code from Neo)
- NEW/TWEAK: Altered script logic to optionally allow NPCs to occupy a PMAC
object with no "real" avatars being present and added a user configuration
variable to enable or disable this feature. By default it will be set to FALSE.
If the NPC is to be rezzed by another object/script that script will also need
to handle seating it, later unseating it, and removing it from the scene.
Initially rezzing a PMAC NPC still requires an avatar user but if that user
stands when NPC flag is TRUE, the NPC will not be removed (I'll need to sit down
again and remove it). Be careful NOT to reset the core script when a PMAC NPC is
still in the scene since this will strand it.
- NEW/TWEAK: Added new user option to show the groups menu instead of the
current group's animation menu when you first initiate the dialog. Subsequently
if you close the dialog and re-show it, you should received whatever your most
recent dialog was unless someone else was in control in the interim.
**** UPDATING FROM PMAC 1.01 TO PMAC 1.02 *****
- if you use in-script user settings instead of the configuration notecard,
transfer your settings to the PMAC core 1.02 script.
- delete the Core 1.01 script from your object's inventory
- place a copy of the Core 1.02 script into the object's inventory - it should
compile and enable itself automatically
- replace the old READ ME 1 and READ ME 2 notecards with the updated versions.
The other three core read me notecards remain unchanged.
- no further changes are require...your system is ready for use
- OPTIONAL: if you want to use the new object-rezzer add-on by Neo Cortex, place
a copy of it in the object's inventory and follow the instructions he supplied
for setting up your animations to use it. The MLP parser by Seth Nygard does not
currently support conversion of MLP rezzed objects so you will need to do this
manually.
***** LICENSE *****
All PMAC scripts and documentation are my own creation and released under
Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International
license. Please be sure you read and adhere to the terms:
https://creativecommons.org/licenses/by-nc-sa/4.0/
Unless otherwise specified, animations contained in any Paramour product are
*not* my creation but were obtained under equivalent CC terms. If you are the
creator of one of the animations and do not wish it distributed please notify me
and I will immediately remove it from all current and future offerings.
***** CONTACT *****
You can most easily contact me in world at refugegrid.com:8002 or on G+

View File

@@ -0,0 +1,420 @@
// :SHOW:
// :CATEGORY:NPC
// :NAME:PMAC
// :AUTHOR:Aine Caoimhe
// :KEYWORDS:
// :CREATED:2015-11-24 20:38:40
// :EDITED:2015-11-24 19:38:40
// :ID:1095
// :NUM:1872
// :REV:1
// :WORLD:OpenSim
// :DESCRIPTION:
// PARAMOUR MULTI-ANIMATION CONTROLLER (PMAC) v1.02 (OSSL)
// :CODE:
PARAMOUR MULTI-ANIMATION CONTROLLER (PMAC) v1.0 (OSSL)
by Aine Caoimhe January 2015
OWNER INITIAL SET-UP AND INSTALLATION
**** OVERVIEW *****
A new PMAC system is usually supplied inside an object that is already set up and configured for general use,
containing all of the necessary animations, notecards, etc. In most cases you can simply "rez and play" right
away provided your region is already set up to allow the necessary script functions.
This notecard contains details configuring regions correctly to allow PMAC to work, details about some of the
user settings you may wish to change, and trouble-shooting tips.
The step-by-step overview for a new user is to set (or confirm) the following:
1. Ensure the server supports the script
2. Ensure the region is configured to allow the necessary functions
3. Rez the object
4. If necessary, reset or even recompile the scripts
5. Adjust any user settings according to preference
***************************************
1. Ensure Server Support of the Script
****************************************
PMAC uses both LSL and OSSL functions that make extensive use of vectors and rotations for positioning and text-based
notecards for data storage. The server must use the period (decimal point)(.) as the decimal separator for numbers that
require this precision (called "floats").
In almost all cases your server will already have this configuration (otherwise other scripts would also have issues)
but if you experience problems with odd behaviour this is the first thing to check. Some computer localizations (particularly
linux systems in Europe) may be configured to use the comma (,) as the decimal separator which will *not*
work with this system (and many other LSL scripts). Consult your operating system guide as to how to
configure the computer to use the decimal point separator.
********************************************************************
2. Ensure the Region is Configured to Allow the Necessary Functions
********************************************************************
The PMAC script makes extensive use of a special set of functions that are only available in Opensim: OSSL functions.
Depending on your region's configuration, these may or may not be available so it is essential to check and ensure that
the correct settings have been made. As a general rule of thumb:
- By default, stock Opensim builds will need changes to the region configuration
- By default, the Diva distribution is pre-configured correctly and will require no changes
- Most open grid configurations will require at least some changes
- Many region hosting services will require some changes, although this is slowly changing, and for many
such providers any changes to the ini files must be made by their staff. If that's the case for you, please
provide them with a copy of this information.
****** NOTE: there have been recent changes to OSSL function set-up and enabling *****
The method for setting OSSL functions changed as of Opensim Git #2e1f5bb (r/25931 2015-04-14) so the instructions
below may not be fully applicable to your region's set-up. Please see:
http://ainetutorials.blogspot.ca/2015/04/notice-ossl-implementation-changes-for.html for further information
You will still need to enable NPC in the [NPC section] in either case.
Unless you are using a special custom configuration (such as the Diva distribution) the configuration changes that
need to be made are located in the /bin/opensim.ini file that is in the same directory as the opensim.exe for the
instance that runs the region.
Scroll down through the opensim.ini file and look for the [NPC] section and ensure that NPCs are enabled to allow
PMAC to rez them in the region
[NPC]
Enabled = true
Now scroll through the opensim.ini file and find the [XEngine] section -- usually it is before the [NPC] section.
There are a number of changes that need to be made here. First, we need to generally allow OSSL functions, then
we need to ensure that some of the ones used by PMAC are both available and suitably "protected" against abuse
by other visitors to your region.
In the [XEngine] section find the line where the AllowOSFunctions variable is set and ensure it is set to true.
[XEngine]
AllowOSFunctions = true
A little further down, look for OSFunctionThreatLevel which sets a global "threat level" for OSSL functions.
If an OSSL has this threat level or less, it will be allowed for any script that wants to use it. By default
Opensim has this set to VeryLow but in my opinion a global Low setting is perfectly secure.
[XEngine]
OSFunctionThreatLevel = Low
PMAC uses a number of functions that are "higher threat" than this, though. You could just set a far higher
global threat level but then you would expose yourself and your region guests to malicious visitors so I strongly
advise against doing so. Instead, you can set specific functions to be available only to a limited range of users.
The options are to specify one or more of the following to have permission to use each function (the one(s) you use
will depend on your specific set-up):
- ESTATE_OWNER allows scripts owned by the estate owner of the region to use those functions
- ESTATE_MANAGER does the same for scripts owned by one of your estate managers
- PARCEL_OWNER does the same for scripts owned by a parcel owner and located in that parcel
- PARCEL_GROUP_MEMBER does the same for scripts owned by a member of the same group that the parcel
- by specifying the UUID of a user (or multiple users) to allow scripts they own to use the functions
Note that in all cases it is the script owner (usually whoever rezzed the object) that is checked against
the permission, not the person using it.
It is beyond the scope of these instructions to go any further into this so if you wish to get absolutely all
of the details see: http://opensimulator.org/wiki/Threat_level
For someone who is a region owner (usually this means ESTATE_OWNER) I would suggest setting all OSSL functions
to be available at least for any scripts that you own, and in many cases probably for those belonging to any E
STATE_MANAGER you assign (since to give them those powers you probably trust them sufficiently not to abuse them).
My own regions' XEngine section includes the following lines to enable OSSL and allow scripts owned by myself
or my estate managers to use functions that are either used by PMAC or are likely to be used by other common
OSSL scripts you might wish to write/use (usually relating to NPC or animation):
[XEngine]
AllowOSFunctions = true
OSFunctionThreatLevel = Low
Allow_osMessageAttachments = true
Allow_osGetGridName = ESTATE_OWNER, ESTATE_MANAGER
Allow_osGetGridNick = ESTATE_OWNER, ESTATE_MANAGER
Allow_osOwnerSaveAppearance = ESTATE_OWNER, ESTATE_MANAGER
Allow_osGetLinkPrimitiveParams = ESTATE_OWNER, ESTATE_MANAGER
Allow_osGetPrimitiveParams = ESTATE_OWNER, ESTATE_MANAGER
Allow_osMakeNotecard = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcCreate = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcGetPos = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcGetRot = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcLoadAppearance = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcMoveTo = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcMoveToTarget = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcPlayAnimation = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcRemove = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcSaveAppearance = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcSay = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcSetRot = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcShout = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcSit = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcStand = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcStopAnimation = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcTouch = ESTATE_OWNER, ESTATE_MANAGER
Allow_osNpcWhisper = ESTATE_OWNER, ESTATE_MANAGER
Allow_osSetPrimitiveParams = ESTATE_OWNER, ESTATE_MANAGER
Allow_osSetProjectionParams = ESTATE_OWNER, ESTATE_MANAGER
Allow_osSetRegionWaterHeight = ESTATE_OWNER, ESTATE_MANAGER
Allow_osSetTerrainHeight = ESTATE_OWNER, ESTATE_MANAGER
Allow_osAvatarPlayAnimation = ESTATE_OWNER, ESTATE_MANAGER
Allow_osAvatarStopAnimation = ESTATE_OWNER, ESTATE_MANAGER
Allow_osForceOtherSit = ESTATE_OWNER, ESTATE_MANAGER
Allow_osGetNotecard = ESTATE_OWNER, ESTATE_MANAGER
Allow_osGetNotecardLine = ESTATE_OWNER, ESTATE_MANAGER
Allow_osGetNumberOfNotecardLines = ESTATE_OWNER, ESTATE_MANAGER
Allow_osRegionNotice = ESTATE_OWNER, ESTATE_MANAGER
Allow_osAgentSaveAppearance = ESTATE_OWNER, ESTATE_MANAGER
There are many other OSSL functions but the above will suffice for most people and includes the ones
necessary to allow PMAC to work correctly. After making your changes you will need to save the
opensim.ini file, then restart the simulator (restarting just the region will not suffice).
******************
3. Rez the Object
******************
Not much to say here...just rez it to ground and position it wherever you want it to be.
*******************************************
4. Reset or Recompile Scripts if Necessary
*******************************************
Exactly what will be required here depends on your main server configuration, your region
configuration, and where you obtained the PMAC object. In many cases you won't need to do
anything...simply rezzing the object will automatically cause the script to reset and initialize.
After a second or two, you'll see a message in general chat telling you that initialization is
complete and the object is ready to use.
If this doesn't happen, you may simply be able to right-click on the object and use the radial
menu to reset the script.
In some regions and/or grids, it is necessary to "recompile" a script -- particularly when the
object was obtained from a different grid while hypergridding -- before it will work. Although
a little tedious, if you don't know how to recompile a script here is a set of steps to take to
be absolutely sure that everything is running properly:
1. Select the object while in edit mode in your viewer
2. Take a copy of the PMAC Core script into your own inventory
3. If the object contains any add-on scripts, take copies of those too
4. Look for an object in inventory called "~~~positioner" and take a copy of it as well
5. Wear the ~~~positioner object (on your left hand), then edit it and open the script inside it
6. Make a tiny change to this script by adding a space at the end of one of the red comment lines
(or add an empty blank line at the very end)
7. Now "Save" this. You should simply see a "Save complete" notice and no errors...this has forced
that script to recompile.
8. Now unwear the ~~~positioner
9. Delete the original ~~~positioner from the main object's inventory
10. Now place your newly recompiled ~~~positioner from your inventory into the original object
11. Delete each of the scripts that you took copies of from the original object
12. If you have any add-on scripts, put the copies of these back into the original object first.
They will automatically recompile when you do this.
13. And finally, place the copy of the PMAC Core script back into the original object and it will
recompile as well.
You should now see the message telling you that initialization is complete and the object is ready to use.
***********************************************
5. Adjust User Settings According to Preference
***********************************************
In most cases this is entirely optional because the object will come pre-configured to be suitable
for the average user. If you want to look at the settings or change any, open the PMAC Core script
and you will see a section at the top where you can do this -- it's divided into a "general user
section" and an "advanced/builder" section.
I'll give detailed information for the basic ones, and assume that anyone using the advanced/builder
ones will have enough scripting knowledge to need a little less detail.
***** General User Settings: *****
Name: defaultGroup
Type : string
Use: Identify the animation group to load when the PMAC object initializes.
Details:
The name you supply here is just the simple group name, not the full notecard name, and must be
enclosed in quotation marks (with a semi-colon after the last one). If your animation group's
notecard name is ".menu123A Groupname" then the value you'd enter just "Groupname" for this variable.
It will always be loaded initially, even if its permission settings wouldn't normally allow the user to do so.
********
Name: resetOnQuit
Type : integer (boolean) TRUE or FALSE
Use: Indicate whether the script should reset and re-initialize the object when you stop using it.
Details:
If you set this to TRUE (no quotation marks!) then after you finish using the object and everyone
stands up, the object will completely reset itself and reload all of its default values. This is useful
for furniture items where you might want them to have a specific set of animations active whenever
someone new sits down and you don't want to have to remember to reset it back to these when you finish using it.
If you set this to FALSE it will simply leave everything the way it's currently set and when someone
sits down again it will resume with whatever animation was most recently loaded. If it was in auto mode
when you stopped using it, it will resume auto mode when the next person sits.
**********
Name: ownerUseReq
Type : integer (boolean) TRUE or FALSE
Use: Indicate whether the owner must be sitting on the object before anyone else is allowed to sit
Details:
If set to TRUE, the object will refuse to allow anyone other than the owner to sit on it. Once the owner
is seated, other people will then be allowed to sit as well. If the owner then stands, the existing users
will be allowed to remain there but no new user (other than the owner) will be allowed to sit. Normally
you'd only set this to TRUE for an object that you wish to reserve for your own private use.
If set to FALSE, anyone can sit down and start using the object even if the owner is offline or in another region.
**********
Name: ownerOnlyMenus
Type : integer (boolean) TRUE or FALSE
Use: Indicate whether only the owner is allowed to access the dialog menus
Details:
If set to TRUE, only the owner can ever touch the object to access the dialogs. Anyone else who sits will
simply play whatever the current animation is and continue to do so until the owner uses the menu to change it.
If auto mode is enabled then it will change animations based on its timer setting so you could use this as a
sort of "multi-person AO" for a furniture item.
If set to FALSE, anyone can touch the object and ask to be the controller in charge of the dialogs. The menu
options they see will depend on the permission settings of the individual group notecards and NPC notecards.
Only the owner ever sees the top line of the OPTIONS menu.
***********
Name: ownerUseUnlocksPerms
Type : integer (boolean) TRUE or FALSE
Use: Indicate whether other users temporarily gain "owner" permissions for groups and NPCs if the owner seated
Details:
If set to TRUE, when the owner is one of the users currently seated on the object, all users can then access
animation groups and NPCs that are normally restricted to the owner. This is a setting you might use for a bed
where you want a different (larger) set of animations available when you're there, but want to restrict them otherwise.
If set to FALSE, only the owner will ever be able to see or load notecards where the permission is set to
owner-only; and only group members with the group currently active will see or be able to access notecards where
the permission is set to group.
*************
Name: autoOn
Type : integer (boolean) TRUE or FALSE
Use: Indicate whether the PMAC Auto mode should be turned on by default
Details:
Auto mode automatically cycles through the animations in the currently-loaded animation group, advancing based
on the time set for autoTimer (see below). If you set this to TRUE, this will automatically be enabled any time
the script is reset so it would be particularly useful if you're using the ownerOnlyMenus=TRUE setting above.
If set to FALSE, the object will be in manual mode when the script resets.
Regardless of this setting, when you stop using the object it will remember and whatever its last setting was
and use it when someone sits down to start using it again. If you don't want that to happen you would need to
set the resetOnScript=TRUE (see above) which will cause the script to reset after you stop using it and then
pick up and use the default value again.
*************
Name: autoTimer
Type : float
Use: Set a default time to use for the auto mode's timer
Details:
The value set here is a number larger than 0.0 and determines the default number of seconds to wait before
advancing to the next animation when PMAC is in auto mode. You can use the OPTIONS menu to change this
during use, too. When you stop using the object it will remember whatever value was most recently used and won't
pick up and use this default value again until the script is reset.
*************
Name: showGroupsMenuFirst
Type : integer (boolean) TRUE or FALSE
Use: determines which menu level to show first when initiating dialog
Details:
When FALSE, initiating the dialog will display the current group's animation selection menu (PMAC 1.01 and MLP
normal behavour). When TRUE, the groups menu will be shown instead. Default is FALSE.
*************
Name: allowSoloNPC
Type : integer (boolean) TRUE or FALSE
Use: Determines whether an NPC can occupy a PMAC object when no avatars are currently using it
Details:
When FALSE, PMAC will not allow a NPC to sit on a PMAC object unless an avatar user is already seated. When
there are no remaining "real" users, any remaining NPC are removed. When TRUE, NPCs are allowed to occupy the
object but it becomes your responsibility to later unseat them and remove them from the scene. DO NOT manually
reset the core script until you've removed any NPCs it is controlling or they will become stranded. NOTE: using
the dialog option "QUIT" will still remove all NPCs regardless of this setting.
***** Advanced/Builder Settings: *****
There are five variables in this section, three of which are simply convenience/preference tweaks
that change the appearance of the "positioner" handles when you are in edit mode.
handleName is the object name in inventory for the positioning handle. If you want to use a different
handle than the one I supply by default, simply put it in inventory and enter its name for this
variable to have it be rezzed instead.
handleColours is a list of nine LSL vector colours to use for the positioning handles in edit mode.
You must supply exactly 9 vectors and they are rezzed in the order supplied in the list for each position.
handleSize is the vector dimension to set for each of the positioning handles. All handles will use this same size.
handleAlpha is the (float) alpha value that will be used for all of the positioning handles.
And finally, baseAn is the name of a priority 1 animation in inventory that should be used for synch.
I supply one in almost all animation products I use that is just a generic standing pose but if you
want to use a different one then drop it into inventory and change this variable to that animation's
name. This is a work-around method for the "fix" that was made to Opensim in 2012 that broke the old
behaviour of stopping and starting animations. While there are various ways to make synch work, in my
view this is the most reliable one for this sort of application. In normal use, you will never see it
or even be aware that it's running underneath the other animations. When a user stands it is
automatically released along with the currently playing animation.
After making any changes to any of the above, save and your changes will be applied.
*********************************
6. Optional Configuration Notecard
*********************************
Instead of manually setting configurations in the script directly, you can include a configuration
notecard in PMAC's inventory instead. Bu default it must have the name ".PMAC-CONFIG" although
you can change this in the script's user settings. Each line of the notecard can contain a parameter
name, followed by an equals sign followed by the desired value. Any that are included will override
the values set in the script directly, and any that omitted will use the script's current default
values. Commands recognized:
- defaultGroup or DefaultGroup
- resetOnQuit or ResetOnQuit
- ownerUseReq or OwnerUseReq
- ownerOnlyMenus or OwnerOnlyMenus
- ownerUseUnlocksPerms or OwnerUseUnlockPerms
- autoTimer or AutoTimerValue
- baseAn or BaseAnimation
-showGroupsMenuFirst or ShowGroupsMenuFirst
- allowSoloNPC or AllowSoloNPC
Example: this would change the default menu to load on startup to "Cuddles", changes the behaviour to
reset the script on quit, and changes the system to allow solo NPCs.
defaultGroup = Cuddles
ResetOnQuit = TRUE
allowSoloNPC = TRUE
***************************
7. Other
***************************
In most cases you'll now be up and ready to go and you will probably not have had to do many of the above steps.
If you use add-ons to the PMAC system, they should supply any necessary instructions for how to set them.
Add-ons are optional and do not need to be included in an object unless your set-up specifically uses them.
If a notecard supplies commands for one but the add-on script isn't present, the command is ignored but it
will in no way impair the operation of the core script.
Unless you are a very advanced scripter I would strongly suggest you never change anything in the script
other than these settings at the top (up to the place where it warns you not to change anything below it).

Some files were not shown because too many files have changed in this diff Show More