This is a script originally written by Rais - though I've fixed it up a bit by adding some error-checking to the targeting parts, and added runebook-renaming.
Copy & paste the script into a text file which you save as (for instance) runebooks.js in your UOX3\JS\CUSTOM folder.
Then add the runebooks.js script to JSE_FILEASSOCIATIONS.SCP with a unique Script ID, and assign it to the runebooks either through the DFNs using the SCRIPT=<scriptID> tag, or using the 'SETSCPTRIG <scriptID> command ingame.
// Gump driven runebook - 95% osi style
// Rais 22nd May 02
// Contact: uox_rais@hotmail.com
// Updated by Xuri 5th February 06 (xuri@sensewave.com)
// Setup:
// Copy this file (Runebook.js) to js/custom
// Edit jse_fileassociations.scp in the js folder and add:
// 20001=js/custom/runebook.js (20001 is the script ID, can be changed but must be unique)
// Example usage:
// In game, do the following
// 'add 0xe3b (add's a book - can be ANY item)
// 'setscptrig 20001 (Set the script to run on the book)
// (if you changed the ID in scpTrig.scp, then use the ID you assigned)
// Tag's Used:
// cchar.ItemUsed holds the serial of the item used (the book)
// item.RuneBook holds the locations and other info
// item.InUsage holds the data on whether or not the book is in use by anyone
// Updates:
// 25th May 02: Recall and Gate spells added
// 26th May 02: Charges and 'New book' check
// Pack checks for Runes and scrolls
// 9th April 02: Fixed erroneous targeting, added Rename button & function, fixed up small stuff to make script work again =)
// 5th February 06: Updated redundant SpawnItem method to CreateDFNItem
// Issues:
// tItem.container.serial - is that legal? .serial shouldnt work
// checkout .serial[0-4]
// Gump buttons are 'Changing' when pressed - 3D client only
function onUseChecked( srcChar, iUsed )
{
// get users socket
var srcSock = srcChar.socket;
// is it in users pack
// If item is on ground, .container returns null. Freeks out .container.serial
if( iUsed.container == null )
iCont = 0;
else
var iCont = iUsed.container.serial; // Serial of the pack its in
var cPack = srcChar.pack.serial; // Serial of users pack
if( iCont != cPack)
iCont = false;
//Range Check
range=iUsed.InRange( srcChar, 3);
//If both range and container failed the check, then get outa here
if( iCont == false && range== false)
{
srcSock.SysMessage("You are too far away to use this.");
return false;
}
//Are we using the item allready?
//Get the serial of the item we have just used
var Serial = new Array;
Serial[0]=iUsed.GetSerial(1);
Serial[1]=iUsed.GetSerial(2);
Serial[2]=iUsed.GetSerial(3);
Serial[3]=iUsed.GetSerial(4);
//Get the stored serial from tag
var oldSerial = new Array;
var iCheck = new String(srcChar.GetTag("ItemUsed"));
var oldSerial = iCheck.split(',');
//Compare the 2, if the same, then we are allready using this item
if( iUsed.GetTag("InUsage") == 1 )
// if( Serial[0] == oldSerial[0] && Serial[1] == oldSerial[1] && Serial[2] == oldSerial[2] && Serial[3] == oldSerial[3] )
{
srcChar.SysMessage( "Someone is already already using this runebook!" );
return false;
}
else
srcChar.SetTag("ItemUsed", Serial[0] + "," + Serial[1] + "," + Serial[2] + "," + Serial[3]);
iUsed.SetTag( "InUsage", 1 );
// Make a noise as the gump opens
srcChar.SoundEffect( 0x58, false );
var myString=new String(iUsed.GetTag("RuneBook"));
var retString = displaygump (srcSock, srcChar, myString);
if (retString!=myString) //The names have changed... IE new book
iUsed.SetTag("RuneBook", retString); //Save the tag here, will then have all the 'Blank's filled in
iUsed.type=50;
return false;
}
function onGumpPress(srcSock,myButton, gumpData)
{
//Calc char
var srcChar = srcSock.currentChar;
//get the items's serial (tag from item used)
var oldSerial = new Array;
var iCheck = new String(srcChar.GetTag("ItemUsed"));
var oldSerial = iCheck.split(',');
//Convert serial into actual numbers not strings
oldSerial[0] = parseInt(oldSerial[0]);
oldSerial[1] = parseInt(oldSerial[1]);
oldSerial[2] = parseInt(oldSerial[2]);
oldSerial[3] = parseInt(oldSerial[3]);
//Find out what the item is from the serial
var iUsed=CalcItemFromSer(oldSerial[0], oldSerial[1], oldSerial[2], oldSerial[3]);
// Do range checks again - just in case they have called up the gump and done a runner
// If item is on ground, .container returns null. Freeks out .container.serial
if( iUsed.container == null )
iCont = 0;
else
var iCont = iUsed.container.serial; // Serial of the pack its in
var cPack = srcChar.pack.serial; // Serial of users pack
if( iCont != cPack)
iCont = false;
//Range Check
range=iUsed.InRange( srcChar, 3);
//If both range and container failed the check, then get outa here
if( iCont == false && range== false)
{
srcSock.SysMessage("You are too far away to use this.");
return;
}
//Get the locations again
myString=new String(iUsed.GetTag("RuneBook"));
var myBook= new Array;
var myBook = myString.split(',');
Charges=parseInt(myBook[65]);
//Button ID 0 (Cancel gump)
if(myButton==0)
{
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
iUsed.SetTag("InUsage", 0);
return;
}
//press any of the blue buttons and use a charge
if (myButton >=1 && myButton <=16)
{
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
iUsed.SetTag( "InUsage", 0 );
//Check if we have any charges
if(Charges == 0)
{
srcSock.SysMessage("This book is out of charges.");
return;
}
//Make sure we are not clicking on a 'Blank'
if(myBook[((myButton-1)*4)+1] != "Blank" )
{
//Make char move a little
srcChar.DoAction(16);
srcChar.Teleport( parseInt(myBook[((myButton-1)*4)+2]), parseInt(myBook[((myButton-1)*4)+3]), parseInt(myBook[((myButton-1)*4)+4]) );
//Removce a charge
Charges -= 1;
//Save Tag
myString=myBook[0]+","; //Book Name
for (i=0;i<=15;i++)
{
myString=myString+myBook[(i*4)+1] + "," + myBook[(i*4)+2] + "," + myBook[(i*4)+3] + "," + myBook[(i*4)+4] + ",";
}
myString=myString+Charges; //don't forget the charges
iUsed.SetTag("RuneBook", myString);
}
return;
}
//Charge book Button
if(myButton==17)
{
srcSock.CustomTarget( 1, "Select scrolls to add." );
iUsed.SetTag("InUsage", 0);
}
//Add Rune Button
if(myButton==18)
{
srcSock.CustomTarget( 0, "Select rune to add." );
iUsed.SetTag("InUsage", 0);
}
//Rename Runebook
if( myButton == 19 )
{
srcChar.SetTag( "toolser1", iUsed.GetSerial(1) );
srcChar.SetTag( "toolser2", iUsed.GetSerial(2) );
srcChar.SetTag( "toolser3", iUsed.GetSerial(3) );
srcChar.SetTag( "toolser4", iUsed.GetSerial(4) );
srcChar.SysMessage("What name do you want to give this Runebook? (50 chars max)" );
srcChar.SpeechInput(1, iUsed );
}
//myButton>100 & <115 = Remove rune button
if(myButton>=100 && myButton<=116)
{
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
iUsed.SetTag("InUsage", 0);
// Do a Pack check here - when lockdowns get implemented ppl would be able to steel runes
// If item is on ground, .container returns null. Freeks out .container.serial
if( iUsed.container == null )
iCont = 0;
else
var iCont = iUsed.container.serial; // Serial of the pack its in
var cPack = srcChar.pack.serial; // Serial of users pack
if( iCont != cPack)
{
srcSock.SysMessage("That has to be in your pack.");
return;
}
place=myButton-100;
//Anything in that location?
if(myBook[(place*4)+1]=="Blank")
return;
//Make new rune and set the location and name
//var newRune = SpawnItem( srcSock, srcChar, "0x1f14", false );
var newRune = CreateDFNItem( srcSock, srcChar, "0x1f14", 1, "ITEM", true )
newRune.morex=parseInt(myBook[(place*4)+2]);
newRune.morey=parseInt(myBook[(place*4)+3]);
newRune.morez=parseInt(myBook[(place*4)+4]);
newRune.name="A recall rune for "+myBook[(place*4)+1];
//Clear the tag entry for the location
myBook[(place*4)+1]="Blank";
myBook[(place*4)+2]=" ";
myBook[(place*4)+3]=" ";
myBook[(place*4)+4]=" ";
//do an order type thing here - don't want blanks in the middle of the book
var newBook = new Array;
var count=0;
for (i=0;i<=15;i++)
{
newBook[(i*4)+1] = "Blank";
newBook[(i*4)+2] = " ";
newBook[(i*4)+3] = " ";
newBook[(i*4)+4] = " ";
if(myBook[(i*4)+1]!="Blank")
{
newBook[(count*4)+1] = myBook[(i*4)+1];
newBook[(count*4)+2] = myBook[(i*4)+2];
newBook[(count*4)+3] = myBook[(i*4)+3];
newBook[(count*4)+4] = myBook[(i*4)+4];
count += 1;
}
}
//Re-save the tag
myString=myBook[0]+","; //Book Name
for (i=0;i<=15;i++)
{
myString=myString+newBook[(i*4)+1] + "," + newBook[(i*4)+2] + "," + newBook[(i*4)+3] + "," + newBook[(i*4)+4] + ",";
}
myString=myString+Charges; //don't forget the charges
iUsed.SetTag("RuneBook", myString);
return;
}
//Recall button
if(myButton>=120 && myButton<=135)
{
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
iUsed.SetTag( "InUsage", 0 );
place=myButton-120;
//Anything in that location?
if(myBook[(place*4)+1] == "Blank")
return;
//do we have the spell
if(srcChar.HasSpell(32) == false)
{
srcSock.SysMessage("You don't have that spell.");
return;
}
//Set the runebook's morexyz to the runes location, cast recall so player can target the book
iUsed.morex=parseInt(myBook[(place*4)+2]);
iUsed.morey=parseInt(myBook[(place*4)+3]);
iUsed.morez=parseInt(myBook[(place*4)+4]);
srcChar.CastSpell(32);
}
//Gate button
if(myButton>=140 && myButton<=155)
{
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
iUsed.SetTag( "InUsage", 0 );
place=myButton-140;
//Anything in that location?
if(myBook[(place*4)+1]=="Blank")
return;
//do we have the spell
if(srcChar.HasSpell(52) == false)
{
srcSock.SysMessage("You don't have that spell.");
return;
}
//Set the runebook's morexyz to the runes location, cast gate so player can target the book
iUsed.morex=parseInt(myBook[(place*4)+2]);
iUsed.morey=parseInt(myBook[(place*4)+3]);
iUsed.morez=parseInt(myBook[(place*4)+4]);
srcChar.CastSpell(52);
}
}
//Add Rune
function onCallback0( srcSock, myTarget )
{
//Get what char is doing this
var srcChar = srcSock.currentChar;
//What item have we targeted?
var StrangeByte = srcSock.GetWord( 1 ); //If Strangebyte is null or different than 0, it's not a dynamic object
if( StrangeByte != 0 || (StrangeByte == 0 && myTarget.isChar) )
{
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
srcChar.SysMessage( "You need to target a recall scroll." );
return;
}
//get the original items's serial (tag from item used)
var oldSerial = new Array;
var iCheck = new String(srcChar.GetTag("ItemUsed"));
var oldSerial = iCheck.split(',');
//Convert serial into actual numbers not strings
oldSerial[0] = parseInt(oldSerial[0]);
oldSerial[1] = parseInt(oldSerial[1]);
oldSerial[2] = parseInt(oldSerial[2]);
oldSerial[3] = parseInt(oldSerial[3]);
//Find out what the item is from the serial
var iUsed=CalcItemFromSer(oldSerial[0], oldSerial[1], oldSerial[2], oldSerial[3]);
//Get the locations again
myString=new String(iUsed.GetTag("RuneBook"));
var myBook= new Array;
var myBook = myString.split(',');
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
//Pack check - So we don't nick runes
// If item is on ground, .container returns null. Freeks out .container.serial
if( myTarget.container == null )
iCont = 0;
else
var iCont = myTarget.container.serial; // Serial of the pack its in
var cPack = srcChar.pack.serial; //Serial of users pack
if( iCont != cPack)
{
srcSock.SysMessage( "That has to be in your backpack." );
return;
}
// is the item of the right type?
var iID = myTarget.id;
if( iID != 0x1F14 && iID != 0x1F15 && iID != 0x1F16 && iID != 0x1F16 )
{
srcSock.SysMessage( "That is not a recall rune." );
return;
}
// Check we have a marked rune
var name = myTarget.name;
var x = myTarget.morex;
var y = myTarget.morey;
var z = myTarget.morez;
if( x == 0 && y == 0 && z == 0 )
{
srcSock.SysMessage( "That is a blank rune." );
return;
}
//Make var place HI, so if no 'Blanks' are found - we know book is full
var place=16;
//first of all, lets find a 'Blank' position in book
for(i=0; i<=16 ; i++)
{
if (myBook[(i*4)+1]=="Blank")
{
place=i;
i=17;
}
if (i==16) //Gone too far, no blanks
place=16;
}
//If place is less than 16 then we have a valid space in the book.
if (place<=15)
{
myBook[(place*4)+1]=name.substr(18,20);
myBook[(place*4)+2]=x;
myBook[(place*4)+3]=y;
myBook[(place*4)+4]=z;
//Make a new string to save
myString=myBook[0]+","; //Book Name
for (i=0;i<=15;i++)
{
myString=myString+myBook[(i*4)+1] + "," + myBook[(i*4)+2] + "," + myBook[(i*4)+3] + "," + myBook[(i*4)+4] + ",";
}
myString=myString+myBook[65]; //don't forget the charges
//Save the tag
iUsed.SetTag("RuneBook", myString);
//delete the rune
srcChar.SysMessage( "You've added a rune named "+myTarget.name+" to your Runebook." );
myTarget.Delete();
}
else
srcSock.SysMessage( "The book is full.");
}
function displaygump(srcSock, srcChar, myString)
{
//Sort out the names and locations
var myBook= new Array;
var myBook = myString.split(',');
Charges=parseInt(myBook[65]);
//Check if its a new book, if so setup name and charges
if (myBook[1]==null)
{
myBook[0]="Runebook";
//Be generous - start with 5 charges on a new book
Charges=5;
}
var myGump = new Gump;
myGump.AddPage(1);
myGump.AddGump( 0, 0, 0x898 );
//Front Page
myGump.AddButton( 25, 5, 0x9aa, 1, 0, 17 );//Charge book button
myGump.AddText( 55, 10, 0, "Charge book (" + Charges + ")");
myGump.AddButton( 25, 25, 0x9aa, 1, 0, 19 );//Rename Book button
myGump.AddText( 55, 30, 0, "Rename book");
myGump.AddButton( 189, 5, 0x9aa, 1, 0, 18 );//add rune button
myGump.AddText( 219, 10, 0, "Add rune" );
myGump.AddButton( 31, 178, 0x8b1, 0, 2, 0 );//No1 at bottom of page
myGump.AddButton( 66, 178, 0x8b2, 0, 3, 0 );
myGump.AddButton( 101, 178, 0x8b3, 0, 4, 0 );
myGump.AddButton( 136, 178, 0x8b4, 0, 5, 0 );
myGump.AddButton( 201, 178, 0x8b5, 0, 6, 0 );
myGump.AddButton( 236, 178, 0x8b6, 0, 7, 0 );
myGump.AddButton( 271, 178, 0x8b7, 0, 8, 0 );
myGump.AddButton( 306, 178, 0x8b8, 0, 9, 0 );
myGump.AddGump( 31, 178, 0x8b1 ); //Mask the button with a piccy, that way you don't see the button 'press'
myGump.AddGump( 66, 178, 0x8b2 );
myGump.AddGump( 101, 178, 0x8b3 );
myGump.AddGump( 136, 178, 0x8b4 );
myGump.AddGump( 201, 178, 0x8b5 );
myGump.AddGump( 236, 178, 0x8b6 );
myGump.AddGump( 271, 178, 0x8b7 );
myGump.AddGump( 306, 178, 0x8b8 );
myGump.AddButton( 293, 5, 0x89e, 0, 2, 0 );//Turn Page button
myGump.AddGump( 293, 5, 0x89e );
myGump.AddGump( 25, 40, 0x39 );//Draw the decoreative line under charges
myGump.AddGump( 55, 40, 0x3a );
myGump.AddGump( 71, 40, 0x3a );
myGump.AddGump( 87, 40, 0x3a );
myGump.AddGump( 103, 40, 0x3a );
myGump.AddGump( 119, 40, 0x3a );
myGump.AddGump( 129, 40, 0x3b );
myGump.AddGump( 189, 40, 0x39 );//and the same on facing page
myGump.AddGump( 219, 40, 0x3a );
myGump.AddGump( 235, 40, 0x3a );
myGump.AddGump( 251, 40, 0x3a );
myGump.AddGump( 267, 40, 0x3a );
myGump.AddGump( 283, 40, 0x3a );
myGump.AddGump( 293, 40, 0x3b );
for (i = 0; i <= 15; i++)
{
if(myBook[(i*4)+1]==null || myBook[(i*4)+1]=="Blank")
{
myBook[(i*4)+1]="Blank";
myBook[(i*4)+2]=" ";
myBook[(i*4)+3]=" ";
myBook[(i*4)+4]=" ";
var color =0;
}
else
var color=10;
bx=28; //Left offset of button (left hand page)
by=56;
tx=41; //Left offset of text (left page)
ty=52;
if (i>=8)
lhs=1; //left hand side of page
else
lhs=0;
myGump.AddButton( bx+(lhs*162), by+((i-(lhs*8))*15), 0x837, 1, 0, i+1 );
myGump.AddText(tx+(lhs*162), ty+((i-(lhs*8))*15), color, myBook[(i*4)+1]);
}
//Draw the pages
for( i = 0; i<=7; i++)
{
myGump.AddPage(i+2);
//Default stuff each page
myGump.AddGump( 0, 0, 0x898 );
myGump.AddButton( 31, 178, 0x8b1, 0, 2, 0 );
myGump.AddGump( 31, 178, 0x8b1 );
myGump.AddButton( 66, 178, 0x8b2, 0, 3, 0 );
myGump.AddGump( 66, 178, 0x8b2 );
myGump.AddButton( 101, 178, 0x8b3, 0, 4, 0 );
myGump.AddGump( 101, 178, 0x8b3 );
myGump.AddButton( 136, 178, 0x8b4, 0, 5, 0 );
myGump.AddGump( 136, 178, 0x8b4 );
myGump.AddButton( 201, 178, 0x8b5, 0, 6, 0 );
myGump.AddGump( 201, 178, 0x8b5 );
myGump.AddButton( 236, 178, 0x8b6, 0, 7, 0 );
myGump.AddGump( 236, 178, 0x8b6 );
myGump.AddButton( 271, 178, 0x8b7, 0, 8, 0 );
myGump.AddGump( 271, 178, 0x8b7 );
myGump.AddButton( 306, 178, 0x8b8, 0, 9, 0 );
myGump.AddGump( 306, 178, 0x8b8 );
myGump.AddGump( 25, 40, 0x39 );//Draw the decoreative line under charges
myGump.AddGump( 55, 40, 0x3a );
myGump.AddGump( 71, 40, 0x3a );
myGump.AddGump( 87, 40, 0x3a );
myGump.AddGump( 103, 40, 0x3a );
myGump.AddGump( 119, 40, 0x3a );
myGump.AddGump( 129, 40, 0x3b );
myGump.AddGump( 189, 40, 0x39 );//and the same on facing page
myGump.AddGump( 219, 40, 0x3a );
myGump.AddGump( 235, 40, 0x3a );
myGump.AddGump( 251, 40, 0x3a );
myGump.AddGump( 267, 40, 0x3a );
myGump.AddGump( 283, 40, 0x3a );
myGump.AddGump( 293, 40, 0x3b );
//Custom Stuff each page
myGump.AddButton( 28, 56, 0x837, 1, 0, (i*2)+1 );
myGump.AddButton( 190, 56, 0x837, 1, 0, (i*2)+2 );
if( myBook[((i*2)*4)+1]=="Blank")
var color =0;
else
var color=10;
myGump.AddText(41, 52, color, myBook[((i*2)*4)+1]);
if( myBook[((i*2)*4)+5]=="Blank")
var color =0;
else
var color=10;
myGump.AddText(203, 52, color, myBook[((i*2)*4)+5]);
myGump.AddText(43,67,0,myBook[((i*2)*4)+2] + " "+ myBook[((i*2)*4)+3] + " " + myBook[((i*2)*4)+4] ); //XYZ Position
myGump.AddText(205,67,0,myBook[((i*2)*4)+6] + " "+ myBook[((i*2)*4)+7] + " " + myBook[((i*2)*4)+8] ); //XYZ Position
myGump.AddButton( 35, 110, 0x985,1,0,(100+(i*2))); // Drop rune
myGump.AddText(45,110,0,"Drop Rune");
myGump.AddButton( 193, 110, 0x985,1,0,(100+(i*2)+1));
myGump.AddText(203,110,0,"Drop Rune");
if (i <= 6) //don't want the next page button on the last page, only previuos page button
{
myGump.AddButton( 293, 5, 0x89e, 0, i+3, 0 );//Turn Page button
myGump.AddGump( 293, 5, 0x89e );
}
myGump.AddButton( 25, 5, 0x89d, 0, i+1, 0 );//Turn Page button
myGump.AddGump( 25, 5, 0x89d );
myGump.AddButton( 35, 130, 0x8df, 1, 0, (120+(i*2)) );//Recall Button
myGump.AddGump( 35, 130, 0x8df );
myGump.AddButton( 110, 130, 0x8f3, 1, 0, (140+(i*2)) );//Gate Button
myGump.AddGump( 110, 130, 0x8f3 );
myGump.AddButton( 193, 130, 0x8df, 1, 0, (120+(i*2))+1 );//Recall Button
myGump.AddGump( 193, 130, 0x8df );
myGump.AddButton( 268, 130, 0x8f3, 1, 0, (140+(i*2))+1 );//Gate Button
myGump.AddGump( 268, 130, 0x8f3 );
}
myGump.Send( srcSock );
//When drawing the gump, we check for NULL's in the names, we change them to blanks
//Remake string so it can be saved to a tag
myString=myBook[0]+","; //Book Name
for (i=0;i<=15;i++)
{
myString=myString+myBook[(i*4)+1] + "," + myBook[(i*4)+2] + "," + myBook[(i*4)+3] + "," + myBook[(i*4)+4] + ",";
}
myString=myString+Charges; //don't forget the charges
return myString;
}
//Charge Book
function onCallback1( srcSock, myTarget )
{
//Get what char is doing this
var srcChar = srcSock.currentChar;
//What item have we targeted?
var StrangeByte = srcSock.GetWord( 1 ); //If Strangebyte is null or different than 0, it's not a dynamic object
if( StrangeByte != 0 || (StrangeByte == 0 && myTarget.isChar) )
{
//Clear the tag
srcChar.SetTag("ItemUsed", "0,0,0,0");
srcChar.SysMessage( "You need to target a recall scroll." );
return;
}
//get the original items's serial (tag from item used)
var oldSerial = new Array;
var iCheck = new String(srcChar.GetTag("ItemUsed"));
var oldSerial = iCheck.split(',');
//Convert serial into actual numbers not strings
oldSerial[0] = parseInt(oldSerial[0]);
oldSerial[1] = parseInt(oldSerial[1]);
oldSerial[2] = parseInt(oldSerial[2]);
oldSerial[3] = parseInt(oldSerial[3]);
//Find out what the item is from the serial
var iUsed=CalcItemFromSer(oldSerial[0], oldSerial[1], oldSerial[2], oldSerial[3]);
//Get the locations again
myString=new String(iUsed.GetTag("RuneBook"));
var myBook= new Array;
var myBook = myString.split(',');
Charges=parseInt(myBook[65]);
//Pack check - So we don't nick scrolls
// If item is on ground, .container returns null. Freeks out .container.serial
if( myTarget.container == null )
iCont = 0;
else
var iCont = myTarget.container.serial; // Serial of the pack its in
var cPack = srcChar.pack.serial; //Serial of users pack
if( iCont != cPack)
{
srcSock.SysMessage( "That has to be in your backpack." );
return;
}
// is the item of the right type?
var iID = myTarget.id;
if( iID != 0x1F4c )
{
srcSock.SysMessage( "That is not a recall scroll." );
return;
}
//Get how many is in pile we targeted
tAmount = myTarget.amount;
//How many do we need to fill the book (max 10 charges)
ChargesRequired = 10 - Charges;
if (ChargesRequired>=tAmount)
{
Charges += tAmount; //If there are less scrolls then required then use um all
myTarget.Delete();
}
else
{
Charges=10;
myTarget.amount -= ChargesRequired; //More than enouth, then just use what we need
}
//Save the tag
myString=myBook[0]+","; //Book Name
for (i=0;i<=15;i++)
{
myString=myString+myBook[(i*4)+1] + "," + myBook[(i*4)+2] + "," + myBook[(i*4)+3] + "," + myBook[(i*4)+4] + ",";
}
myString=myString+Charges; //don't forget the charges
iUsed.SetTag("RuneBook", myString);
}
function onSpeechInput(pUser, iUsed, pSpeech, pSpeechID)
{
iUsed.SetTag("InUsage", 0);
if(pSpeech == null || pSpeech == " ")
{
pUser.SysMessage( "That name is too short, or no name was entered." );
return;
}
switch(pSpeechID)
{
case 1: //Rename Runebook
if( pSpeech.length > 50 )
{
pUser.SysMessage( "That name is too long. Maximum 50 chars." );
return;
}
iUsed.name = pSpeech;
pUser.SysMessage("The new name of the Runebook is: "+iUsed.name );
break;
}
}