Aller au contenu

Photo

Could use a lil help with a few scripts.


  • Veuillez vous connecter pour répondre
35 réponses à ce sujet

#1
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Hey all,
I have gotten a ton of help in the past from alot of you here on the boards, so I thought I would see if I could pick you all's brains a bit more? I have a few scripts I could use some help with, and would welcome any input. I will start with my current top priority.

We have tried 2 different ways at modifying defensive stance. This is the second attempt I will post first as if we can get this to work it would be much better than my first attempt. The idea behind this is that you use an object to use one of you DDDS uses per day, and it fires this script which gives the DD a HP boost based of DD level and Con modifier, in addition to 5% immunity to all dmg types per 10 DD levels. It works beautifully, but the problem is for some reason I have not been able to figure out it just stops working randomly (I can not figure out the exact conditions that cause this), and will not work again until the server is restarted. Any ideas about why this is happening, and how to fix it would be appreciated.

Thanks, Laz

#include "x2_i0_spells"
//#include "core_inc_post40"
void main()
{
  if(!GetUserDefinedItemEventNumber() == X2_ITEM_EVENT_ACTIVATE) return;
  object oPC = GetItemActivator();
  if(!GetHasFeat(FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE, oPC)) return;
  if(GetLocalInt(oPC, "DD") == TRUE)
  {
     FloatingTextStringOnCreature("Still in cool down", oPC, FALSE);
     return;
  }
  PlayVoiceChat(VOICE_CHAT_BATTLECRY1, oPC);
  int nclassLevel = GetLevelByclass(class_TYPE_DWARVENDEFENDER, oPC);
  int nPercent = nclassLevel/10 *5;
  int nHP = (nclassLevel + GetAbilityModifier(ABILITY_CONSTITUTION, oPC)) *10;
  effect eVis = EffectVisualEffect(VFX_DUR_AURA_PULSE_RED_YELLOW);
  effect eLink = EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, nPercent);
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_ELECTRICAL, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_POSITIVE, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_SLASHING, nPercent));
  eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_SONIC, nPercent));
  eLink = EffectLinkEffects(eLink, eVis);
  effect eHP = EffectTemporaryHitpoints(nHP);
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oPC, 60.0);
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eHP, oPC, 60.0);
  DecrementRemainingFeatUses(oPC, FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE);
  SetLocalInt(oPC, "DD", TRUE);
  DelayCommand(60.0, DeleteLocalInt(oPC, "DD"));


#2
Xardex

Xardex
  • Members
  • 217 messages
It most likely is happening because for some reason your DelayCommand is interrupted. When server restarts, local ints from characters are wiped. This is why I decided not to use delay command but instead this:

"mod_time" - Name of the script, you can use whatever you like

// Returns current server time in seconds
int Time();

int Time()
{
    int iTime;
    int iH = FloatToInt(HoursToSeconds(1))/60; // Amount of minutes per hour
    iTime -= GetLocalInt(GetModule(), "time_zero");
    iTime += GetTimeSecond();
    iTime += GetTimeMinute()*60;
    iTime += GetTimeHour()*iH*60;
    iTime += GetCalendarDay()*24*iH*60;
    iTime += GetCalendarMonth()*28*24*iH*60;
    iTime += GetCalendarYear()*12*28*24*iH*60;
    return iTime;
}


Should be self explanatory. Put this to your module load event:
( And remember to include "mod_time" )

SetLocalInt(OBJECT_SELF, "time_zero", Time());


Now you can easily add cooldowns for any feats or items by including "mod_time" and doing this (using your script as example):

SetLocalInt(oPC, "DD", Time()+60;

And when you check for cooldown:

if (Time() < GetLocalInt(oPC, "DD")){}


One more thing... Remember to add the cooldowns always to something where they dont persist over server restarts, or they might not work as expected.



EDIT

Wait a moment...!
Can someone tell me will this overflow if year is 2220 or higher? (assuming iH is the default 2)
[ Unless im totally wrong... Doesn't nwn assign 32 bits for its ints? ]

Now that im thinking about it, I could remove the calendar year and it should work anytime... But then I would need to add a pseudo heartbeat with a delay of a YEAR to remove cooldowns. Or just assume a server restarts at least once every 11 days. Hmm. Im dumb. Moving 1 line to fix it. Bleeding my thoughts here....

The script should work fine now.:whistle:

I guess it could fail if module calendar year is advanced by over 2220 years after server has started running... But I'll consider that an acceptable flaw.
<_<

Modifié par Xardex, 21 septembre 2011 - 10:18 .


#3
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Thank you for the suggestion Xardex. I will try that, if I can't get it to work as is, but couldn't I just remove the set/delete local interger functions if this is what is causing the problem? Since the buff only last one minute anyways, is it even necessary to have that?

#4
Axe_Murderer

Axe_Murderer
  • Members
  • 279 messages
You should probably ensure that should the percent computation come up zero, you don't apply all those effects.

Also you could simplify that computation from x/10 *5 to x/2.

You might also consider turning on the cooldown even when they don't have the feat.

#5
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Not exactly sure what you mean Axe. The point is to apply all those effects (granted at only 5% per 10 DD lvls).

Wouldn't x/2 make it 5% per 2 DD lvls? That's not quite what we are going for.

If they dont have the feat, the cool down timer is irrelavant. In fact I am not too concerned about it in general. If a player wants to use all his/her DS in one shot (stacking) to become immune for one min, it's not a big deal. There is a 10 min rest timer on Av3, so that will leave them hard up for the other 9 min...

#6
Axe_Murderer

Axe_Murderer
  • Members
  • 279 messages
(x/10)*5 == (x*5)/10 == x*(5/10) == x*(1/2) == x/2
its the same thing just less math for the cpu to do...one division rather than both a division and a mult.
percent will end up always being half their DD level...which equates to 1% every 2 levels, 5% every 10.

There is however an integer division in there so if you're level 9 DD then percent will be zero if you do x/10*5 because 9/10 == 0 in integer math and that will get evaluated before the mult...maybe you wanted that, I was assuming you didn't. That's why I mentioned not applying the effects when it's zero.

Modifié par Axe_Murderer, 22 septembre 2011 - 11:13 .


#7
the.gray.fox

the.gray.fox
  • Members
  • 127 messages
Hello.

Lazarus Magni wrote...

[...] The idea behind this is that you use an object to use one of you DDDS uses per day, and it fires this script which [...]


Can this object used to activate the DDDS expire
or be depleted, or otherwise be destroyed?
Would you reveal its exact nature, just so we are sure?


Anyway...
Barring the possibility that a 2nd script somewhere is secretly
SetlocalInt() "DD" on the PC, I too believe that the issued
DelayCommand() is being canceled.

But the exact why... I can not tell.
OBJECT_SELF therein is the Module -- right?


A workaround would be to AssignCommand() the DelayCommand()
to DeleteLocalInt() to the very PC. As the PC is constantly
around and constantly granted a high CPU slice, it is
guaranteed to carry it out.
(If this too fails, then you _do_ have a 2nd script interfering)


But your problem is worth investigation.
The Module, being indestructible, is not supposed to ever
drop any DelayCommand() issued to it.
Something sneaky is being at work here, you see.
I would run your script as-is for some time with a debug
output to state when the SetLocalInt() DeleteLocalInt() has been successfully
run (a wrapper function will do).
That should help you catch the "when" it stops working and,
from there, pin down the why.


-fox

Modifié par the.gray.fox, 22 septembre 2011 - 10:03 .


#8
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Thanks for your responses. My apologies Axe, I should probably look at what the variable is before trying to interpret an equation. Indeed you'er correct, although I believe the original intent of the /10 was to make it so DDs only got this bonus every 10 levels. The more I think on it I like the 1% every 2 levels better so I will change it to that.

Fox, the object is an unlimited use per day cast spell unique power self only item. It can not be depleted. I believe your on to something here though, I noticed in the log right before it stops working this occurs:
[Thu Sep 22 03:21:26] [Location] Clearing LastCDKey for Player Driptin Dasterly

I am looking at the on client enter script and I see there are quite a few delayed commands, deleting local integers (although not this one specifically.) Like this portion of the on client enter script:
 //Remove all uses for usable feats
      if ( GetLocalInt( GetModule( ), sName + "_losefeatsuses" ))
      {
        for( nFeat = 0; nFeat <= MAX_FEATS; ++nFeat )
        {
          if( GetHasFeat( nFeat, oPC ))
          {
            for( i = 0; i <= 20; ++i )
            {
              DecrementRemainingFeatUses( oPC, nFeat );
            }
          }
        }
                //Clean up local variable to free up memory
        DeleteLocalInt( GetModule( ), sName + "_logged" );
        DeleteLocalInt( GetModule( ), sName + "_hp" );
        DeleteLocalInt( GetModule( ), sName + "_losefeatsuses" );
        for ( nSpell = 0; nSpell <= MAX_SPELLS; ++nSpell )
        {
          DeleteLocalInt( GetModule( ), sName + "_Spell_" + IntToString( nSpell ) + "_" );
        }

Could this be causing the problem?

Modifié par Lazarus Magni, 22 septembre 2011 - 10:17 .


#9
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
What you could do, is put the effect creation and application into a subroutine assigned to the wand, then check to see if the player has an effect created by that item instead of using a variable. It would be slightly less efficient processor wise, but there'd be no chance of the error you're getting now that way.

#10
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Can you elaborate on that concept FB? I am not sure if I am understanding what you are saying. Keep in mind I am not a scripter...

#11
Failed.Bard

Failed.Bard
  • Members
  • 774 messages

Lazarus Magni wrote...

Can you elaborate on that concept FB? I am not sure if I am understanding what you are saying. Keep in mind I am not a scripter...


Something like this:

// In a seperate routine so the creation of the affects can be applied by the
// creator of choice.
void ApplyDDEffects (object oPC);

// Checks to see if oTarget has an effect created by oCreator
int GetHasEffectByCreator (object oTarget, object oCreator);

void main()
{
 // Include bypassing event activation check.
 if (GetLocalInt(OBJECT_SELF,"X2_L_LAST_ITEM_EVENT") != 0) return;
 // if(!GetUserDefinedItemEventNumber() == X2_ITEM_EVENT_ACTIVATE) return; 

 object oPC = GetItemActivator();
 object oItem = GetItemActivated();

 if (!GetHasFeat(FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE, oPC))
    {
     FloatingTextStringOnCreature ("You have no uses of this feat left.", oPC, FALSE);
     return;
    }
 if (GetHasEffectByCreator (oPC, oItem))
    {
     FloatingTextStringOnCreature("Feat still in cool down.", oPC, FALSE);
     return;
    }

// By moving the effect declarations to an assigned subscript, you can control
// what object creates the effect in order to compare against it later.
AssignCommand (oItem, ApplyDDEffects (oPC));
}

void ApplyDDEffects (object oPC)
{
 PlayVoiceChat(VOICE_CHAT_BATTLECRY1, oPC);
 int nclassLevel = GetLevelByclass(class_TYPE_DWARVENDEFENDER, oPC);
 int nPercent = nclassLevel/10 *5;
 int nHP = (nclassLevel + GetAbilityModifier(ABILITY_CONSTITUTION, oPC)) *10;

 effect eHP = EffectTemporaryHitpoints(nHP);
 effect eVis = EffectVisualEffect(VFX_DUR_AURA_PULSE_RED_YELLOW);
 
 effect eLink = EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, nPercent);
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_ELECTRICAL, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_POSITIVE, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_SLASHING, nPercent));
 eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_SONIC, nPercent));
 eLink = EffectLinkEffects(eLink, eVis);
 
 ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oPC, 60.0);
 ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eHP, oPC, 60.0);
 DecrementRemainingFeatUses(oPC, FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE);
}

