|
Osiris TechnologyOsiris Technology offers the latest low lag, high performance sim management technology for Second Life. Our first product offering, the Osiris Roleplay Combat System, is rapidly becoming the hottest roleplaying system in Second Life. Latest NewsIntroducing OsirisThank you to Neon Serge for suggesting the name we eventually went with: Osiris. You'll see some changes on the website in the next few days, and the next update (v 0.75) will bear the new Osiris CS name. Because we plan in the long run to go much further than a combat system, this one fits very nicely! Congrats Neon and thank you! Alphabet Soup and Working TitlesAs we approach version 1.0 of RPCS, it's time to start seriously thinking about a name.
Ranged Weapons API Ready with release of 0.73With the release of 0.73 this morning, the ranged weapons API is now available to developers. Most of this works exactly the same as melee procs, with a couple of changes, in particular the addition of the bullet name. Note: this script does _not_ go in the bullets. Rather it goes in the actual gun/attachment, and ideally should be integrated with your main script in whatever way is most convenient for you. Set initial variableskey gCreatorKey="your key goes here"; string bulletname; string gObjectName="Your weapon's object name here"; string gAPIType="R"; string gAPIRace="ALL"; string gPartDur="0"; string gTPart="0"; string gTPartDur="0"; string gCheckURL="http://sl.rpcombat.com/APIcheck.cfm"; integer gAvatarChannel; string gPass; key http_request_id; integer initialHUDChannel = -39485739; integer initialHUDListener; Next step is put in the functions:
string crypt(string str){
return llXorBase64StringsCorrect(llStringToBase64(str),llStringToBase64(gPass));
}
string decrypt(string str){
return llBase64ToString(llXorBase64StringsCorrect(str,llStringToBase64(gPass)));
}
getChannel()
{
http_request_id=llHTTPRequest(gCheckURL + "?cKey=" + llEscapeURL(gCreatorKey) + "&obn=" + llEscapeURL(gObjectName) + "&crKe=" + llEscapeURL(llGetCreator()) + "&scKey=" + llEscapeURL(llGetInventoryCreator(llGetScriptName())), [],"");
}
doProc(key target)
{
string msg="V||" + (string)target + "^" + gAPIType + "|" + gAPIRace + "|" + gEffectedStat + "|" + gEmote + "|" + gVicEmote + "|" + gPart + "|" + gPartDur + "|" + gTPart + "|" + gTPartDur;
llRegionSay(gAvatarChannel, crypt(msg));
}
In the body of your script, you're going to start with setting the listener for the meter. This only accepts two commands: RESET or RPCS... the purpose here is for you to be able to confirm the player is wearing RPCS before you register your weapon. In the listen event, we call the getChannel() function when a reset happens
state_entry() {
initialHUDListener=llListen(initialHUDChannel, "", "", "");
llSay(initialHUDChannel, "QUERY|RPCS");
}
listen(integer channel,string name,key id,string message) {
if (channel==initialHUDChannel) {
if (llGetOwnerKey(id)==llGetOwner()) {
if (message=="RPCS" || message=="RPCS|RESET") {
getChannel();
}
}
}
}
The getChannel() function called above will return an http response. We deal with that here:
http_response(key id,integer h_status,list meta,string body) {
if (h_status==200)
{
llOwnerSay(body);
list response=llCSV2List(llStringTrim(body, STRING_TRIM));
if (llList2String(response, 0)=="MSG") {
llOwnerSay(llList2String(response, 1));
} else if (llList2String(response, 0)=="GO") {
gAvatarChannel=llList2Integer(response, 1);
gPass=llStringTrim(llList2String(response, 2), STRING_TRIM);
bulletname=llStringTrim(llList2String(response, 3), STRING_TRIM);
llMessageLinked(LINK_SET, 3959492, bulletname, NULL_KEY);
}
}
}
Note the last two lines of this which are quite different than the melee test script. First, we set a bullet name, then pass that out via linked message. You can do this however you want to... the main thing is you need to be able to set a global variable in your main script with the bulletname text. We'll see why in just a moment. Next step is to know when to tell the meter we are enhanced. The easiest way is to have your script send a linked message when the weapon is drawn (in this example, we're sending a linked message with the num 4242 to tell the API script it needs to be sending to the meter now. That way, the the meter is ready to deal out enhanced commands the moment you are combat ready. That said, we don't want to be sending it constantly. Put it on a timer... send the proc to the meter every 30 seconds... then when the weapon is put away, kill the timer. Sending the command to the meter
link_message(integer linknum, integer num, string str, key id) {
if (num==4242) {doProc(NULL_KEY); llSetTimerEvent(30.0);}
else if (num==4343) {llSetTimerEvent(0.0);}
}
timer () {
doProc(NULL_KEY);
}
At this point what's happening is your gun is telling the meter: "my bullets are enhanced." The meter is telling everyone around you ... that your bullets are enhanced. The problem is: they aren't yet. There's one final step that has to be taken. Setting the bullet nameThe way this works is pretty simple. At this point, because you've sent the enhancement information to the meter, and it has communicated with your neighbors, your victims are ready to be shot. Except how will they know the bullet came from your enhanced weapon, and not a freebie popgun you pick up somewhere. Here's how. Remember earlier where we set the bulletname variable and sent it to the rest of the object via linked request? Here it is again: bulletname=llStringTrim(llList2String(response, 3), STRING_TRIM); llMessageLinked(LINK_SET, 3959492, bulletname, NULL_KEY); The reason for this is because the enemy's meter will give enhanced damage _if_ your meter sent out the signal (see above) and _if_ the bullet name matches. When you rez your bullet, you're going to send an integer to it matching the desired bullet name:
llRezObject("bullet", pos, vel, rot, (integer)bulletname);
Your bullet should grab that variable on rez, then llSetObjectName((string)bulletname); So... if your bullet name matches, then each bullet you send downrange will do an extra +2 points of damage. Announcing the first API Enhanced RPCS Weapon
Melee Weapon Example ScriptThe first section of your script should set specific variables as follows: key gCreatorKey="place your API key here"; string gObjectName="Place the unique name of this weapon here"; string gAPIType="M"; string gEffectedStat="Z"; string gAPIRace="ALL"; string gEmote="%a hits %d over the head"; string gVicEmote="%d cringes in pain"; string gPart="0"; string gPartDur="0"; string gTPart="0"; string gTPartDur="0"; gEffectedStat="Z"; string gCheckURL="http://sl.rpcombat.com/APIcheck.cfm"; integer gAvatarChannel; string gPass; key http_request_id; integer bulletname; //ignored for melee integer initialHUDChannel = -39485739; integer initialHUDListener;These are the the default options for a melee weapon script. Insert your own license key and an object name you select in the first two fields. Other options included here:
string crypt(string str){
return llXorBase64StringsCorrect(llStringToBase64(str),llStringToBase64(gPass));
}
string decrypt(string str){
return llBase64ToString(llXorBase64StringsCorrect(str,llStringToBase64(gPass)));
}
getChannel()
{
http_request_id=llHTTPRequest(gCheckURL + "?cKey=" + llEscapeURL(gCreatorKey) + "&obn=" + llEscapeURL(gObjectName) + "&crKe=" + llEscapeURL(llGetCreator()) + "&scKey=" + llEscapeURL(llGetInventoryCreator(llGetScriptName())), [],"");
}
doProc(key target)
{
string msg="V||" + (string)target + "^" + gAPIType + "|" + gAPIRace + "|" + gEffectedStat + "|" + gEmote + "|" + gVicEmote + "|" + gPart + "|" + gPartDur + "|" + gTPart + "|" + gTPartDur;
llRegionSay(gAvatarChannel, crypt(msg));
}
In State_entry() we're going to to do one thing: query to find out if the owner has an RPCS meter, and open a listener on a known channel for a response. The purpose of this is that there is no point in licensing an enhanced weapon for someone who is not wearing the meter.
state_entry() {
initialHUDListener=llListen(initialHUDChannel, "", "", "");
llRegionSay(initialHUDChannel, "QUERY|RPCS");
}
listen(integer channel,string name,key id,string message) {
if (channel==initialHUDChannel) {
if (llGetOwnerKey(id)==llGetOwner()) {
if (message=="RPCS" || message=="RPCS|RESET") {
getChannel();
}
}
}
}
Note that your listener on the default known channel is looking for two things: an acknowledgement that we are wearing RPCS, or a reset command. Any time you get either one of those, you call the getChannel function which will retreive the avatar channel and encryption key. Next we handle the http response, assigning a avatar specific channel to communicate with the owner, and an encryption password. Note that RPCS uses individual unique channels for each wearer: your API script will only be able to communicate with the owner of the weapon. Everything else is handled by the meter.
http_response(key id,integer h_status,list meta,string body) {
if (h_status==200)
{
list response=llCSV2List(llStringTrim(body, STRING_TRIM));
if (llList2String(response, 0)=="MSG") {
llOwnerSay(llList2String(response, 1));
} else if (llList2String(response, 0)=="GO") {
gAvatarChannel=llList2Integer(response, 1);
gPass=llStringTrim(llList2String(response, 2), STRING_TRIM);
}
}
}
Finally we tell the meter that this is an enhanced weapon. I'm doing this on restart/relog and when the weapon is drawn by sending a linked message to the API script. Note that the meter will not retain indefinately that you are using an enhanced weapon: you have to _resend_ the proc every 300 seconds. I stop it from sending the command when the weapon is sheathed by sending a linked message with num 4343, then on drawing the weapon send 4242 and start the timer again.
link_message(integer linknum, integer num, string str, key id) {
if (num==4242) {doProc(NULL_KEY); llSetTimerEvent(300);}
else if (num==4343) {llSetTimerEvent(0.0);}
}
timer () {
doProc(NULL_KEY);
}
Feel free to grab a test key from the Content Creators section on the website and test it out!
|
Second Life and the inSL logo are trademarks of Linden Research, Inc. Osiris Technology is not affiliated with or sponsored by Linden Research. |
|