This is a script for non-stackable flasks of health/mana with a set number of uses, that are automatically replenished over time. The amount of health/mana restored from is comparable to that of a greater heal potion.
Copy & paste the following script into a new text document in your favourite text editor:
// Self-Replenishing Flasks of Health/Mana
// v1.0
// by Xuri (xuri@uox3.org)
// Last Updated: 26/03/2021
//
// Give this script a unique ID in jse_fileassociations.scp, then assign the script to an object
// along with a MOREY property value of 20 (for Flask of Health) or 21 (for Flask of Mana).
// Using the flask will restore the user's health or mana, depending on which flask is used, and
// will activate a timer on the flask that will replenish 1 use (defined by AMOUNT property) every
// 30 seconds until it reaches max amount of uses. Using the flask again before the 30 seconds are
// up will restart the timer. Using up all the available uses on the flask will cause the first
// replenish timer to take twice as long.
const flaskMaxUses = 10;
const flaskReplenishTimer = 60000; // 60 seconds
function onUseChecked( pUser, iUsed )
{
var socket = pUser.socket;
if( socket && iUsed && iUsed.isItem )
{
if( pUser.isUsingPotion )
{
socket.SysMessage( GetDictionaryEntry( 430, socket.language ) ); //You must wait a while before using another potion.
socket.SysMessage( iUsed.GetTimer( 1 ));
return false;
}
//Check to see if it's locked down
if( iUsed.movable == 3 )
{
socket.SysMessage( GetDictionaryEntry( 774, socket.language ) ); //That is locked down and you cannot use it
return false;
}
if( iUsed.amount <= 0 )
{
socket.SysMessage( "This flask has no more uses left, wait for it to replenish!" );
return false;
}
switch( iUsed.morey )
{
case 20: // Flask of Health
if( pUser.health == pUser.maxhp )
{
socket.SysMessage( "You are already at full health!" );
return false;
}
pUser.health = (pUser.health + 20 + RandomNumber( 1, 20 ));
pUser.SysMessage( "You take a swig from the flask and recover some health! (" + (iUsed.amount - 1) + " uses remaining)" ); //You feel much better!
pUser.StaticEffect( 0x376A, 0x09, 0x06 );
pUser.SoundEffect( 0x01E3, true );
pUser.isUsingPotion = true;
DoTempEffect( 0, pUser, pUser, 26, 0, 0, 0 ); //Disallow immediately using another potion
break;
case 21: // Flask of Mana
if( pUser.mana == pUser.maxmana )
{
socket.SysMessage( "You are already at full mana!" );
return false;
}
pUser.mana = (pUser.mana + 20 + RandomNumber( 1, 20 ));
pUser.SysMessage( "You take a swig from the flask and recover some mana! (" + (iUsed.amount - 1) + " uses remaining)" );
pUser.StaticEffect( 0x376A, 0x09, 0x06 );
pUser.SoundEffect( 0x01E3, true );
pUser.isUsingPotion = true;
DoTempEffect( 0, pUser, pUser, 26, 0, 0, 0 ); //Disallow immediately using another potion
break;
default:
break;
}
// Reduce amount of uses left on flask on use
pUser.SoundEffect( 0x0030, true );
if( pUser.id > 0x0189 && !pUser.isonhorse )
pUser.DoAction( 0x22 );
if( iUsed.amount > 0 )
iUsed.amount--;
// Start timer to replenish flash (but kill old timers first)
iUsed.KillTimers();
if( iUsed.amount == 0 )
iUsed.StartTimer( flaskReplenishTimer * 2, 1, true ); // If empty of uses, first replenish takes longer
else
iUsed.StartTimer( flaskReplenishTimer, 1, true );
}
return false;
}
function onTimer( timerObj, timerID )
{
if( timerID == 1 && ValidateObject( timerObj ))
{
if( timerObj.amount < flaskMaxUses )
{
// Replenish flask usage by 1
timerObj.amount++;
// Start another timer to replenish it again
timerObj.StartTimer( flaskReplenishTimer, 1, true );
}
}
}
// v1.0
// by Xuri (xuri@uox3.org)
// Last Updated: 26/03/2021
//
// Give this script a unique ID in jse_fileassociations.scp, then assign the script to an object
// along with a MOREY property value of 20 (for Flask of Health) or 21 (for Flask of Mana).
// Using the flask will restore the user's health or mana, depending on which flask is used, and
// will activate a timer on the flask that will replenish 1 use (defined by AMOUNT property) every
// 30 seconds until it reaches max amount of uses. Using the flask again before the 30 seconds are
// up will restart the timer. Using up all the available uses on the flask will cause the first
// replenish timer to take twice as long.
const flaskMaxUses = 10;
const flaskReplenishTimer = 60000; // 60 seconds
function onUseChecked( pUser, iUsed )
{
var socket = pUser.socket;
if( socket && iUsed && iUsed.isItem )
{
if( pUser.isUsingPotion )
{
socket.SysMessage( GetDictionaryEntry( 430, socket.language ) ); //You must wait a while before using another potion.
socket.SysMessage( iUsed.GetTimer( 1 ));
return false;
}
//Check to see if it's locked down
if( iUsed.movable == 3 )
{
socket.SysMessage( GetDictionaryEntry( 774, socket.language ) ); //That is locked down and you cannot use it
return false;
}
if( iUsed.amount <= 0 )
{
socket.SysMessage( "This flask has no more uses left, wait for it to replenish!" );
return false;
}
switch( iUsed.morey )
{
case 20: // Flask of Health
if( pUser.health == pUser.maxhp )
{
socket.SysMessage( "You are already at full health!" );
return false;
}
pUser.health = (pUser.health + 20 + RandomNumber( 1, 20 ));
pUser.SysMessage( "You take a swig from the flask and recover some health! (" + (iUsed.amount - 1) + " uses remaining)" ); //You feel much better!
pUser.StaticEffect( 0x376A, 0x09, 0x06 );
pUser.SoundEffect( 0x01E3, true );
pUser.isUsingPotion = true;
DoTempEffect( 0, pUser, pUser, 26, 0, 0, 0 ); //Disallow immediately using another potion
break;
case 21: // Flask of Mana
if( pUser.mana == pUser.maxmana )
{
socket.SysMessage( "You are already at full mana!" );
return false;
}
pUser.mana = (pUser.mana + 20 + RandomNumber( 1, 20 ));
pUser.SysMessage( "You take a swig from the flask and recover some mana! (" + (iUsed.amount - 1) + " uses remaining)" );
pUser.StaticEffect( 0x376A, 0x09, 0x06 );
pUser.SoundEffect( 0x01E3, true );
pUser.isUsingPotion = true;
DoTempEffect( 0, pUser, pUser, 26, 0, 0, 0 ); //Disallow immediately using another potion
break;
default:
break;
}
// Reduce amount of uses left on flask on use
pUser.SoundEffect( 0x0030, true );
if( pUser.id > 0x0189 && !pUser.isonhorse )
pUser.DoAction( 0x22 );
if( iUsed.amount > 0 )
iUsed.amount--;
// Start timer to replenish flash (but kill old timers first)
iUsed.KillTimers();
if( iUsed.amount == 0 )
iUsed.StartTimer( flaskReplenishTimer * 2, 1, true ); // If empty of uses, first replenish takes longer
else
iUsed.StartTimer( flaskReplenishTimer, 1, true );
}
return false;
}
function onTimer( timerObj, timerID )
{
if( timerID == 1 && ValidateObject( timerObj ))
{
if( timerObj.amount < flaskMaxUses )
{
// Replenish flask usage by 1
timerObj.amount++;
// Start another timer to replenish it again
timerObj.StartTimer( flaskReplenishTimer, 1, true );
}
}
}
Code: Select all
5101=custom/flasks.jsNext, add the following Item definitions for flasks into a custom item .dfn file, for instance UOX3/dfndata/items/customItems.dfn:
[0x182a]
{
get=base_item
name=flask of mana
id=0x182a
value=2000 3500
weight=1000
restock=50
decay=1
pileable=0
amount=10
morey=21
good=29
script=5101
}
[0x182c]
{
get=base_item
name=flask of health
id=0x182c
value=2000 3500
weight=1000
restock=50
decay=1
pileable=0
amount=10
morey=20
good=29
script=5101
}
{
get=base_item
name=flask of mana
id=0x182a
value=2000 3500
weight=1000
restock=50
decay=1
pileable=0
amount=10
morey=21
good=29
script=5101
}
[0x182c]
{
get=base_item
name=flask of health
id=0x182c
value=2000 3500
weight=1000
restock=50
decay=1
pileable=0
amount=10
morey=20
good=29
script=5101
}
'add item 0x182a (flask of mana)
'add item 0x182c (flask of health)
You can also add the flasks to NPC shopkeeper buy/sell-lists (UOX3/dfndata/items/shoplist.dfn), or make them craftable by players (see files in UOX3/dfndata/create/).