int GetHasEffectByCreator (object oTarget, object oCreator)
{
 effect eEffect = GetFirstEffect (oTarget);
 while (GetIsEffectValid (eEffect))
    {
     if (GetEffectCreator (eEffect) == oCreator) return TRUE;
     eEffect = GetNextEffect (oTarget);
    }
return FALSE;
}



Whatever object is running the script at the time the effect is created gets stored with the effect. Since it's the module originally running the script, it's better to assign the creation of the effect to an object that won't be making any other effects to check against.

Edited to add the formatting back in.  The "class" alterations you'll have to fix yourself after copying.  It's just something these boards do.

Modifié par Failed.Bard, 22 septembre 2011 - 10:46 .


#12
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Just so I am clear, so this is one script, that would replace the existing one? I am still fairly unfamilar with the scripting vanacular, and in this instance "a seperate routine" is confusing me. By that you just meant an additional routine within the existing script, and not a seperate script correct? Also, not sure what you mean about the formating... Is there something specific in the formating here on the boards that needs to be changed in the actual script?

#13
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
The formatting is just for readability. Aside from it changing "class" to always be small case within the scripts, it's not really a negative change removing it, it's just that little bit harder for others to read through to look at without the indenting and spacings intended.

These lines will need fixing though:

int nclassLevel = GetLevelByclass(class_TYPE_DWARVENDEFENDER, oPC);
int nPercent = nclassLevel/10 *5;
int nHP = (nclassLevel + GetAbilityModifier(ABILITY_CONSTITUTION, oPC)) *10;

I tried editing them to get class_TYPE_* and nclassLevel to post with the capital letters in "class", but it keeps making them all small case.


as for the scripts themselves, those three scripts would all go within the items script as a complete replacement for the original, if you wanted to try/use them.

I'm not really that good at explaining scripts, I might have used the wrong terms. void main() is the primary script, and under a tag based system will be called on any item event.
If it's an item activation event, it then checks for the remaining feats, and the new check to see if there's an effect on the user created by the item. If it passes both those checks, it calls the new sub-routine, which assigns the item as the effect creator to check against the next time the item is used.

#14
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Thank you very much FB, for the script, and the clarification/explaination. I really appreciate it. So I take it I don't need the include from the original script?

Edit: Got it to compile. I will test this, and report back my findings.

Modifié par Lazarus Magni, 22 septembre 2011 - 11:44 .


#15
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Well on initial testing this looks great Failed Bard, thank you so much! It will require some more extensive testing live to be sure, but so far haven't experienced the bug once yet. Thank you again, and thank you also to everyone who offered their input, ideas, and help. Cheers you all! This is a much needed boost for DDs on my mod.

#16
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Hmm well this worked great testing locally, but now that it is live on the server, once again it stops working after a short while. This is the last server message I got before it stopped working:
[Thu Sep 22 19:49:32] [Location] Clearing LastCDKey for Player Driptin Dasterly
My best guess is it has something to do with the module load event, or the oncliententer event clearing something, but I am really clueless at this point.

#17
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
Does the item activate still, but the "feat" won't fire, or is the script itself not getting called anymore when the item is used? If the item isn't activating at all, it might be something is altering the tag based scripting module switch set in the on module load script.

#18
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
I am not sure how to determine this? When it stops working, from the players perspective, I am getting the use item animation, however it does nothing. It doesn't send me a message about feat is still in cool down, or anything. It simply seems to do nothing. I can still use the regular version of DS normally, but using the item just ceases to work untill the server is restarted again.

#19
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
BTW this is our onmoduleload script event. After looking at this I see I should probably comment out the lines about nwnx_weapons, since that is a linux plugin we arent currently using, but I am guessing that is irrelevant to the current issue at hand. Still nonetheless, here is our current module load event in case it gives you any ideas...:

//Aventia onmonload.nss
// Name : Avlis Persistence System OnModuleLoad
// Purpose : Initialize APS on module load event
// Authors : Ingmar Stieger
// Modified : January 27, 2003

