// Wandering Healer
// v1.00
// by Xuri (xuri@sensewave.com)
// The Wandering Healer-script will let any character it's attached to, heal and resurrect wounded/dead players, as
// well as heal him/her-self in the process, if wounded. (Also a chance to heal him/her-self if in combat)
// By default it's setup to function as a wandering healer-script, but customization is easy.
// Will not heal/res criminals or murderers
// DON'T CHANGE THIS VALUE:
var i = 0;
// searchAmount = Number of times healer will look around for chars to heal/resurrect before stopping
// searchInterval = The interval at wihch the healer looks around for chars to heal/resurrect after having started searching
// searchRange = The radius in which the healer searches for wounded people
// searchTimer = Amount of time between each time the healer initiates his searches
// resTimer = Minimum time that must pass before healer will resurrect same char again (1000 = 1 second)
// healTimer = Minimum time that must pass before healer will heal same char again (1000 = 1 second)
// manaCostHeal = the amount of mana the NPC uses for healing
// manaCostRes = the amount of mana the NPC uses for resurrecting
var searchAmount = 3;
var searchInterval = 5000;
var searchRange = 4;
var searchTimer = 15000;
var resTimer = 30000;
var healTimer = 30000;
var manaCostHeal = 11;
var manaCostRes = 50;
// These variables can be customized or commented out if you don't want to use them
var healSoundFX = 0x01f2;
var healGFXEffect = 0x376A;
var resSoundFX = 0x376A;
var resGFXEffect = 0x376A;
// These messages can be customized. If you don't want to use them at all, comment them out
var healMsgPositive = "Thou hast been healed. Mayest thou stay healthy.";
var healMsgNegative = "Thou hast been healed too recently. Try again later.";
var resMsgPositive = "Thou hast been resurrected. Now STAY alive!";
var resMsgNegative = "Thou hast been resurrected too recently. Try again later.";
var criminalReply = "Thou art a criminal and I will not assist thee!";
var outOfManaMsg = "I have no mana left! Try again later...";
var startSearchEmote = "*looks around for someone to heal*";
var endSearchEmote = "*shrugs and goes back to wandering*";
var healSelfEmote = "*heals self*";
function inRange( pCharacter, objInRange )
{
if( objInRange.isChar )
{
// Get the current server clock, and if it exists, the time for when the last search was started
// Compare the two, and the script will see if enough time has passed to initiate a new search
// This also ensures that the script stays working even if the server saves in the middle of a
// search, but crashes before the next save.
var iTime = GetCurrentClock();
var initSearchTime = pCharacter.GetTag( "initSearchTime" );
//If search has already been initiated, don't start a new search, unless an abnormal amount of time has passed
if(( initSearchTime != null && initSearchTime != 0 ) && ((( iTime - initSearchTime ) < searchTimer ) && !( initSearchTime > iTime )))
return;
else if((( iTime - initSearchTime ) > searchTimer ) || initSearchTime > iTime )
{
pCharacter.SetTag( "initSearchTime", iTime );
if( startSearchEmote )
pCharacter.EmoteMessage( startSearchEmote );
pCharacter.StartTimer( searchInterval, 1, true );
}
}
}
// This triggers the keyword-based healing/resurrection
function onSpeech( strSaid, pTalking, npcHealer )
{
if( strSaid == "heal" )
{
if( pTalking.dead )
doRes( pTalking, npcHealer );
else if( pTalking.health < pTalking.maxhp )
doHeal( pTalking, npcHealer );
}
return false;
}
// This is the general function for healing characters
function doHeal( woundedChar, npcHealer )
{
if( !woundedChar.criminal && !woundedChar.murderer )
{
if( npcHealer.mana > manaCostHeal )
{
var iTime = GetCurrentClock();
var lastHealTime = woundedChar.GetTag( "lastHealTime" );
if(( lastHealTime == null || lastHealTime == 0 ) || ((( iTime - lastHealTime ) > healTimer ) || ( lastHealTime > iTime )))
{
woundedChar.health = woundedChar.maxhp;
woundedChar.StaticEffect( healGFXEffect, 0, 15 );
woundedChar.SoundEffect( healSoundFX, true );
woundedChar.SetTag( "lastHealTime", iTime );
npcHealer.mana-= manaCostHeal;
if( healMsgPositive )
npcHealer.TextMessage( healMsgPositive );
return;
}
else
{
if( healMsgNegative )
npcHealer.TextMessage( healMsgNegative );
return;
}
}
else
{
if( outOfManaMsg )
npcHealer.TextMessage( outOfManaMsg );
return;
}
}
else
{
if( criminalReply )
npcHealer.TextMessage( criminalReply );
return;
}
}
// This is the general function for resurrecting characters
function doRes( deadChar, npcHealer )
{
if( !deadChar.criminal && !deadChar.murderer )
{
if( npcHealer.mana > manaCostRes )
{
var iTime = GetCurrentClock();
var lastResTime = deadChar.GetTag( "lastResTime" );
if(( lastResTime == null || lastResTime == 0 ) || ((( iTime - lastResTime ) > resTimer ) || ( lastResTime > iTime )))
{
deadChar.Resurrect();
deadChar.SetTag( "lastResTime", iTime );
npcHealer.mana-= manaCostRes;
if( resMsgPositive )
npcHealer.TextMessage( resMsgPositive );
return;
}
else
{
if( resMsgNegative )
npcHealer.TextMessage( resMsgNegative );
return;
}
}
else
{
if( outOfManaMsg )
npcHealer.TextMessage( outOfManaMsg );
return;
}
}
else
{
if( criminalReply )
npcHealer.TextMessage( criminalReply );
return;
}
}
// Gives the healer a chance to heal himself any time damage is done towards him
function onDefense( pAttacker, pDefender )
{
var iNum = RandomNumber( 0, 1000 );
if( iNum > 700 )
{
if( pDefender.health < pDefender.maxhp )
{
if( pDefender.mana > manaCostHeal )
{
pDefender.health = pDefender.maxhp;
pDefender.mana-= manaCostHeal;
pDefender.StaticEffect( 0x376A, 0, 15 );
pDefender.SoundEffect( 0x01f2, true );
if( healSelfEmote )
pDefender.EmoteMessage( healSelfEmote );
}
}
}
}
function onTimer( srcChar, timerID )
{
if( timerID == 1 )
{ //Search for nearby wounded characters the specified amount of times
if( i < searchAmount )
{
AreaCharacterFunction( "searchForWounded", srcChar, searchRange );
srcChar.StartTimer( searchInterval, 1, true );
i++;
}
else
{
i = 0;
if( endSearchEmote )
srcChar.EmoteMessage( endSearchEmote );
}
}
}
//This function iterates through all characters within the specified radius in AreaCharacterFunction
//It then checks to make sure they are valid for receiving healing or resurrection.
function searchForWounded( srcChar, trgChar, pSock )
{
if( trgChar.serial != srcChar.serial )
{
if( trgChar.dead )
doRes( trgChar, srcChar );
else if( trgChar.health < trgChar.maxhp )
doHeal( trgChar, srcChar );
}
else
{
if( srcChar.health < srcChar.maxhp )
{
if( srcChar.mana > manaCostHeal )
{
srcChar.health = srcChar.maxhp;
srcChar.mana-= manaCostHeal;
srcChar.StaticEffect( 0x376A, 0, 15 );
srcChar.SoundEffect( 0x01f2, true );
if( healSelfEmote )
srcChar.EmoteMessage( healSelfEmote );
}
}
}
}
// v1.00
// by Xuri (xuri@sensewave.com)
// The Wandering Healer-script will let any character it's attached to, heal and resurrect wounded/dead players, as
// well as heal him/her-self in the process, if wounded. (Also a chance to heal him/her-self if in combat)
// By default it's setup to function as a wandering healer-script, but customization is easy.
// Will not heal/res criminals or murderers
// DON'T CHANGE THIS VALUE:
var i = 0;
// searchAmount = Number of times healer will look around for chars to heal/resurrect before stopping
// searchInterval = The interval at wihch the healer looks around for chars to heal/resurrect after having started searching
// searchRange = The radius in which the healer searches for wounded people
// searchTimer = Amount of time between each time the healer initiates his searches
// resTimer = Minimum time that must pass before healer will resurrect same char again (1000 = 1 second)
// healTimer = Minimum time that must pass before healer will heal same char again (1000 = 1 second)
// manaCostHeal = the amount of mana the NPC uses for healing
// manaCostRes = the amount of mana the NPC uses for resurrecting
var searchAmount = 3;
var searchInterval = 5000;
var searchRange = 4;
var searchTimer = 15000;
var resTimer = 30000;
var healTimer = 30000;
var manaCostHeal = 11;
var manaCostRes = 50;
// These variables can be customized or commented out if you don't want to use them
var healSoundFX = 0x01f2;
var healGFXEffect = 0x376A;
var resSoundFX = 0x376A;
var resGFXEffect = 0x376A;
// These messages can be customized. If you don't want to use them at all, comment them out
var healMsgPositive = "Thou hast been healed. Mayest thou stay healthy.";
var healMsgNegative = "Thou hast been healed too recently. Try again later.";
var resMsgPositive = "Thou hast been resurrected. Now STAY alive!";
var resMsgNegative = "Thou hast been resurrected too recently. Try again later.";
var criminalReply = "Thou art a criminal and I will not assist thee!";
var outOfManaMsg = "I have no mana left! Try again later...";
var startSearchEmote = "*looks around for someone to heal*";
var endSearchEmote = "*shrugs and goes back to wandering*";
var healSelfEmote = "*heals self*";
function inRange( pCharacter, objInRange )
{
if( objInRange.isChar )
{
// Get the current server clock, and if it exists, the time for when the last search was started
// Compare the two, and the script will see if enough time has passed to initiate a new search
// This also ensures that the script stays working even if the server saves in the middle of a
// search, but crashes before the next save.
var iTime = GetCurrentClock();
var initSearchTime = pCharacter.GetTag( "initSearchTime" );
//If search has already been initiated, don't start a new search, unless an abnormal amount of time has passed
if(( initSearchTime != null && initSearchTime != 0 ) && ((( iTime - initSearchTime ) < searchTimer ) && !( initSearchTime > iTime )))
return;
else if((( iTime - initSearchTime ) > searchTimer ) || initSearchTime > iTime )
{
pCharacter.SetTag( "initSearchTime", iTime );
if( startSearchEmote )
pCharacter.EmoteMessage( startSearchEmote );
pCharacter.StartTimer( searchInterval, 1, true );
}
}
}
// This triggers the keyword-based healing/resurrection
function onSpeech( strSaid, pTalking, npcHealer )
{
if( strSaid == "heal" )
{
if( pTalking.dead )
doRes( pTalking, npcHealer );
else if( pTalking.health < pTalking.maxhp )
doHeal( pTalking, npcHealer );
}
return false;
}
// This is the general function for healing characters
function doHeal( woundedChar, npcHealer )
{
if( !woundedChar.criminal && !woundedChar.murderer )
{
if( npcHealer.mana > manaCostHeal )
{
var iTime = GetCurrentClock();
var lastHealTime = woundedChar.GetTag( "lastHealTime" );
if(( lastHealTime == null || lastHealTime == 0 ) || ((( iTime - lastHealTime ) > healTimer ) || ( lastHealTime > iTime )))
{
woundedChar.health = woundedChar.maxhp;
woundedChar.StaticEffect( healGFXEffect, 0, 15 );
woundedChar.SoundEffect( healSoundFX, true );
woundedChar.SetTag( "lastHealTime", iTime );
npcHealer.mana-= manaCostHeal;
if( healMsgPositive )
npcHealer.TextMessage( healMsgPositive );
return;
}
else
{
if( healMsgNegative )
npcHealer.TextMessage( healMsgNegative );
return;
}
}
else
{
if( outOfManaMsg )
npcHealer.TextMessage( outOfManaMsg );
return;
}
}
else
{
if( criminalReply )
npcHealer.TextMessage( criminalReply );
return;
}
}
// This is the general function for resurrecting characters
function doRes( deadChar, npcHealer )
{
if( !deadChar.criminal && !deadChar.murderer )
{
if( npcHealer.mana > manaCostRes )
{
var iTime = GetCurrentClock();
var lastResTime = deadChar.GetTag( "lastResTime" );
if(( lastResTime == null || lastResTime == 0 ) || ((( iTime - lastResTime ) > resTimer ) || ( lastResTime > iTime )))
{
deadChar.Resurrect();
deadChar.SetTag( "lastResTime", iTime );
npcHealer.mana-= manaCostRes;
if( resMsgPositive )
npcHealer.TextMessage( resMsgPositive );
return;
}
else
{
if( resMsgNegative )
npcHealer.TextMessage( resMsgNegative );
return;
}
}
else
{
if( outOfManaMsg )
npcHealer.TextMessage( outOfManaMsg );
return;
}
}
else
{
if( criminalReply )
npcHealer.TextMessage( criminalReply );
return;
}
}
// Gives the healer a chance to heal himself any time damage is done towards him
function onDefense( pAttacker, pDefender )
{
var iNum = RandomNumber( 0, 1000 );
if( iNum > 700 )
{
if( pDefender.health < pDefender.maxhp )
{
if( pDefender.mana > manaCostHeal )
{
pDefender.health = pDefender.maxhp;
pDefender.mana-= manaCostHeal;
pDefender.StaticEffect( 0x376A, 0, 15 );
pDefender.SoundEffect( 0x01f2, true );
if( healSelfEmote )
pDefender.EmoteMessage( healSelfEmote );
}
}
}
}
function onTimer( srcChar, timerID )
{
if( timerID == 1 )
{ //Search for nearby wounded characters the specified amount of times
if( i < searchAmount )
{
AreaCharacterFunction( "searchForWounded", srcChar, searchRange );
srcChar.StartTimer( searchInterval, 1, true );
i++;
}
else
{
i = 0;
if( endSearchEmote )
srcChar.EmoteMessage( endSearchEmote );
}
}
}
//This function iterates through all characters within the specified radius in AreaCharacterFunction
//It then checks to make sure they are valid for receiving healing or resurrection.
function searchForWounded( srcChar, trgChar, pSock )
{
if( trgChar.serial != srcChar.serial )
{
if( trgChar.dead )
doRes( trgChar, srcChar );
else if( trgChar.health < trgChar.maxhp )
doHeal( trgChar, srcChar );
}
else
{
if( srcChar.health < srcChar.maxhp )
{
if( srcChar.mana > manaCostHeal )
{
srcChar.health = srcChar.maxhp;
srcChar.mana-= manaCostHeal;
srcChar.StaticEffect( 0x376A, 0, 15 );
srcChar.SoundEffect( 0x01f2, true );
if( healSelfEmote )
srcChar.EmoteMessage( healSelfEmote );
}
}
}
}