From f33e37ac06d052d91ee85e8a31d6f65a4672e2f7 Mon Sep 17 00:00:00 2001 From: Xoduz Date: Sun, 17 Oct 2021 08:08:19 +0800 Subject: [PATCH] Updated onSkillGain, onSkillLoss and onSkillChange JS events Updated onSkillGain, onSkillLoss and onSkillChange JS events: Additional parameters now supported by events - skillGainAmount and skillLossAmount onSkillGain( player, skillID, skillGainAmount ) // skillGainAmount is always positive onSkillLoss( player, skillID, skillLossAmount ) // skillLossAmount is always positive onSkillChange( player, skillID, skillChangeAmount ) // skillChangeAmount can be negative or positive The return value from onSkillGain and onSkillLoss events can now be used to control behavior: return true - skill gain/loss is allowed, and server will go through with the skill update return false - skill gain/loss is not allowed, and server will prevent the skill update, but will not block additional scripts with same event from running onSkillChange will now run as long as onSkillGain or onSkillLoss events return true, and if those events are not defined Updated JS Docs --- docs/jsdocs/events.html | 55 ++++++++++++----------- docs/jsdocs/updates.html | 8 +++- source/Changelog.txt | 12 +++++ source/cScript.cpp | 51 +++++++++++++--------- source/cScript.h | 6 +-- source/skills.cpp | 94 +++++++++++++++++++++++++++++++++------- 6 files changed, 162 insertions(+), 64 deletions(-) diff --git a/docs/jsdocs/events.html b/docs/jsdocs/events.html index da0971acc..61c364776 100644 --- a/docs/jsdocs/events.html +++ b/docs/jsdocs/events.html @@ -51,7 +51,7 @@ tChar.DoAction( 111 ); When pAttacker attacks pDefender (in each "round" of combat) NotespAttacker's script is activated, and pDefender's onDefense event is fired! PurposeFlesh out the attacking code. -Example of Usage
function onAttack( pAttacker, pDefender )
{
pAttacker.TextMessage( "Who lives in that castle?" );
pDefender.TextMessage( "Help! Help! I'm being repressed!" );
} +Example of Usage
function onAttack( pAttacker, pDefender )
{
pAttacker.TextMessage( "Who lives in that castle?" );
pDefender.TextMessage( "Help! Help! I'm being repressed!" );
}
@@ -258,7 +258,7 @@ If script is attached to a character, will also trigger when the AllNames macro
When triggeredWhen an item or char is created. Note that for PCs, this is triggered when they first enter the world. NotesobjType == 0 indicates an item
objType == 1 indicates a character PurposeUsed for customization of players at creation, or tinkering items/chars when they're made. -Example of Usage
function onCreate( objMade, objType )
+Example of Usage
function onCreateDFN( objMade, objType )
 {
 	if( objType == 1 )
 		objMade.SysMessage( "Welcome to Our Unique World(TM)!" );
@@ -273,7 +273,7 @@ If script is attached to a character, will also trigger when the AllNames macro
 
When triggeredWhen a non-DFN based item is created. NotesobjType == 0 indicates an item
objType == 1 indicates a character PurposeUsed for customization of non-DFN based items at creation. -Example of Usage
function onCreate( objMade, objType )
+Example of Usage
function onCreateTile( objMade, objType )
 {
 	objMade.name = "A renamed item";
 }
@@ -374,7 +374,7 @@ function onDecay( iDecaying )
 NotespDefender's script fires, pAttacker's onAttack event is also fired
 
 PurposeFlesh out the attacking code.
-Example of Usage
function onDefense( pAttacker, pDefender )
{
pAttacker.TextMessage( "Who lives in that castle?" );
pDefender.TextMessage( "Help! Help! I'm being repressed!" );
} +Example of Usage
function onDefense( pAttacker, pDefender )
{
pAttacker.TextMessage( "Who lives in that castle?" );
pDefender.TextMessage( "Help! Help! I'm being repressed!" );
}
@@ -1044,13 +1044,16 @@ function onSkill( objUsing, skillUsed, objType )

 

onSkillChange -
Prototype
function onSkillChange( pPlayer, skill )
-
When triggeredThis is fired if onSkillLoss isn't defined for skill loss, or onSkillGain isn't defined for skill gain. -
Notes  -
PurposeAllows you to take action when your skill level changes -
Example of Usage
function onSkillChange( pPlayer, skill )
+
Prototype
function onSkillChange( pPlayer, skill, skillChangeAmount )
+
When triggeredThis event is fired if onSkillLoss or onSkillGain return true, or if those events are not defined. If the events returned false, onSkillChange will not trigger. +
Notes +
PurposeAllows you to take action when your skill level changes (positively or negatively) +
Example of Usage
function onSkillChange( pPlayer, skill, skillChangeAmount )
 {
-	pPlayer.TextMessage( pPlayer, "Oh dear, my skill's changed" );
+	if( skillChangeAmount > 0 )
+		pPlayer.TextMessage( "Oh wow, I've gained some points in skill number " + skill + "!" );
+	else
+		pPlayer.TextMessage( "Oh noes, I've lost some points in skill number " + skill + "!" );
 }
 
@@ -1058,7 +1061,7 @@ function onSkill( objUsing, skillUsed, objType ) onSkillCheck Prototype
function onSkillCheck( pUser, skillID, lowSkill, highSkill )
 
When triggeredTriggers for character with event attached when a skillcheck is performed -Notes Runs just prior to skillcheck. Returning true will allow skillcheck to take place, but will also prevent any other scripts with same event from running. +NotesRuns just prior to skillcheck. Returning true will allow skillcheck to take place, but will also prevent any other scripts with same event from running. PurposeFor taking additional action when skillchecks are performed. Example of Usage
function onSkillCheck( pUser, skillID, lowSkill, highSkill )
 {
@@ -1069,25 +1072,27 @@ function onSkill( objUsing, skillUsed, objType )
 
 

 

onSkillGain -
Prototype
function onSkillGain( pPlayer, skill )
-
When triggeredwhen pPlayer gains in skill skill -
Notes  -
PurposeFor taking actions when you gain skill. -
Example of Usage
function onSkillGain( pPlayer, skill )
+
Prototype
function onSkillGain( pPlayer, skill, skillGainAmount )
+
When triggeredJust before pPlayer gains points in skill +
Notes +
PurposeAllows preventing or taking special action before skill gain takes place +
Example of Usage
function onSkillGain( pPlayer, skill, skillGainAmount )
 {
-	pPlayer.TextMessage("Wheee! I've gained some skill!");
+	pPlayer.TextMessage( "Aww, I was about to gain " + ( skillGainAmount / 10 ) + " points in skill number " + skill + ", but got denied!" );
+	return false;
 }
 

 

onSkillLoss -
Prototype
function onSkillLoss( pPlayer, skill )
-
When triggeredWhen pPlayer loses in skill skill -
Notes  -
PurposeFor doing something when you lose skill -
Example of Usage
function onSkillLoss( pPlayer, skill )
+
Prototype
function onSkillLoss( pPlayer, skill, skillLossAmount )
+
When triggeredJust before pPlayer loses points in skill +
Notes +
PurposeAllows preventing or taking special action before skill loss takes place +
Example of Usage
function onSkillLoss( pPlayer, skill, skillLossAmount )
 {
-	pPlayer.TextMessage( "Oh no, I've lost skill!" );
+	pPlayer.TextMessage( "Phew, I was about to lose " + ( skillLossAmount / 10 ) + " points in skill number " + skill + ", but it didn't happen!" );
+	return false;
 }
 
@@ -1095,7 +1100,7 @@ function onSkill( objUsing, skillUsed, objType ) onSkillGump Prototype
function onSkillGump( pUser )
 
When triggeredWhen pUser tries opening the skill-gump -Notes  +Notes PurposeFor overriding the client's request to open the default skillgump. Return false to prevent opening default skillgump, or true to allow. Example of Usage
function onSkillGump( pUser )
 {
@@ -1138,7 +1143,7 @@ function onSkill( objUsing, skillUsed, objType )
 PurposeTo allow for behavioural change on snooping behaviour.
 Example of Usage
function onSnooped( pSnooped, pSnooping, bSuccess )
 {
-	pSnooped.TextMessage( "Oi! You! Stop snooping!" );
+	pSnooped.TextMessage( "Oi! You! Stop snooping!" );
 }
 
diff --git a/docs/jsdocs/updates.html b/docs/jsdocs/updates.html index 8595da5b1..2fd089391 100644 --- a/docs/jsdocs/updates.html +++ b/docs/jsdocs/updates.html @@ -12,12 +12,18 @@

UOX3 Script Engine

Functions, Methods, Properties and Event handling

-

Revision History - Last Update: 20 Sept 2021

+

Revision History - Last Update: 17 Oct 2021

+ + + +
Version Change
0.59 + Events Updated onCreateDFN, onCreateTile, onSkillGain, onSkillLoss, onSkillChange
+
0.58 diff --git a/source/Changelog.txt b/source/Changelog.txt index c9b7d9982..17c6ca5da 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,15 @@ +17/10/2021 - Xuri + Updated onSkillGain, onSkillLoss and onSkillChange JS events: + Additional parameters now supported by events - skillGainAmount and skillLossAmount + onSkillGain( player, skillID, skillGainAmount ) // skillGainAmount is always positive + onSkillLoss( player, skillID, skillLossAmount ) // skillLossAmount is always positive + onSkillChange( player, skillID, skillChangeAmount ) // skillChangeAmount can be negative or positive + The return value from onSkillGain and onSkillLoss events can now be used to control behavior: + return true - skill gain/loss is allowed, and server will go through with the skill update + return false - skill gain/loss is not allowed, and server will prevent the skill update, but will not block additional scripts with same event from running + onSkillChange will now run as long as onSkillGain or onSkillLoss events return true, and if those events are not defined + Updated JS Docs + 12/10/2021 - Dragon Slayer Healing someone with bandages now unhides player Updated calculations for duration it takes to heal self/another target, and for the amount of health healed diff --git a/source/cScript.cpp b/source/cScript.cpp index 0dd132b68..84d59668f 100644 --- a/source/cScript.cpp +++ b/source/cScript.cpp @@ -748,27 +748,32 @@ bool cScript::OnDefense( CChar *attacker, CChar *defender ) } //o-----------------------------------------------------------------------------------------------o -//| Function - bool OnSkillGain( CChar *player, SI08 skill ) +//| Function - SI08 OnSkillGain( CChar *player, SI08 skill, UI32 skillGainAmount ) //o-----------------------------------------------------------------------------------------------o //| Purpose - Triggers for character with event attached when gaining skillpoints //o-----------------------------------------------------------------------------------------------o -bool cScript::OnSkillGain( CChar *player, SI08 skill ) +SI08 cScript::OnSkillGain( CChar *player, SI08 skill, UI32 skillGainAmount ) { - if( !ValidateObject( player ) ) - return false; + const SI08 RV_NOFUNC = -1; + if( !ValidateObject( player )) + return RV_NOFUNC; if( !ExistAndVerify( seOnSkillGain, "onSkillGain" ) ) - return false; + return RV_NOFUNC; - jsval params[2], rval; + jsval params[3], rval; JSObject *charObj = JSEngine->AcquireObject( IUE_CHAR, player, runTime ); params[0] = OBJECT_TO_JSVAL( charObj ); params[1] = INT_TO_JSVAL( skill ); - JSBool retVal = JS_CallFunctionName( targContext, targObject, "onSkillGain", 2, params, &rval ); + params[2] = INT_TO_JSVAL( skillGainAmount ); + JSBool retVal = JS_CallFunctionName( targContext, targObject, "onSkillGain", 3, params, &rval ); if( retVal == JS_FALSE ) + { SetEventExists( seOnSkillGain, false ); + return RV_NOFUNC; + } - return ( retVal == JS_TRUE ); + return TryParseJSVal( rval ); } //o-----------------------------------------------------------------------------------------------o @@ -1738,45 +1743,51 @@ bool cScript::OnStatChange( CChar *player, UI32 stat ) } //o-----------------------------------------------------------------------------------------------o -//| Function - bool OnSkillLoss( CChar *player, SI08 skill ) +//| Function - SI08 OnSkillLoss( CChar *player, SI08 skill, UI32 skillLossAmount ) //o-----------------------------------------------------------------------------------------------o //| Purpose - Triggers for characters with event attached when losing skillpoints //o-----------------------------------------------------------------------------------------------o -bool cScript::OnSkillLoss( CChar *player, SI08 skill ) +SI08 cScript::OnSkillLoss( CChar *player, SI08 skill, UI32 skillLossAmount ) { - if( !ValidateObject( player ) ) - return false; + const SI08 RV_NOFUNC = -1; + if( !ValidateObject( player )) + return RV_NOFUNC; if( !ExistAndVerify( seOnSkillLoss, "onSkillLoss" ) ) - return false; + return RV_NOFUNC; - jsval params[2], rval; + jsval params[3], rval; JSObject *charObj = JSEngine->AcquireObject( IUE_CHAR, player, runTime ); params[0] = OBJECT_TO_JSVAL( charObj ); params[1] = INT_TO_JSVAL( skill ); - JSBool retVal = JS_CallFunctionName( targContext, targObject, "onSkillLoss", 2, params, &rval ); + params[2] = INT_TO_JSVAL( skillLossAmount ); + JSBool retVal = JS_CallFunctionName( targContext, targObject, "onSkillLoss", 3, params, &rval ); if( retVal == JS_FALSE ) + { SetEventExists( seOnSkillLoss, false ); + return RV_NOFUNC; + } - return ( retVal == JS_TRUE ); + return TryParseJSVal( rval ); } //o-----------------------------------------------------------------------------------------------o -//| Function - bool OnSkillChange( CChar *player, SI08 skill ) +//| Function - bool OnSkillChange( CChar *player, SI08 skill, SI32 skillChangeAmount ) //o-----------------------------------------------------------------------------------------------o //| Purpose - Triggers for characters with event attached when skillpoints change //o-----------------------------------------------------------------------------------------------o -bool cScript::OnSkillChange( CChar *player, SI08 skill ) +bool cScript::OnSkillChange( CChar *player, SI08 skill, SI32 skillChangeAmount ) { if( !ValidateObject( player ) ) return false; if( !ExistAndVerify( seOnSkillChange, "onSkillChange" ) ) return false; - jsval params[2], rval; + jsval params[3], rval; JSObject *charObj = JSEngine->AcquireObject( IUE_CHAR, player, runTime ); params[0] = OBJECT_TO_JSVAL( charObj ); params[1] = INT_TO_JSVAL( skill ); - JSBool retVal = JS_CallFunctionName( targContext, targObject, "onSkillChange", 2, params, &rval ); + params[2] = INT_TO_JSVAL( skillChangeAmount ); + JSBool retVal = JS_CallFunctionName( targContext, targObject, "onSkillChange", 3, params, &rval ); if( retVal == JS_FALSE ) SetEventExists( seOnSkillChange, false ); diff --git a/source/cScript.h b/source/cScript.h index 61687ebb0..752e16d52 100644 --- a/source/cScript.h +++ b/source/cScript.h @@ -179,9 +179,9 @@ public: std::string OnTooltip( CBaseObject *myObj ); bool OnAttack( CChar *attacker, CChar *defender ); bool OnDefense( CChar *attacker, CChar *defender ); - bool OnSkillGain( CChar *player, SI08 skill ); - bool OnSkillLoss( CChar *player, SI08 skill ); - bool OnSkillChange( CChar *player, SI08 skill ); + SI08 OnSkillGain( CChar *player, SI08 skill, UI32 skillAmtGained ); + SI08 OnSkillLoss( CChar *player, SI08 skill, UI32 skillAmtLost ); + bool OnSkillChange( CChar *player, SI08 skill, SI32 skillAmtChanged ); bool OnStatGained( CChar *player, UI32 stat, SI08 skill ); bool OnStatGain( CChar *player, UI32 stat, SI08 skill ); bool OnStatLoss( CChar *player, UI32 stat ); diff --git a/source/skills.cpp b/source/skills.cpp index 719b1a43d..0e1237b6b 100644 --- a/source/skills.cpp +++ b/source/skills.cpp @@ -918,18 +918,40 @@ void cSkills::HandleSkillChange( CChar *c, UI08 sk, SI08 skillAdvance, bool succ if( success ) amtToGain = cwmWorldState->skill[sk].advancement[skillAdvance].amtToGain; UI16 skillCap = cwmWorldState->ServerData()->ServerSkillTotalCapStatus(); + bool updateSkill = true; if( c->IsNpc() ) { - c->SetBaseSkill( c->GetBaseSkill( sk ) + amtToGain, sk ); - + // Check for existence of onSkillGain event for NPC for( auto scriptTrig : scriptTriggers ) { cScript *toExecute = JSMapping->GetScript( scriptTrig ); if( toExecute != nullptr ) { - if( !toExecute->OnSkillGain( c, sk ) ) - toExecute->OnSkillChange( c, sk ); + // If retVal is -1, event doesn't exist in script + // If retVal is 0, event exists, but returned false/0, and handles item usage. Don't proceed with hard code (or other scripts!) + // If retVal is 1, event exists, proceed with hard code/other scripts + if( !toExecute->OnSkillGain( c, sk, amtToGain ) ) + { + updateSkill = false; + return; + } + } + } + + if( updateSkill ) + { + // Increase base skill of NPC + c->SetBaseSkill( c->GetBaseSkill( sk ) + amtToGain, sk ); + + // Check for existence of onSkillChange event for NPC + for( auto scriptTrig : scriptTriggers ) + { + cScript *toExecute = JSMapping->GetScript( scriptTrig ); + if( toExecute != nullptr ) + { + toExecute->OnSkillChange( c, sk, amtToGain ); + } } } return; @@ -976,36 +998,78 @@ void cSkills::HandleSkillChange( CChar *c, UI08 sk, SI08 skillAdvance, bool succ { if( toDec != 0xFF ) { - totalSkill -= amtToGain; - c->SetBaseSkill( c->GetBaseSkill( toDec ) - amtToGain, toDec ); - + // Check for existence of onSkillLoss event for player for( auto scriptTrig : scriptTriggers ) { cScript *toExecute = JSMapping->GetScript( scriptTrig ); if( toExecute != nullptr ) { - if( !toExecute->OnSkillLoss( c, toDec ) ) - toExecute->OnSkillChange( c, toDec ); + // If retVal is -1, event doesn't exist in script + // If retVal is 0, event exists, but returned false/0, and handles item usage. Don't proceed with hard code (or other scripts!) + // If retVal is 1, event exists, proceed with hard code/other scripts + if( !toExecute->OnSkillLoss( c, toDec, amtToGain ) ) + { + updateSkill = false; + return; + } } } - mSock->updateskill( toDec ); + + if( updateSkill ) + { + // Reduce base skill of player + totalSkill -= amtToGain; + c->SetBaseSkill( c->GetBaseSkill( toDec ) - amtToGain, toDec ); + + // Check for existence of onSkillChange event for player + for( auto scriptTrig : scriptTriggers ) + { + cScript *toExecute = JSMapping->GetScript( scriptTrig ); + if( toExecute != nullptr ) + { + toExecute->OnSkillChange( c, toDec, ( amtToGain * -1 )); + } + } + mSock->updateskill( toDec ); + } } } if( skillCap > static_cast(totalSkill) ) { - c->SetBaseSkill( c->GetBaseSkill( sk ) + amtToGain, sk ); - + // Check for existence of onSkillGain event for player for( auto scriptTrig : scriptTriggers ) { cScript *toExecute = JSMapping->GetScript( scriptTrig ); if( toExecute != nullptr ) { - if( !toExecute->OnSkillGain( c, sk ) ) - toExecute->OnSkillChange( c, sk ); + // If retVal is -1, event doesn't exist in script + // If retVal is 0, event exists, but returned false/0, and handles item usage. Don't proceed with hard code (or other scripts!) + // If retVal is 1, event exists, proceed with hard code/other scripts + if( !toExecute->OnSkillGain( c, sk, amtToGain ) ) + { + updateSkill = false; + break; + } } } - mSock->updateskill( sk ); + + if( updateSkill ) + { + // Increase base skill of player + c->SetBaseSkill( c->GetBaseSkill( sk ) + amtToGain, sk ); + + // Check for existence of onSkillChange event for player + for( auto scriptTrig : scriptTriggers ) + { + cScript *toExecute = JSMapping->GetScript( scriptTrig ); + if( toExecute != nullptr ) + { + toExecute->OnSkillChange( c, sk, amtToGain ); + } + } + mSock->updateskill( sk ); + } } }