// This file is licensed under the terms of the
// GNU GENERAL PUBLIC LICENSE (GPL) Version 2

// wys_e_modload - Executed upon the module loading
#include "aps_include"
#include "wys_i_common"
#include "wys_i_booze"
#include "x2_inc_switches"
#include "x2_inc_restsys"

#include "conf_module"
#include "pf_msg_util"
#include "pf_autosave"
#include "pc_export_inc"

#include "nwnx_weapons"

void ClearRecentRestart( )
{
WriteTimestampedLogEntry( "[Location] Clearing RecentRestart Flag" );
DeleteLocalInt( GetModule( ), "RecentRestart" );

string sSQL = "TRUNCATE " + MODULE_PC_LOCATION_TABLE;
SQLExecDirect( sSQL );
}

void main()
{
//Edit by Kenquinn 12-9-2010
//Added in the new shifter fix's auto save system
pc_export_onmoduleload();
//Edit by Kenquinn 12-10-2010
//Addes in changes to dev crit via nwnx_weapons
// Edited 06/30/11 by Laz to disable auto kill for all
SetWeaponOption(NWNX_WEAPONS_OPT_DEVCRIT_DISABLE_ALL, TRUE);
SetWeaponOption(NWNX_WEAPONS_OPT_DEVCRIT_MULT_BONUS, 1);
SetWeaponOption(NWNX_WEAPONS_OPT_DEVCRIT_MULT_STACK, TRUE);
SetWeaponOption(NWNX_WEAPONS_OPT_OVERCRIT_RANGE_BONUS, 1);

// Init placeholders for ODBC gateway
SQLInit( );
WriteTimestampedLogEntry( "*** Started module " + GetModuleName( ));

SetLocalString( GetModule( ), MODULE_SERVER_ID, SQLEncodeSpecialChars( Get2DAString( "serverid", "ID", 0 )));

// Add standard alcoholic Beverages
DelayCommand( 230.0, WysAddStdBooze( ));

ExecuteScript( MODULE_NAME_INIT, OBJECT_SELF );
//wait 5 minutes after module is started to do the first save

// Save locations of PC's
// Save characters to the vault
DelayCommand( MODULE_INITIAL_AUTOSAVE_INTERVAL * 60.0, pf_autosave( ));

//Crafting exploit
SetLocalInt( GetModule( ), "X2_L_DO_NOT_ALLOW_CRAFTSKILLS", TRUE );

if ( GetGameDifficulty( ) == GAME_DIFFICULTY_CORE_RULES || GetGameDifficulty( ) == GAME_DIFFICULTY_DIFFICULT )
{
// * Setting the switch below will enable a seperate Use Magic Device Skillcheck for
// * rogues when playing on Hardcore+ difficulty. This only applies to scrolls
SetModuleSwitch( MODULE_SWITCH_ENABLE_UMD_SCROLLS, TRUE );

// * Activating the switch below will make AOE spells hurt neutral NPCS by default
SetModuleSwitch( MODULE_SWITCH_AOE_HURT_NEUTRAL_NPCS, FALSE );
}

// * AI: Activating the switch below will make the creaures using the WalkWaypoint function
// * able to walk across areas
SetModuleSwitch( MODULE_SWITCH_ENABLE_CROSSAREA_WALKWAYPOINTS, TRUE );

// * Spells: Activating the switch below will make the Glyph of Warding spell behave differently:
// * The visual glyph will disappear after 6 seconds, making them impossible to spot
// SetModuleSwitch( MODULE_SWITCH_ENABLE_INVISIBLE_GLYPH_OF_WARDING, TRUE);

// * Craft Feats: Want 50 charges on a newly created wand? We found this unbalancing,
// * but since it is described this way in the book, here is the switch to get it back...
// SetModuleSwitch( MODULE_SWITCH_ENABLE_CRAFT_WAND_50_CHARGES, TRUE);

// * Craft Feats: Use this to disable Item Creation Feats if you do not want
// * them in your module
SetModuleSwitch( MODULE_SWITCH_DISABLE_ITEM_CREATION_FEATS, TRUE );

// * Palemaster: Deathless master touch in PnP only affects creatures up to a certain size.
// * We do not support this check for balancing reasons, but you can still activate it...
// SetModuleSwitch( MODULE_SWITCH_SPELL_CORERULES_DMASTERTOUCH, TRUE);

// * Epic Spellcasting: Some Epic spells feed on the liveforce of the caster. However this
// * did not fit into NWNs spell system and was confusing, so we took it out...
// SetModuleSwitch( MODULE_SWITCH_EPIC_SPELLS_HURT_CASTER, TRUE);

// * Epic Spellcasting: Some Epic spells feed on the liveforce of the caster. However this
// * did not fit into NWNs spell system and was confusing, so we took it out...
// SetModuleSwitch( MODULE_SWITCH_RESTRICT_USE_POISON_TO_FEAT, TRUE);

// * Spellcasting: Some people don't like caster's abusing expertise to raise their AC
// * Uncommenting this line will drop expertise mode whenever a spell is cast by a player
SetModuleSwitch( MODULE_VAR_AI_STOP_EXPERTISE_ABUSE, TRUE );


// * Item Event Scripts: The game's default event scripts allow routing of all item related events
// * into a single file, based on the tag of that item. If an item's tag is "test", it will fire a
// * script called "test" when an item based event (equip, unequip, acquire, unacquire, activate,...)
// * is triggered. Check "x2_it_example.nss" for an example.
// * This feature is disabled by default.
SetModuleSwitch( MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS, TRUE );

SetLocalString( GetModule( ), "X2_S_UD_SPELLSCRIPT", "mod_spellhook" );
SetLocalInt( GetModule( ), "RecentRestart", 1 );
DelayCommand( 600.0, ClearRecentRestart( ));
}

My other hypothesis is the oncliententer event. This is the one (as mentioned above) that seems to clear some local intergers. Then again I am pretty much shooting in the dark here....

Modifié par Lazarus Magni, 23 septembre 2011 - 02:35 .


#20
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
If it's a tag scripting issue, you could test that by trying out another item with a unique power, to see if that one still functions. It does seem to me as though some other routine is disabling the tag based scripting switch, but without knowing what's in all those other includes and scripts, or even the OnActivateItem script, it's hard to say for certain.

#21
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Well I know for a fact that other unique power items are working fine. I had actually wondered if the item needed to be included in the on item activated script, but when I tested it (albiet possibly feebly due to my lack of scripting skills) it did nothing to prevent this. Here is our on activate script though in case it helps. From my uneducated eyes though I can't see anything that would be interfering...

//this line is needed if you are going to use pipe and witchweed
#include "conf_module"
#include "lib_witchgrass"
#include "wys_i_common"
#include "wys_i_booze"
#include "nw_i0_plot"
#include "pf_portal_util"
#include "zdlg_include_i"
#include "zep_inc_phenos"

