@@ -1,5 +1,5 @@
|
||||
<Project name="All In One NPC Recorder and Player" guid="d3dec827-ef5a-4d9b-af98-c80cf31b7eb7">
|
||||
<Object name="Object" guid="dcc0f525-dc9f-41c9-afbf-1769629e09a6" active="true" description="key=12345000-0000-0000-0000-0000000000002">
|
||||
<Object name="Object" guid="dcc0f525-dc9f-41c9-afbf-1769629e09a6" active="true" description="key=00000000-0000-0000-0000-000000000000">
|
||||
<Notecard name="!Appearance" guid="bcec7dca-aee3-4d54-a0af-e1f451b44c8a">
|
||||
</Notecard>
|
||||
<Notecard name="!Appearance2" guid="56d7e740-7f85-4a7c-ae2a-f9a8f8118e17">
|
||||
@@ -10,15 +10,17 @@
|
||||
</Script>
|
||||
<Notecard name="Notecard.txt" guid="29db291e-182f-487b-8592-789b7c7f6e0c">
|
||||
</Notecard>
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.2.lsl" guid="5bfa66b7-9929-4fa0-86ef-4640f4b51da4">
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.2.lsl" guid="b01a40c3-bb4a-4745-a0cd-2e79fcb21b44">
|
||||
</Script>
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.3.lsl" guid="eb980de4-2d95-4ba2-b8be-5d0a174ecfe0">
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.4.lsl" guid="b4b4fbe5-3c63-4afe-9122-010836bb22a0">
|
||||
</Script>
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.4.lsl" guid="605a95f5-0e57-4ccc-bffd-6ad4f8a253d3">
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.6.lsl" guid="835f8412-ec91-473b-9e64-3f09651b8490">
|
||||
</Script>
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.5.lsl" guid="acff7b7e-7041-42ef-822e-6e61ed5d3d9f">
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.8.lsl" guid="38cd026c-f41d-4350-b9ad-43010c018319">
|
||||
</Script>
|
||||
<Script name="NPC Puppeteer Recorder Script v2.3.lsl" guid="edd1d061-cd4c-4c6e-b0ac-b5b9221f5232">
|
||||
<Script name="NPC Puppeteer Recorder Script v 3.9.lsl" guid="8824d14e-4f6f-4b57-83dc-11a9a4b6afc9">
|
||||
</Script>
|
||||
<Script name="NPC Puppeteer Recorder Script v2.3.lsl" guid="958535ef-f974-4409-a898-a11aa5d6b2e2">
|
||||
</Script>
|
||||
</Object>
|
||||
<Object name="Test Object" guid="d1b532da-cdc1-4047-bde4-dc0efb10165a">
|
||||
|
||||
@@ -127,6 +127,12 @@ osSetSpeed(key NPC, float speed) {
|
||||
}
|
||||
|
||||
osNpcTouch(key NPC, key thing, integer where) {;}
|
||||
|
||||
osForceAttachToOtherAvatarFromInventory(key npc, string inventory, integer point) {
|
||||
llSay(0,"attach " + inventory + " to " + (string) point);
|
||||
}
|
||||
|
||||
|
||||
// END commented code for OpenSim vs Editor environments
|
||||
//*******************************************************************//
|
||||
// comment this out, is only here for testing in LSLEditor.
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
// :SHOW:
|
||||
// :CATEGORY:ChatBot
|
||||
// :NAME:ChatBot
|
||||
// :AUTHOR:Ferd Frederix
|
||||
// :KEYWORDS:
|
||||
// :CREATED:2014-08-11 17:28:45
|
||||
// :EDITED:2014-08-11
|
||||
// :EDITED:2015-08-28 22:27:06
|
||||
// :ID:1038
|
||||
// :NUM:1621
|
||||
// :REV:1.0
|
||||
// :WORLD:Second Life, OpenSim
|
||||
// :REV:1.1
|
||||
// :WORLD:OpenSim
|
||||
// :DESCRIPTION:
|
||||
// This chatbot is for OpenSim Only. It only works on NPC's.
|
||||
|
||||
// Rev 1.1 08-27-2015 made API use first name as the Hypergid names were too long
|
||||
|
||||
// Chatbot for PersonalityForge. Get a free account at http://www.personalityforge.com.
|
||||
// 5,000 chats are free.
|
||||
// :CODE:
|
||||
|
||||
// fiorst, get a free account at http://www.personalityforge.com.
|
||||
// Get an API ID, and add it to the apiKey :
|
||||
|
||||
string apiKey = "jkeU6Hv3tbk318wn1"; // your supplied apiKey from your Chat Bot API subscription
|
||||
string apiKey = "jkeU6Hv3tbssk318wn1"; // your supplied apiKey from your Chat Bot API subscription
|
||||
|
||||
// Add the domain *.secondlife.com or your OpenSim server IP to the list of authorized domains at http://www.personalityforge.com/botland/myapi.php
|
||||
// Add a checkmark to the "Enable Simple API" in tyour account.
|
||||
@@ -26,6 +30,8 @@ string apiKey = "jkeU6Hv3tbk318wn1"; // your supplied apiKey from your Chat B
|
||||
// Sex Bot Ciran is 100387. Type menu for choices
|
||||
// 754 is Liddora a sexy tart
|
||||
|
||||
// look at http://www.personalityforge.com/bookofapi.php for more public chat bots
|
||||
|
||||
string chatBotID = "754"; // the ID of the chat bot you're talking to
|
||||
integer greeting = TRUE; // if TRUE, say hello when anyone comes up.
|
||||
|
||||
@@ -42,7 +48,7 @@ integer debug = TRUE; // Set this TRUE to see the gory details
|
||||
|
||||
// various tuneable code bits
|
||||
float range = 15; // haw far awy an avatar is before we greet them/. No point in making this more than 20, that cannot hear us after that
|
||||
float wpm = 33; // 33 wpm = 2.75 cps @ 5 chars per word for a typical avatar to type with.
|
||||
float wpm = 50; // 33 wpm = 2.75 cps @ 5 chars per word for a typical avatar to type with.
|
||||
// Larger numbers make your NPC answer quicker.
|
||||
float cps;
|
||||
integer emotionchannel = 199; // a secret channel that the chatbot sends emotion strings on.
|
||||
@@ -147,7 +153,7 @@ default
|
||||
+ "?apiKey=" + llEscapeURL(apiKey)
|
||||
+ "&message=" + llEscapeURL(message)
|
||||
+ "&chatBotID=" + llEscapeURL(chatBotID)
|
||||
+ "&externalID=" + llEscapeURL(name)
|
||||
+ "&externalID=" + llEscapeURL(firstname)
|
||||
+ "&firstName=" + llEscapeURL(firstname)
|
||||
+ "&lastName=" + llEscapeURL(lastname)
|
||||
,[HTTP_METHOD,"GET"],"");
|
||||
|
||||
BIN
Demon Circle/Pointer.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
Demon Circle/assembled view.png
Normal file
|
After Width: | Height: | Size: 419 KiB |
BIN
Demon Circle/blue.bmp
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
Demon Circle/green.bmp
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
Demon Circle/magic circle1.jpg
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
Demon Circle/magic circle2.jpg
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
Demon Circle/orange.bmp
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
Demon Circle/purple magic circle1.bmp
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
Demon Circle/red.bmp
Normal file
|
After Width: | Height: | Size: 92 KiB |
3
NPC Attacker/NPC Attacker.sol
Normal file
@@ -0,0 +1,3 @@
|
||||
<Solution name="NPC Attacker">
|
||||
<Project name="NPC Attacker" path="NPC Attacker\NPC Attacker.prj" active="true"/>
|
||||
</Solution>
|
||||
6
NPC Attacker/NPC Attacker/NPC Attacker.prj
Normal file
@@ -0,0 +1,6 @@
|
||||
<Project name="NPC Attacker" guid="a2038eaa-43f5-4b75-8516-f38f779cf5da">
|
||||
<Object name="Object" guid="25daea0b-1e1a-4b70-a61a-7717a5e94735" active="true">
|
||||
<Script name="Script.lsl" guid="a5797ac9-ea9c-4316-96d6-ec2fe9b2a439">
|
||||
</Script>
|
||||
</Object>
|
||||
</Project>
|
||||
322
NPC Attacker/NPC Attacker/Object/Script.lsl
Normal file
@@ -0,0 +1,322 @@
|
||||
// :SHOW:
|
||||
// :CATEGORY:OpenSim NPC
|
||||
// :NAME:NPC Attacker
|
||||
// :AUTHOR:Ferd Frederix
|
||||
// :KEYWORDS:
|
||||
// :CREATED:2015-08-28 23:27:14
|
||||
// :EDITED:2015-08-28 22:27:14
|
||||
// :ID:1085
|
||||
// :NUM:1825
|
||||
// :REV:1.1
|
||||
// :WORLD:OpenSim
|
||||
// :DESCRIPTION:
|
||||
// This is a NPC attacker for Opensim. I use it in a RAM to butt people.
|
||||
// License: http://creativecommons.org/licenses/by-nc
|
||||
// :CODE:
|
||||
|
||||
// 8-1-2014 for Rambo, the attack Ram
|
||||
// 8-11-2014 make a round prim, set it to phantom, add this script. Yotouch it to record your appearance as a RAM
|
||||
// Set the prim to 4 X 4 meters and the Ram will stay ontop of it and attack anyone that steps on it.
|
||||
|
||||
integer debug = FALSE;
|
||||
key avatarKey;
|
||||
vector vRandSpot ;
|
||||
|
||||
DEBUG(string msg)
|
||||
{
|
||||
if (debug)
|
||||
llOwnerSay(msg);
|
||||
}
|
||||
|
||||
// tunables
|
||||
float max_distance; //distance for sensoring a real avatar
|
||||
string fName = "Cobra";
|
||||
string lName = "";
|
||||
float SenseTime = 10;
|
||||
integer JamTimer = 10;
|
||||
|
||||
// OS_NPC_CREATOR_OWNED will create an 'owned' NPC that will only respond to osNpc* commands issued from scripts that have the same owner as the one that created the NPC.
|
||||
// OS_NPC_NOT_OWNED will create an 'unowned' NPC that will respond to any script that has OSSL permissions to call osNpc* commands.
|
||||
integer NPCOptions = OS_NPC_CREATOR_OWNED; // only the owner of this box can control this NPC.
|
||||
integer iWaitCounter ; // 10 second attack counter
|
||||
integer iListenChannel; // dialog channel
|
||||
integer iListenHandle; // holds the listener handle;
|
||||
key kNPCKey; // npc key
|
||||
integer off = FALSE;
|
||||
string lastAnim; // thw last animation played
|
||||
vector vSensedPos ; // the last place we sensed an avatar
|
||||
vector vDestination; // where we are headed
|
||||
|
||||
// animations list
|
||||
string Stand = "SnakeStand";
|
||||
string Idle = "SnakeStand";
|
||||
string Run = "SnakeStand";
|
||||
string Walk = "SnakeWalk";
|
||||
|
||||
// Sounds
|
||||
string AttackSound = "Hiss";
|
||||
string YouLose = "sad-trombone";
|
||||
|
||||
Restart() {
|
||||
// we must have fallen down and can't get up
|
||||
|
||||
osNpcRemove((key) KeyValueGet("key"));
|
||||
|
||||
// reboot
|
||||
|
||||
Start();
|
||||
llSleep(2);
|
||||
iWaitCounter = JamTimer;
|
||||
|
||||
|
||||
}
|
||||
// this function is Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
|
||||
|
||||
string KeyValueGet(string var) {
|
||||
list dVars = llParseString2List(llGetObjectDesc(), ["&"], []);
|
||||
do {
|
||||
list data = llParseString2List(llList2String(dVars, 0), ["="], []);
|
||||
string k = llList2String(data, 0);
|
||||
if(k != var) jump continue;
|
||||
//DEBUG("got " + var + " = " + llList2String(data, 1));
|
||||
return llList2String(data, 1);
|
||||
@continue;
|
||||
dVars = llDeleteSubList(dVars, 0, 0);
|
||||
} while(llGetListLength(dVars));
|
||||
return "";
|
||||
}
|
||||
// this function is Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
|
||||
KeyValueSet(string var, string val) {
|
||||
|
||||
//DEBUG("set " + var + " = " + val);
|
||||
list dVars = llParseString2List(llGetObjectDesc(), ["&"], []);
|
||||
if(llGetListLength(dVars) == 0)
|
||||
{
|
||||
llSetObjectDesc(var + "=" + val);
|
||||
return;
|
||||
}
|
||||
list result = [];
|
||||
do {
|
||||
list data = llParseString2List(llList2String(dVars, 0), ["="], []);
|
||||
string k = llList2String(data, 0);
|
||||
if(k == "") jump continue;
|
||||
if(k == var && val == "") jump continue;
|
||||
if(k == var) {
|
||||
result += k + "=" + val;
|
||||
val = "";
|
||||
jump continue;
|
||||
}
|
||||
string v = llList2String(data, 1);
|
||||
if(v == "") jump continue;
|
||||
result += k + "=" + v;
|
||||
@continue;
|
||||
dVars = llDeleteSubList(dVars, 0, 0);
|
||||
} while(llGetListLength(dVars));
|
||||
if(val != "") result += var + "=" + val;
|
||||
llSetObjectDesc(llDumpList2String(result, "&"));
|
||||
}
|
||||
|
||||
|
||||
Play(string anima)
|
||||
{
|
||||
if (anima == lastAnim)
|
||||
return;
|
||||
|
||||
if (anima == Stand && llFrand(3) < 1)
|
||||
{
|
||||
anima = Idle;
|
||||
}
|
||||
|
||||
DEBUG(anima);
|
||||
osNpcPlayAnimation(kNPCKey,anima);
|
||||
osNpcStopAnimation(kNPCKey,lastAnim);
|
||||
lastAnim = anima;
|
||||
}
|
||||
|
||||
Sound()
|
||||
{
|
||||
if (llFrand(2) > 0.5)
|
||||
return;
|
||||
|
||||
integer n = llGetInventoryNumber(INVENTORY_SOUND);
|
||||
integer n2 = llCeil(llFrand(n));
|
||||
|
||||
string name = llGetInventoryName(INVENTORY_SOUND,n2);
|
||||
llTriggerSound(name,1.0);
|
||||
DEBUG(name);
|
||||
}
|
||||
|
||||
|
||||
GoTo(vector myPos)
|
||||
{
|
||||
DEBUG("Walk to " + (string) myPos);
|
||||
myPos.z += .5;
|
||||
|
||||
osNpcMoveToTarget(kNPCKey, myPos, OS_NPC_NO_FLY );
|
||||
}
|
||||
|
||||
float randBetween(float min, float max)
|
||||
{
|
||||
return llFrand(max - min) + min ;
|
||||
}
|
||||
|
||||
|
||||
dialog(key avi)
|
||||
{
|
||||
iListenChannel = llCeil(llFrand(5000) + 5000);
|
||||
iListenHandle = llListen(iListenChannel,"","","");
|
||||
llDialog(avi, "Choose:",["Start","Remove","Save Appearance"],iListenChannel);
|
||||
}
|
||||
|
||||
Start()
|
||||
{
|
||||
vector size = llGetScale();
|
||||
max_distance = size.x/2;
|
||||
iWaitCounter = JamTimer;
|
||||
vDestination = llGetPos();
|
||||
|
||||
|
||||
osNpcRemove((key) KeyValueGet("key"));
|
||||
llSleep(1);
|
||||
vector npcPos = llGetPos() + <0.0,0.0,1.0>;
|
||||
kNPCKey = osNpcCreate(fName,lName, npcPos, "Appearance",NPCOptions);
|
||||
KeyValueSet("key",(string) kNPCKey);
|
||||
off = FALSE;
|
||||
llSensorRepeat("", NULL_KEY, AGENT, max_distance, PI,SenseTime);
|
||||
}
|
||||
|
||||
|
||||
vector CirclePoint(float radius) {
|
||||
float x = llFrand(radius *2) - radius; // +/- radius, randomized
|
||||
float y = llFrand(radius *2) - radius; // +/- radius, randomized
|
||||
return <x, y, 0>; // so this should always happen
|
||||
}
|
||||
|
||||
|
||||
default
|
||||
{
|
||||
|
||||
state_entry()
|
||||
{
|
||||
Start();
|
||||
}
|
||||
|
||||
changed (integer what)
|
||||
{
|
||||
if (what & CHANGED_REGION_RESTART)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
on_rez(integer p)
|
||||
{
|
||||
llResetScript();
|
||||
}
|
||||
|
||||
touch_start(integer x)
|
||||
{
|
||||
if (llDetectedKey(0) == llGetOwner()) {
|
||||
dialog(llDetectedKey(0));
|
||||
}
|
||||
}
|
||||
|
||||
listen(integer channel, string name, key id, string msg) {
|
||||
llListenRemove (iListenHandle);
|
||||
if (msg == "Start")
|
||||
{
|
||||
if( off ) {
|
||||
Start();
|
||||
} else {
|
||||
llOwnerSay("Already running");
|
||||
}
|
||||
} else if (msg == "Remove") {
|
||||
off = TRUE;
|
||||
osNpcRemove((key) KeyValueGet("key"));
|
||||
llSetTimerEvent(0);
|
||||
} else if (msg == "Save Appearance") {
|
||||
osAgentSaveAppearance(llGetOwner(), "Appearance");
|
||||
llOwnerSay("Your appearance has been saved");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sensor(integer num)
|
||||
{
|
||||
DEBUG("sensed");
|
||||
|
||||
vector Dest = llDetectedPos(0);
|
||||
avatarKey = llDetectedKey(0);
|
||||
iWaitCounter = JamTimer; // 10 second attacks
|
||||
|
||||
vSensedPos = Dest; // make a backup, no trashing the 'real' Dest we will walk to
|
||||
vSensedPos.z = 0;
|
||||
|
||||
GoTo(Dest);
|
||||
llPlaySound(AttackSound,1.0);
|
||||
|
||||
llSetTimerEvent(2); // check Positions every couple of seconds
|
||||
|
||||
}
|
||||
|
||||
no_sensor()
|
||||
{
|
||||
DEBUG("noone");
|
||||
|
||||
llSetTimerEvent(0);
|
||||
|
||||
list npcPosition = llGetObjectDetails(kNPCKey,[OBJECT_POS]);
|
||||
vector vNpcPos = llList2Vector(npcPosition, 0);
|
||||
|
||||
float Distance = llVecDist(vNpcPos, vDestination ) ;
|
||||
DEBUG("Distance: " + (string) Distance);
|
||||
|
||||
if (Distance > 1.0) {
|
||||
|
||||
Play(Walk);
|
||||
DEBUG("idlectr: " + iWaitCounter);
|
||||
if (! --iWaitCounter) {
|
||||
Restart();
|
||||
}
|
||||
|
||||
} else {
|
||||
// new destination
|
||||
Play(Idle); // munchies
|
||||
vRandSpot = CirclePoint(max_distance);
|
||||
vDestination = llGetPos() + vRandSpot;
|
||||
iWaitCounter = JamTimer;
|
||||
}
|
||||
GoTo(vDestination);
|
||||
}
|
||||
|
||||
|
||||
timer()
|
||||
{
|
||||
|
||||
llPreloadSound(YouLose);
|
||||
Play(Run);
|
||||
|
||||
// we only have so many seconds to get there
|
||||
if (! --iWaitCounter) {
|
||||
Restart();
|
||||
}
|
||||
|
||||
list npcPosition = llGetObjectDetails(kNPCKey,[OBJECT_POS]);
|
||||
vector vNpcPos = llList2Vector(npcPosition, 0);
|
||||
vNpcPos.z = 0; // ignore height by using z = 0
|
||||
|
||||
list aviPosition = llGetObjectDetails(avatarKey,[OBJECT_POS]);
|
||||
vector vAviPos = llList2Vector(aviPosition, 0);
|
||||
vAviPos.z = 0; // ignore height by using z = 0
|
||||
|
||||
|
||||
if (llVecDist(vNpcPos, vAviPos ) < 1.5 ) {
|
||||
|
||||
llTriggerSound(YouLose,1.0);
|
||||
DEBUG("Dead");
|
||||
llSleep(5.0);
|
||||
llMessageLinked(LINK_SET,0,"DEAD",avatarKey);
|
||||
Play(Stand); // cancel the hot ramming action
|
||||
}
|
||||
}
|
||||
}
|
||||