void AnnounceArea( string sMessage, object oSource )
{
  object oPC=GetFirstPC( );
  while( GetIsObjectValid( oPC ))
  {
    if( GetObjectSeen( oPC, oSource ))
    {
      SendMessageToPC( oPC, sMessage );
    }
    oPC= GetNextPC( );
  }
}
void main( )
{
    //Define and st variable that can be used by all custom items
  object oItem = GetItemActivated( );
  object oPC = GetItemActivator( );
  object oTarget = GetItemActivatedTarget( );
  location lTarget = GetItemActivatedTargetLocation( );
  location lLocation = GetItemActivatedTargetLocation( );
  location lActivator = GetLocation( oPC );
  string sTag = GetTag( oItem );
  effect eEffect;
    // wys_e_modact - Module OnActivate checks for alcoholic beverage use.
    // All alcoholic beverages must be custom potions with tags that begin with
    // ALC_ to activate the appropriate effects.
    //
  if ( GetBaseItemType( oItem ) == BASE_ITEM_POTIONS )
  {
    if ( GetSubString( sTag, 0, 4 ) == "ALC_" )
    {
      WysUseDrink( sTag, oTarget );
      return;
    }
  }
  if ( sTag == "ALC_RODDW" )
  {
    if ( GetObjectType( oTarget ) == OBJECT_TYPE_CREATURE )
    {
      // Note: If you use WYSDRUNK_DECCON it starts to compound upon
      // itself with this function! Use WYSDRUNK_NOCON instead.
      eEffect = EffectVisualEffect( VFX_IMP_HEAD_ODD );
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eEffect, oTarget );
      WysMakeDrunkLevel( GetItemActivatedTarget( ), WYSDRUNK_UNCONSCIOUS,
                        WYSDRUNK_DECSTR | WYSDRUNK_NOCON | WYSDRUNK_NASTY |
                        WYSDRUNK_PUNISH );
      return;
    }
    else
    {
      eEffect = EffectVisualEffect( 293 );
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eEffect, oPC );
      SendMessageToPC( oPC, "Invalid target" );
      return;
    }
  }
  // Mount System
  // Uses an integer on the item to determine the mount type.
  // Twainer 28th May 2007
  if( GetStringLeft(sTag, 13) == "twn_summount_" )
  {
        // check Mounted Status
    if (GetPhenoType(oPC) > 2){ // Mounted
        // Apply an implosion effect above the users head
        float facing = GetFacing(oPC);
        vector offset = GetPositionFromLocation(GetLocation(oPC)) + Vector(0.0, 0.0, 3.5);
        location lvfx = Location(GetArea(oPC), offset, facing);
        effect remove = EffectVisualEffect(VFX_FNF_IMPLOSION);
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, remove, lvfx);
        zep_Dismount(oPC);
    } else { // NotMounted
        // Code to allow areas to prohibit mounts
        if (GetLocalInt(GetArea(oPC), "core_nomounts")){
            SendMessageToPC(oPC, "No mounts allowed in here");
            return;
        }
        // This is where we grab the mount type from the item
        int nMount = StringToInt(GetStringRight(sTag, 2));
        effect summon;
        // Different effects for the "Exotic" mounts
        if (nMount == 12 || nMount == 32)
            summon = EffectVisualEffect(VFX_FNF_SUMMON_GATE);
        else if (nMount == 13 || nMount == 33)
            summon = EffectVisualEffect(VFX_FNF_SUMMON_CELESTIAL);
        else
            summon = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_2);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, summon, oPC);
        zep_Mount(oPC, OBJECT_INVALID, nMount);
    }
  return;
  }
  if ( GetStringRight( sTag, 7 ) == "_quiver" )
  {
    //create the arrows in a stack of 99 on the user
    object oArrows = DbgCreateItemOnObject( GetStringLeft( sTag, GetStringLength( sTag ) - 7 ), oPC, 99 );
    //identify the arrows for the user
    SetIdentified( oArrows, 1 );
    //Set arrows to plot so that they can not be sold
    SetPlotFlag( oArrows, TRUE );
    return;
  }
    //shard of returning
  if ( pf_CanPortalOut( oPC ))
  {
    if( sTag == "ShardofReturning" )
    {
      pf_Portal( oPC, PORTAL_DEST_NARIA, "NariaCentalPortal" );
      return;
    }
    //Bind Token: Badger Alley
    if( sTag == "BindGemBadger" )
    {
      pf_Portal( oPC, PORTAL_DEST_DUSK, "NW_BADGERALLEYPORTAL" );
      return;
    }
    //Bind Token: Insanity
    if( sTag == "BindGemInsanity" )
    {
      pf_Portal( oPC, PORTAL_DEST_DUSK, "NW_INSANITYPORTAL" );
      return;
    }
    //Bind Token: South Isle
    if( sTag == "BindGemSouthIsle" )
    {
      pf_Portal( oPC, PORTAL_DEST_SOUTHISLE, "NW_SOUTHISLEPORTAL" );
      return;
    }
    //Bind Token: Explorers Guild
    if( sTag == "BindGemExplorer" )
    {
      pf_Portal( oPC, PORTAL_DEST_NARIA, "EXPLORERSGUILDPORTAL" );
      return;
    }
    //Bind Token: Castle du Ralt
    if( sTag == "BindGemCastle" )
    {
      pf_Portal( oPC, PORTAL_DEST_DUSK, "NW_CastleduRaltRoof" );
      return;
    }
    //Bind Token: DM's Helper
    if( sTag == "BindGemDMHelper" )
    {
      pf_Portal( oPC, PORTAL_DEST_DUSK, "WP_rlt_DMHelperInside" );
      return;
    }
    //Bind Token: Western Islands
    if( sTag == "BindGemWI" )
    {
      pf_Portal( oPC, PORTAL_DEST_DUSK, "WP_rlt_DMHelperInside" );
      return;
    }
  }
// Ralt's Ball of Yarn
  if ( sTag == "BallofYarn" )
  {
    ExecuteScript( "rlt_summonkitten", oPC );
    return;
  }
//Wand of perculiarities
  if ( sTag == "alw_wand_wop" )
  {
    AssignCommand( oPC, ActionStartConversation( oPC, "alw_conv_wop", TRUE ));
    return;
  }
  if ( sTag == "pf_buff_rod" )
  {
    ExecuteScript( "autocast_begin", oPC );
    return;
  }
    //dorcheck wand activateitem
  if ( sTag == "jk_DoorCheckDMWa" )
  {
    if ( !GetIsDM( oPC ))
      DestroyObject( oItem );
    else
      AssignCommand( oPC, ActionStartConversation( oPC, "jk_doorcheckwand", FALSE, FALSE ));
    return;
  }
    //Melee Buff Rune
  if ( sTag == "MeleeBuffRune" )
  {
    DestroyObject( oItem, 1.0 );
    return;
  }
    //Explorer's Guild Token
  if ( sTag == "ik_guildtoken" )
  {
    AssignCommand( oPC, ActionStartConversation( oPC, "ik_tokencon", TRUE, FALSE ));
    return;
  }
    //Cloak of the Wolf
  if( sTag == "CloakoftheWolf" )
  {
    effect eWolf = EffectPolymorph( POLYMORPH_TYPE_WOLF );
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eWolf, oPC, 360.0 );
    return;
  }
    //GreaterCloakoftheWolf
  if( sTag == "GreaterCloakoftheWolf" )
  {
    effect eWWolf = EffectPolymorph( POLYMORPH_TYPE_WEREWOLF );
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eWWolf, oPC, 360.0 );
    return;
  }
    //Player's Ear
  if( GetResRef( oItem ) == "playerear" )
  {
    SendMessageToPC( oPC, "This is " + sTag + "'s ear." );
    return;
  }
    //Potion of Harm
  if( sTag == "PotionofHarm" )
  {
    object oTarget = GetItemActivator( );
    int nDamage, nHeal;
    effect eVis = EffectVisualEffect( 246 );
    effect eVis2 = EffectVisualEffect( VFX_IMP_HEALING_G );
    effect eHeal, eDam;
    if ( GetRacialType( oTarget ) == RACIAL_TYPE_UNDEAD )
    {
            //Figure out the amount of damage to heal
      nHeal = GetMaxHitPoints( oTarget ) - GetCurrentHitPoints( oTarget );
            //Set the heal effect
      eHeal = EffectHeal( nHeal );
            //Apply heal effect and VFX impact
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eHeal, oTarget );
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eVis2, oTarget );
      ExecuteScript( "core_post40_hp", oTarget );
    }
    else
    {
      nDamage = GetCurrentHitPoints( oTarget ) - d4( 1 );
      // Check for metamagic
      eDam = EffectDamage( nDamage, DAMAGE_TYPE_NEGATIVE );
      // Apply the VFX impact and effects
      DelayCommand( 1.0, ApplyEffectToObject( DURATION_TYPE_INSTANT, eDam, oTarget ));
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eVis, oTarget );
    }
    return;
  }
    //END Potion of Harm

  //Begin script for DMs Rod of Nudity
//                             1234567890123456
  if ( sTag == "DMsRodofNudity" )
  {
    if ( GetIsPC( oTarget ))
    {
      AssignCommand( oTarget, ActionUnequipItem( GetItemInSlot( INVENTORY_SLOT_CHEST , oTarget )));
      AssignCommand( oTarget, ActionUnequipItem( GetItemInSlot( INVENTORY_SLOT_HEAD , oTarget )));
      AssignCommand( oTarget, ActionUnequipItem( GetItemInSlot( INVENTORY_SLOT_LEFTHAND , oTarget )));
      AssignCommand( oTarget, ActionUnequipItem( GetItemInSlot( INVENTORY_SLOT_RIGHTHAND , oTarget )));
    }
    return;
  }
    //End script for DMs Rod of Nudity
    //Sowrd of Dios
  if( sTag == "SwordofDios" )
  {
    effect eDamage = EffectDamage(( 5*GetHitDice( oPC )));
    if( !GetIsPC( oTarget ))
    {
      effect eVis = EffectVisualEffect( VFX_FNF_IMPLOSION );
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eDamage, oTarget );
      ApplyEffectAtLocation( DURATION_TYPE_INSTANT, eVis, GetLocation( oTarget ));
      eVis= EffectVisualEffect( VFX_FNF_WAIL_O_BANSHEES );
      ApplyEffectAtLocation( DURATION_TYPE_INSTANT, eVis, GetLocation( oPC ));
    }
    return;
  }
    //Shard Blade
  if( sTag == "ShardBlade" )
  {
    effect eDamage = EffectDamage(( 3*GetHitDice( oPC )));
    if( !GetIsPC( oTarget ))
    {
      effect eVis = EffectVisualEffect( VFX_IMP_SLOW );
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eDamage, oTarget );
      ApplyEffectAtLocation( DURATION_TYPE_INSTANT, eVis, GetLocation( oTarget ));
      eVis= EffectVisualEffect( VFX_IMP_HASTE );
      ApplyEffectAtLocation( DURATION_TYPE_INSTANT, eVis, GetLocation( oPC ));
      AnnounceArea( GetName( oTarget )+" is rent by shards of the blade", oTarget );
    }
    return;
  }
    // Dice Bag
  if ( sTag == "DiceBag" )
  {
    ExecuteScript( "pf_dicebag", oPC );
    return;
  }
    //Party Stone
  if ( sTag == "JK_PartyStone" )
  {
    AssignCommand( oPC, ActionStartConversation( oPC, "jk_partystone", TRUE ));
    return;
  }
    //Vampiric ring
  if( sTag == "VampiricRing" )
  {
    effect eDamage = EffectDamage( 5 );
    effect eHeal   = EffectHeal( 5 );
    if( !GetIsPC( oTarget ))
    {
      if( GetHitDice( oPC ) > 9 )
      {
        effect eVis = EffectVisualEffect( VFX_IMP_NEGATIVE_ENERGY );
        ApplyEffectToObject( DURATION_TYPE_INSTANT, eDamage, oTarget );
        ApplyEffectToObject( DURATION_TYPE_INSTANT, eHeal, oPC );
        ApplyEffectAtLocation( DURATION_TYPE_INSTANT, eVis, GetLocation( oTarget ));
        ApplyEffectAtLocation( DURATION_TYPE_INSTANT, eVis, GetLocation( oPC ));
        AnnounceArea( GetName( oTarget )+"'s blood drains from it's body", oTarget );
      }
      else
      {
        SendMessageToPC( oPC, "Your will is not strong enough to command this ring" );
      }
    }
    return;
  }
//dmw_activate
// ** This script goes in the OnItemActivation event of your Module
// ** Properties.  It checks to see if the item used is a DM Helper
// ** And if so, and the user isnt a DM, destroys it, otherwise it
// ** Starts the DM Helper working.
  if( sTag == "dmschelper" )
  {
    if( GetIsDM( oPC ) != TRUE )
    {
      object oTest = GetFirstPC( );
      string sTestName = GetPCPlayerName( oPC );
      int nFound = FALSE;
      while ( GetIsObjectValid( oTest ) && ( ! nFound ))
      {
        if ( GetPCPlayerName( oTest ) == sTestName )
        {
          if( GetIsDM( oTest ))
          {
            nFound = TRUE;
          }
          else
          {
            DestroyObject( oItem );
            SendMessageToPC( oPC, "You are mortal and this is not yours!" );
            return;
          }
        }
        oTest = GetNextPC( );
      }
    }
      // get the wand's activator and target, put target info into local vars on activator
    object oMyActivator = GetItemActivator( );
    object oMyTarget = GetItemActivatedTarget( );
    SetLocalObject( oMyActivator, "dmwandtarget", oMyTarget );
    location lMyLoc = GetItemActivatedTargetLocation( );
    SetLocalLocation( oMyActivator, "dmwandloc", lMyLoc );
      //Make the activator start a conversation with itself
    AssignCommand( oMyActivator, ActionStartConversation( oMyActivator, "dmwand", TRUE ));
    return;
  }
  if( sTag == "AutoFollow" )
  {
    object oTarget = GetItemActivatedTarget( );
    if( GetIsObjectValid( oTarget ))
    {
      AssignCommand ( oPC, ActionForceFollowObject( oTarget ));
    }
    return;
  }

  if( sTag == "WandOfFX" )
  {
    // get the wand's activator and target, put target info into local vars on activator
    object oDM = GetItemActivator( );
    object oMyTarget = GetItemActivatedTarget( );
    SetLocalObject( oDM, "FXWandTarget", oMyTarget );
    location lTargetLoc = GetItemActivatedTargetLocation( );
    SetLocalLocation( oDM, "FXWandLoc", lTargetLoc );
    object oTest=GetFirstPC( );
    string sTestName = GetPCPlayerName( oDM );
      // Test to make sure the activator is a DM, or is a DM
      // controlling a creature.
    if( GetIsDM( oDM ) != TRUE )
    {
      object oTest = GetFirstPC( );
      string sTestName = GetPCPlayerName( oDM );
      int nFound = FALSE;
      while ( GetIsObjectValid( oTest ) && ( ! nFound ))
      {
        if ( GetPCPlayerName( oTest ) == sTestName )
        {
          if( GetIsDM( oTest ))
          {
            nFound = TRUE;
          }
          else
          {
            DestroyObject( oItem );
            SendMessageToPC( oDM, "You are mortal and this is not yours!" );
            return;
          }
        }
        oTest=GetNextPC( );
      }
    }
    //Make the activator start a conversation with itself
    AssignCommand( oDM, ActionStartConversation( oDM, "fxwand", TRUE ));
    return;
  }
  if( sTag == "EmoteWand" )
  {
    StartDlg( oPC, oItem, "pf_emotewand", TRUE, FALSE );
    return;
  }
  //BEGIN jk_onactivate Script source
  //Begin script for Stone of Statue Form
  if( sTag == "StoneofStatueForm" )
  {
        //declarations
    effect eStatueVis; //Statue form visual
    effect eParalyze; //Paralyze effect
    effect eImmunityFire; //Immunity to fire
    effect eImmunityCold; //Immunity to cold
    effect eImmunityAcid; //Immunity to acid
    effect eImmunitySonic; //Immunity to sonic
    effect eImmunityDivine; //Immunity to divine
    effect eImmunityElec; //Immunity to electric
    effect eImmunityMagic; //Immunity to magical energy
    effect eImmunityNeg; //Immunity to negative energy
    effect eImmunityPos; //Immunity to positive energy
    effect eImmunityPierce; //Immunity to pierce
    effect eImmunityBlunt; //Immunity to bludgeoning
    effect eImmunitySlash; //Immunity to slash
    int iPercent; //Percent Immunity
    float fDuration; //Duration effect lasts
        //setting values
    iPercent = 100; //Percent Immunity
    fDuration = 30.0; //Duration effect lasts in seconds
    eStatueVis = EffectVisualEffect( VFX_DUR_PROT_STONESKIN );//Stoneskin visual
    eParalyze = EffectParalyze( );//Paralyze effect
    eImmunityFire = EffectDamageImmunityIncrease( DAMAGE_TYPE_FIRE, iPercent );//Fire Immunity
    eImmunityCold = EffectDamageImmunityIncrease( DAMAGE_TYPE_COLD, iPercent );//Cold Immunity
    eImmunityAcid = EffectDamageImmunityIncrease( DAMAGE_TYPE_ACID, iPercent );//Acid Immunity
    eImmunitySonic = EffectDamageImmunityIncrease( DAMAGE_TYPE_SONIC, iPercent );//Sonic Immunity
    eImmunityDivine = EffectDamageImmunityIncrease( DAMAGE_TYPE_DIVINE, iPercent );//Divine Immunity
    eImmunityElec = EffectDamageImmunityIncrease( DAMAGE_TYPE_ELECTRICAL, iPercent );//Electrical Immunity
    eImmunityMagic = EffectDamageImmunityIncrease( DAMAGE_TYPE_MAGICAL, iPercent );//Magical Immunity
    eImmunityNeg = EffectDamageImmunityIncrease( DAMAGE_TYPE_NEGATIVE, iPercent );//Negative energy Immunity
    eImmunityPos = EffectDamageImmunityIncrease( DAMAGE_TYPE_POSITIVE, iPercent );//Positive energy Immunity
    eImmunityPierce = EffectDamageImmunityIncrease( DAMAGE_TYPE_PIERCING, iPercent );//Piercing Immunity
    eImmunityBlunt = EffectDamageImmunityIncrease( DAMAGE_TYPE_BLUDGEONING, iPercent );//Bludgeoning Immunity
    eImmunitySlash = EffectDamageImmunityIncrease( DAMAGE_TYPE_SLASHING, iPercent );//Slashing Immunity
        //applying effects
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eStatueVis, oPC, fDuration ); //Stoneskin visual
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eParalyze, oPC, fDuration ); //Paralyze effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityFire, oPC, fDuration ); //Immunity to fire effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityCold, oPC, fDuration ); //Immunity to cold effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityAcid, oPC, fDuration ); //Immunity to acid effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunitySonic, oPC, fDuration ); //Immunity to sonic effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityDivine, oPC, fDuration ); //Immunity to divine energy effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityElec, oPC, fDuration ); //Immunity to electric effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityMagic, oPC, fDuration ); //Immunity to magical energy effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityNeg, oPC, fDuration ); //Immunity to negative energy effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityPos, oPC, fDuration ); //Immunity to positive energy effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityPierce, oPC, fDuration ); //Immunity to piercing effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunityBlunt, oPC, fDuration ); //Immunity to bludgeoning effect
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eImmunitySlash, oPC, fDuration ); //Immunity to slashing effect
    return;
  }
    //End script for Stone of Statue Form
    //Begin Medusa's cure
  if ( sTag == "jk_MedusasCure" )
  {
    string sName = GetName( oTarget );
    effect eBuff = GetFirstEffect( oTarget );
    while ( GetIsEffectValid( eBuff ))
    {
      if ( GetEffectSubType( eBuff ) == SUBTYPE_SUPERNATURAL &&
          GetEffectType( eBuff ) != EFFECT_TYPE_DAMAGE_INCREASE &&
          GetEffectDurationType( eBuff ) == DURATION_TYPE_PERMANENT )
      {
        RemoveEffect( oTarget, eBuff );
        SetStandardFactionReputation( STANDARD_FACTION_HOSTILE, 0, oTarget );
      }
      eBuff = GetNextEffect( oTarget );
    }
    SetLocalInt( GetModule( ), "MedusaStoned" + sName, 0 );
    return;
  }
    //End Medusa's cure

    //Begin script for Gort
  if( sTag == "Gort" )
  {
        //declarations
    effect eGortVis; //Gort visual
    effect eStr; //Strength effect
    effect eDex; //Dexterity effect
    effect eCon; //Constitution effect
    effect eWis; //Wisdom effect
    effect eAttacks; //Number of attacks increase effect
    effect eResistSlash; //Slashing damage resistance effect
    effect eResistBlunt; //Bludgeoning damage resistance effect
    effect eResistPierce; //Piercing damage resistance effect
    int iResist; //Amount of resistance
    int iStat; //Amount for stat increase
    float fDuration; //Duration effect lasts
    float fDown; //Duration hangover lasts
    effect eDeath; //Death effect
    effect eConfuse; //Confusion effect
    effect eStrL; //Str lowering effect
    effect eDexL; //Dex lowering effect
    effect eConL; //Con lowering effect
    effect eWisL; //Wis lowering effect
    effect eDownVis; //Hangover visual
        //setting values
    iResist = 20; //Resist amount
    iStat = 5; //Amount to alter stat
    fDuration = 180.0; //Duration effect lasts in seconds as a floating number
    fDown = 60.0; //Duration hangover lasts in seconds as a floating number
    eGortVis = EffectVisualEffect( VFX_DUR_PROTECTION_GOOD_MINOR );//Gort visual
    eStr = EffectAbilityIncrease( ABILITY_STRENGTH, iStat );//Raise Str by 10 effect
    eDex = EffectAbilityIncrease( ABILITY_DEXTERITY, iStat );//Raise Dex by 10 effect
    eCon = EffectAbilityIncrease( ABILITY_CONSTITUTION, iStat );//Raise Con by 10 effect
    eWis = EffectAbilityIncrease( ABILITY_WISDOM, iStat );//Raise Wis by 10 effect
    eAttacks = EffectModifyAttacks( 5 );//add five attacks
    eResistSlash = EffectDamageResistance( DAMAGE_TYPE_SLASHING, iResist, 0 );//Slashing resist
    eResistBlunt = EffectDamageResistance( DAMAGE_TYPE_BLUDGEONING, iResist, 0 );//Bludgeoning resist
    eResistPierce = EffectDamageResistance( DAMAGE_TYPE_PIERCING, iResist, 0 );//Piercing resist
    eDeath = EffectDeath( );//Death Effect
    eConfuse = EffectConfused( );//Confusion effect
    eStrL = EffectAbilityDecrease( ABILITY_STRENGTH, iStat );//Lower stat effect
    eDexL = EffectAbilityDecrease( ABILITY_DEXTERITY, iStat );//Lower stat effect
    eConL = EffectAbilityDecrease( ABILITY_CONSTITUTION, iStat );//Lower stat effect
    eWisL = EffectAbilityDecrease( ABILITY_WISDOM, iStat );//Lower stat effect
    eDownVis = EffectVisualEffect( VFX_DUR_MIND_AFFECTING_DOMINATED );//Hangover visual
        //applying effects
    int iRND;
    iRND = d100( );
    if (( iRND >= 1 ) && ( iRND <= 5 ))
    {
      ApplyEffectToObject( DURATION_TYPE_INSTANT, eDeath, oPC ); //Death effect 5% of the time
    }
    else if (( iRND >= 6 ) && ( iRND <= 15 ))
    {
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eGortVis, oPC, fDuration ); //Gort visual
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eConfuse, oPC, fDuration ); //Confused effect 10% of the time
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eDownVis, oPC, fDown )); //Str effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eStrL, oPC, fDown )); //Str effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eDexL, oPC, fDown )); //Dex effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eConL, oPC, fDown )); //Con effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eWisL, oPC, fDown )); //Wis effect
    }
    else if (( iRND >= 16 ) && ( iRND <= 100 ))
    {
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eGortVis, oPC, fDuration ); //Gort visual
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eStr, oPC, fDuration ); //Str effect
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eDex, oPC, fDuration ); //Dex effect
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eCon, oPC, fDuration ); //Con effect
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eWis, oPC, fDuration ); //Wis effect
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eAttacks, oPC, fDuration ); //add 5 attacks effect
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eResistSlash, oPC, fDuration ); //Resist slashing effect
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eResistBlunt, oPC, fDuration ); //Resist bludgeoning effect
      ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eResistPierce, oPC, fDuration ); //Resist piercing effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eDownVis, oPC, fDown )); //Str effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eStrL, oPC, fDown )); //Str effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eDexL, oPC, fDown )); //Dex effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eConL, oPC, fDown )); //Con effect
      DelayCommand( fDuration, ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eWisL, oPC, fDown )); //Wis effect
    }
    return;
  }
    //End script for Gort
    //Begin script for Rune of Arrow Summoning
  if( sTag == "RuneofArrowSummoning" )
  {
        //declare my variables
    int iRND;
    string sArrows = "NW_WAMMAR00" + IntToString( d8( ));
    object oArrows = DbgCreateItemOnObject( sArrows, oPC, 99 );//create the arrows in a stack of 99 on the user
    SetIdentified( oArrows, 1 );//identify the arrows for the user
    SetPlotFlag( oArrows, TRUE );//Set arrows to plot so that they can not be sold
    return;
  }
    //End script for Rune of Arrow Summoning

  if( sTag == "HanzoRune" )
  {
    string sArrows;
    switch( d8( ))
    {
      case 1:
      case 2:
      case 3:
        sArrows = "whatever";
        break;
      case 4:
      case 5:
      case 6:
        sArrows = "darkghost";
        break;
      case 7:
      case 8:
        sArrows = "thesnowman";
        break;
    }
    //create the arrows in a stack of 99 on the user
    object oArrows = DbgCreateItemOnObject( sArrows, oPC, 99 );
    //identify the arrows for the user
    SetIdentified( oArrows, 1 );
    //Set arrows to plot so that they can not be sold
    SetPlotFlag( oArrows, TRUE );
    return;
  }

    //Begin script for The Raptured Rune of Arrow Summoning
  if( sTag == "TheRapturedRuneofArrow" )
  {
    //declare my variables
    string sArrows;
    switch( d8( ))
    {
      case 1:
      case 2:
        sArrows = "therapturedarr";
        break;
      case 3:
      case 4:
      case 5:
        sArrows = "nightmare";
        break;
      case 6:
      case 7:
      case 8:
        sArrows = "ouch";
        break;
    }
    object oArrows = DbgCreateItemOnObject( sArrows, oPC, 99 );//create the arrows in a stack of 99 on the user
    SetIdentified( oArrows, 1 );//identify the arrows for the user
    SetPlotFlag( oArrows, TRUE );//Set arrows to plot so that they can not be sold
    return;
  }
    //Begin script for The Raptured Rune of Arrow Summoning
  //Begin script for Tomahawk Case
  if( sTag == "TomahawkCase" )
  {
    //create the axes in a stack of 50 on the user
    object oAxes = DbgCreateItemOnObject( "jk_fireytomahawk", oPC, 50 );
    //identify the axes for the user
    SetIdentified( oAxes, 1 );
    //Set axes to plot so that they can not be sold
    SetPlotFlag( oAxes, TRUE );
  }
 
    //Begin script for Knockdown Rune
  if( sTag == "KnockdownRune" )
  {
    effect eKnockDown = EffectKnockdown( );
    //Set length of time for knowdown effect
    float fDuration = 15.0;
    //Set the effect shape, size and the location.  Capture the first target object in the shape.
    oTarget = GetFirstObjectInShape( SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation( oPC ), OBJECT_TYPE_CREATURE );
    //Cycle through the targets within the area until an invalid object is captured.
    while( GetIsObjectValid( oTarget ))
    {
      if( !GetIsReactionTypeFriendly( oTarget ) && !GetIsFriend( oTarget ) && oTarget != oPC )
      {
        ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eKnockDown, oTarget, fDuration );
      }
      //Select the next target within the area
      oTarget = GetNextObjectInShape( SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation( oPC ), OBJECT_TYPE_CREATURE );
    }
    return;
  }
  //End script for Knockdown Rune
  //Begin script for Value Rod
  if( sTag == "ValueRod" )
  {
        //declare my variables
    object oItem;
    int iSlotID;
    int nTotalInvValue = 0;
    int nTotalEquipValue = 0;
    for ( iSlotID = 0; iSlotID < NUM_INVENTORY_SLOTS; iSlotID++ )
    {
      oItem = GetItemInSlot( iSlotID, oTarget );
      nTotalEquipValue = nTotalEquipValue + GetGoldPieceValue( oItem );
    }
    oItem = OBJECT_INVALID;
    oItem = GetFirstItemInInventory( oTarget );
    while ( GetIsObjectValid( oItem ))
    {
      nTotalInvValue = nTotalInvValue + GetGoldPieceValue( oItem );
      oItem = GetNextItemInInventory( oTarget );
    }
    SendMessageToPC( oPC, GetName( oTarget ) + " has " + IntToString( nTotalEquipValue ) + " gold worth of items equiped." );
    SendMessageToPC( oPC, GetName( oTarget ) + " has " + IntToString( nTotalInvValue ) + " gold worth of items in inventory." );
    SendMessageToPC( oPC, GetName( oTarget ) + " has " + IntToString( nTotalInvValue + nTotalEquipValue ) + " gold worth of items in total." );
    return;
  }
    //End script for Value Rod
    //Begin script for Tomahawk Case
  if( sTag == "TomahawkCase" )
  {
        //declare my variables
    int iRND;
    object oAxes = DbgCreateItemOnObject( "jk_fireytomahawk", oPC, 50 );//create the axes in a stack of 50 on the user
    SetIdentified( oAxes, 1 );//identify the axes for the user
    SetPlotFlag( oAxes, TRUE );//Set axes to plot so that they can not be sold
    return;
  }
    //End script for Tomahawk Case
    //Begin script for JBoys DM Wand
  if( sTag == "JBoysDMWand" )
  {
    if ( !GetIsDM( oPC ))
    {
      DestroyObject( oItem );
      SendMessageToPC( oPC, "You should not have this." );
      return;
    }
    else
    {
      SetLocalObject( oPC, "JBoysDMWandTarget", oTarget );
      AssignCommand( oPC, ActionStartConversation( oPC, "JBoysDMWand", TRUE ));
    }
    return;
  }
    //End script for JBoys DM Wand
    //END jk_onactivate Script source
    //BEGIN DM NPC WAND
  if ( sTag == "npcaction" )    // NPC Control Rod
  {
        // Add a check to validate that GetIsDM( oPC ) is true to limit this item to DM usage.
    SetLocalString( oPC, "jg_conv_script", "jg_npc_action" );
    SetLocalInt( oPC, "jg_conv_state", 0 );
    SetLocalObject( oPC, "jg_conv_target", oTarget );
    AssignCommand( oPC, ActionStartConversation( oPC, "jg_data_driven", TRUE ));
    return;
  }
  if ( sTag == "template" )   // example data driven conversation template
  {
    SetLocalString( oPC, "jg_conv_script", "jg_dd_template" );
    SetLocalInt( oPC, "jg_conv_state", 0 );
    SetLocalObject( oPC, "jg_conv_target", oTarget );
    AssignCommand( oPC, ActionStartConversation( oPC, "jg_data_driven", TRUE ));
    return;
  }
    //END DM NPC WAND
    //BEGIN tournamentwand
  if ( sTag == "tournamentwand" )
  {
    if ( oTarget == oPC )
    {
      AssignCommand( oPC, ActionStartConversation( oPC, "ath_tournyconv", TRUE ));
    }
    if ( oTarget != oPC )
    {
      if ( HasItem( oTarget, "TournamentContenderRune" ) == 0 )
      {
        SendMessageToPC( oPC, "Target Not In Tournament" );
      }
      if ( HasItem( oTarget, "TournamentContenderRune" ) == 1 )
      {
        object oItem = GetFirstItemInInventory( oTarget );
        object oDestroy;
        while ( GetIsObjectValid( oItem ))
        {
          if ( sTag == "TournamentContenderRune" ) oDestroy = oItem;
          SendMessageToPC( oTarget, "You have been removed from the Tournament, Thank you for Participating." );
          oItem = GetNextItemInInventory( oTarget );
        }
        DestroyObject( oDestroy );
      }
    }
    return;
  }
  //END tournamentwand
  //Begin Script for pipe
  if ( sTag == "pipe" )
  {
    location lLoc;
    if( GetIsObjectValid( oItem ))
    {
            //they need something to smoke in it...
      object oBud = GetItemPossessedBy( oPC, "witchbud" );
      AssignCommand( oPC, ClearAllActions( ));
      if( oBud != OBJECT_INVALID ){
                //apply effects
        AssignCommand( oPC, ActionPlayAnimation( ANIMATION_FIREFORGET_DRINK ));
        GetHigh( oPC );
        DelayCommand( 1.0f, GenerateSmoke( oPC, TRUE ));
        //destroy the smoked bud
        DestroyObject( oBud );
      }
      else
      {
        AssignCommand( oPC, ActionSpeakString( "I don't have anything to smoke in it!" ));
      }
    }
    return;
  }
  //End Script for pipe
  //Begin Script for witchweed
  if ( sTag == "witchseeds" )
  {
    location lLoc;
    if( GetIsObjectValid( oItem ))
    {
      if( GetIsObjectValid( oPC ))
      {
        string sAreaTag = GetTag( GetArea( oPC ));
        //if ( sAreaTag == "UnknownForrest" || sAreaTag == "BoxCanyonA" || sAreaTag == "BoxCanyonB" || sAreaTag == "HomeAgain" ){
        AssignCommand( oPC, ClearAllActions( ));
        AssignCommand( oPC, ActionMoveToLocation( lLoc, TRUE ));
        DelayCommand( 3.f, CreateNewPlant( oPC ));
        DestroyObject( oItem, 3.f );
        //}
        //else
        //{
        //    AssignCommand( oPC, ActionSpeakString( "There's no where to plant it." ));
        //}
      }
    }
    return;
  }
    //End Script for witchweed
  // DM QP Wand
  // DM QP control
  ////////////////////////////////////////////////
  /*
  if ( sTag == "jk_DMQPWand" )
  {
      AssignCommand( oPC, ActionStartConversation( oPC, "jkdmqpwand", TRUE, FALSE ));
      SetLocalObject( oPC, "Target", oTarget );
  }
  */
  if ( sTag == "scy_book_aventia" )
  {
    AssignCommand(oPC, ActionStartConversation(oPC, "scy_book_aventia", TRUE, FALSE));
    return;
  }
  if( GetResRef( oItem ) == "tal_qpwand" )
  {
    SetLocalObject( oPC, "otarg", oTarget );
    AssignCommand( oPC, ActionStartConversation( OBJECT_SELF, "tal_qpwand", TRUE, FALSE ));
    return;
  }
  if( GetResRef( oItem ) == "tal_qpcheckwand" )
  {
    SetLocalObject( oPC, "otarg", oPC );
    AssignCommand( oPC, ActionStartConversation( OBJECT_SELF, "tal_qpchecker", TRUE, FALSE ));
    return;
  }

    // ROD OF EXPLODY GOODNESS
    // Giving new meaning to DM Power Abuse
    ////////////////////////////////////////////////
  if ( sTag == "dmt_dynarod" )
  {
    int iIsDM = GetIsDM( oPC );
        // If player is not a DM light a fuse on him, make him speak and remove the Rod
    if ( !GetIsDM( oPC ))
    {
      ExecuteScript( "dmt_keg_burn", oPC );
      AssignCommand( oPC, SpeakString( "*Sniff Sniff* Can you smell something burning?" ));
      DestroyObject( oItem );
    }
        // If he is a DM, take his orders.
    else
    {
      object oTarget = GetItemActivatedTarget( );
      if( GetIsObjectValid( oTarget ))
      {
        ExecuteScript( "dmt_keg_burn", oTarget );
     

#22
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Hmm looks like that got truncated... here is the rest of it...:
}
}
return;
}
if( GetResRef( oItem ) == "tal_pokeball" ) //Player tries to capture 'pokemon'
{
if( GetCurrentHitPoints( oTarget ) < ( GetMaxHitPoints( oTarget ) / 4 ) && d4( ) != 1 && GetCurrentHitPoints( oTarget )>0 && GetChallengeRating( oTarget )<=GetChallengeRating( oPC ))
{
ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectVisualEffect( VFX_FNF_SOUND_BURST ), oTarget );
DbgCreateObject( OBJECT_TYPE_ITEM, "tal_pokeballfull", GetLocation( oTarget ), TRUE, GetResRef( oTarget ));
DestroyObject( oTarget );
FloatingTextStringOnCreature( "*Capture Success*", oPC, TRUE );
}
else
{
FloatingTextStringOnCreature( "*Capture Failure*", oPC, TRUE );
}
return;
}
PrintString( "[ mod_onactivate ] Calling " + sTag + " for item: " + GetName( oItem ));
ExecuteScript( sTag, oPC );
ExecuteScript("bardsongonact", OBJECT_SELF);
}

#23
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
PrintString( "[ mod_onactivate ] Calling " + sTag + " for item: " + GetName( oItem ));
ExecuteScript( sTag, oPC );

Try moving that to near the very beginning, right after this line here:
string sTag = GetTag( oItem );


That will let you know if one of those other if statements is ending the check prematurely, before it reaches the tag based ExecuteScript call. There might be an errant return; command in there, but it's a pile of code to look through to find it.

#24
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
The module is not fully set up for tag based scripting. The last script you posted proves that. Your other unique powers are working because they are running directly from the OnActvate script . I would guess tat you have at least one event that is set up for TBS and it is changing the UserDefined Item event number. Since your OnActvate script never changes the event number back to 0 (activate) It just quits working. It looks like you are also running the script "bardsongonact" every time you run your TBS scripts.

That is if I am correct in my assumptions.
Assumption1: The Script above is your Modules OnActivateItem Event.
Assumption 2: There are no modifications to script nw_s3_actitem01
Assumption 3: nw_s3_actitem01 is still the Impact script for all unique powers in Spells.2da.

#25
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
I can give that a try FB, but I am not sure what I would be looking for to verify that one way or another...

Light, thank's for chiming in here. I honestly am not knowledgeable in all this stuff to know for sure. Indeed however bardsongonact is executed with this script, and that is a modification I made from the original script that was passed down to me, to utalize a few custom bard instruments off the vault which have not proved tremendously usefull. I could perhaps remove those if they are interfering.

As far as your assumptions, 1 is correct, 2 is incorrect as it looks like it has been modified to this:
//::///////////////////////////////////////////////
//:: Actuvate Item Script
//:: NW_S3_ActItem01
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This fires the event on the module that allows
    for items to have special powers.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 19, 2001
//:://////////////////////////////////////////////
void main()
{
    object oItem = GetSpellCastItem();
    object oTarget = GetSpellTargetObject();
    location lLocal = GetSpellTargetLocation();
    if (GetStringLeft(GetTag(oItem), 5) == "dmfi_" ||
    GetStringLeft(GetTag(oItem), 8) == "hlslang_")
    {
        SetLocalObject(OBJECT_SELF, "dmfi_item", oItem);
        SetLocalObject(OBJECT_SELF, "dmfi_target", oTarget);
        SetLocalLocation(OBJECT_SELF, "dmfi_location", lLocal);
        ExecuteScript("dmfi_activate", OBJECT_SELF);
        return;
    }
    SignalEvent(GetModule(), EventActivateItem(oItem, lLocal, oTarget));
}

3? I am not sure how to determine this...?