Aller au contenu

Photo

RE: Any Way to Stop Spell Replenishment When Resting?


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

#1
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Anyone know of a way to stop a wizard from regaining spells when resting? I have added a "Wizard's Spellbook" item and need to stop spell replenishment when resting if the wizard does not have the spellbook.

#2
Greyfort

Greyfort
  • Members
  • 234 messages
NWNXFuncs_SetMemorizedSpellSlot which is a nwnx plugin for windows. You can find all info here http://www.nwnx.org/

You may have to set the spell slots to zero after the rest, but it may be possible.

#3
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
I was hoping for something within the constraints of the standard game functions without having to use something like NWNX - which confounds me to no small end.

#4
lordofworms

lordofworms
  • Members
  • 252 messages
I too felt that way with nwnx2, but sincerely, its no more difficult than telling someone who never uses haks to use a hak. it SEEMS difficult but if you use the built in sqlite database (instead of setting up a MySQL) thats part of the nwnx2 files its a simple as setting some ini files
and trust me, i would never go back not when I have sooooo many new great options that are just not possible (or easy) any other way.

give it a try and I assure you, you wont think twice about ever not using it again.

#5
Greyfort

Greyfort
  • Members
  • 234 messages
Yes worm is right...You dont have to set up MySQL it will work all by its self with SQLite, and the plugins are great. I looked into it a little more and found the functions would help you do what you spoke of:

//:://////////////////////////////////////////////////////////////
//:: Title : spells_1
//:: Author: Greyfort
//:: Module: any who need
//:: Date : Aug 11, 2011
//:: Vers : 1.0
//:: Info :
//:://////////////////////////////////////////////////////////////
#include "nwnx_events2"
void main()
{

//1)first get known spells with

//NWNXFuncs_GetKnownSpells
// returns a string delimited by sDelimiter of all known spells of a given class and spell level
//string NWNXFuncs_GetKnownSpells(object oCreature, int iclass, int iSpellLevel, string sDelimiter=",")

//NWNXFuncs_GetKnownSpellCount
// returns the number of spells known for a given class and spell level
//int NWNXFuncs_GetKnownSpellCount(object oCreature, int iclass, int iSpellLevel)

//NWNXFuncs_GetMemorizedSpellSlot
// Returns information about a memorized spell (spell id, meta magic and whether the spell is ready to be cast)
//struct MemorizedSpellSlot NWNXFuncs_GetMemorizedSpellSlot(object oCreature, int iclass, int iSpellLevel, int iIndex)

//2)then setmemorized spells with

//NWNXFuncs_SetMemorizedSpellSlot
// Sets information about a spell in a memorized spell slot (spell id, meta magic and whether the spell is ready to be cast);
//void NWNXFuncs_SetMemorizedSpellSlot(object oCreature, int iclass, int iSpellLevel, int iIndex, struct MemorizedSpellSlot spell)

}

this is not a working script just a basic layout, If I have the time I will try to make a working one, but it would mean you need to install nwnx.

#6
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Well I guess I'm going to have to take the plunge. Maybe someone can point me to some NWNX tutorials or such...

#7
Shadooow

Shadooow
  • Members
  • 4 470 messages
You dont need NWNX for that. Simpy use DecreaseRemainingSpellUses command with spell id from 0 to the last 569 in (double) loop. Could make you script a bit later if noone else does. But as I know you it wont be neccessary.

Modifié par ShaDoOoW, 11 août 2011 - 10:38 .


#8
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
You can also do it all from the rest event.

in the REST_EVENTTYPE_REST_STARTED section check to see what spells they still have.

in the REST_EVENTTYPE_REST_FINISHED section decrease the uses to what they where stored at above.

#9
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
ShaDoOoW, Lightfoot - actually working on an amalgam of both your suggestions :P

#10
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Maybe someone could take a look at this and tell me where I went wrong? Spells are NOT decrementing to pre-rest levels like they should. Note that it should only fire for Wizards AND only if they do NOT have the item indicated.

Note - BioWare forums seems to dislike the class constants. The word class will only display in lowercase. This block of code does compile. 


 if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)
        {
            if (GetLevelByclass(class_TYPE_WIZARD, oPC) > 0)
            {
                if (GetItemPossessedBy(oPC, "m1_it_spellbk001") == OBJECT_INVALID)
                {
                    //Store pre-rest values for all memorized spells
                    int nSpell, nUses;
                    for (nSpell = 0; nSpell < 599; nSpell ++)
                    {
                        nUses = GetHasSpell(nSpell, oPC);
                        if (nUses > 0)
                        {
                            SetLocalInt(oPC, IntToString(nSpell), nUses);
                        }
                    }
                }
            }
        }
        else if (GetLastRestEventType()==REST_EVENTTYPE_REST_FINISHED)
        {
            if (GetLevelByclass(class_TYPE_WIZARD, oPC) > 0)
            {
                if (GetItemPossessedBy(oPC, "m1_it_spellbk001") == OBJECT_INVALID)
                {
                    //Reset spells to their pre-rest values
                    int nSpell, nUses, nStored;
                    for (nSpell = 0; nSpell < 599; nSpell ++)
                    {
                        nUses = GetHasSpell(nSpell, oPC);
                        nStored = GetLocalInt(oPC, IntToString(nSpell));
                        nStored = nUses - nStored;
                        for (nUses = 0; nUses < nStored; nUses ++)
                        {
                            DecrementRemainingSpellUses(oPC, nSpell);
                        }
                        DeleteLocalInt(oPC, IntToString(nSpell));
                    }
                }
            }

Modifié par Pstemarie, 12 août 2011 - 12:52 .


#11
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Nevermind, its working. I tied it in with the HotU Wandering Monster system since I'm planning on using that - only I hadn't activated the system yet Image IPB

Modifié par Pstemarie, 12 août 2011 - 01:02 .


#12
henesua

henesua
  • Members
  • 3 867 messages
Pstemarie, if you have trouble posting code, a utility like pastebin is really helpful. http://pastebin.com/

[edit - the rest removed as I was responding to the wrong thread.]

Modifié par henesua, 12 août 2011 - 05:12 .


#13
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Thanks Henesua

#14
Mad.Hatter

Mad.Hatter
  • Members
  • 165 messages
I don't have the code in front of me, but I know that Ed Beck's HCR2 for NWN1 limits regaining spells to once per day regardless of how many times you sleep. It decouples the two completely.

You might want to take a look at that package. It does exactly what you're describing (w/o NWNX).

Modifié par Mad.Hatter, 16 août 2011 - 01:30 .


#15
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
I have the HCR, but its a little too advanced and subsystem intensive for what we're trying to achieve. Anyway, I have the problem solved and with just a small block of code and two subscripts.

#16
Baaleos

Baaleos
  • Members
  • 1 330 messages
A more efficient method would be to use nwnx_funcs - but of course, that prob wont serve your needs if this is single player.


nwnx_funcs allows you to retrieve a ¬ delimitated string, containing the spell numbers of the spells the player currently possesses.
Meaning instead of looping 560+ times for all the spells in the game, you only loop about 40 or so, depending on how many spells the player actually has.

eg - At level 1, the loops would be maybe 3-6 for the cantrip spells.

Then nwnx_funcs also allows you to get the remaining uses of the spells, and even set them.

I would store the spell uses on Rest as a local int on the player

SPELL_USES_#### (#### = The spell id)

and then at the end of rest - when it is finished, we set the spell uses back to the value attached to the local ints.


for (nSpell = 0; nSpell < 599; nSpell ++)

Why???
Inefficiency incarnate.


Only seeing now, that Greyfort  has posted the nwnx_funcs stuff already.

Modifié par Baaleos, 16 août 2011 - 12:11 .


#17
Baaleos

Baaleos
  • Members
  • 1 330 messages

#include "x0_i0_stringlib"

string sSpellsKnown = NWNXFuncs_GetKnownSpells(oPC, 9, 0, "¬");

string sSpell = "a Spell"; // Just to kick of the initial loop

int iPos = 0;

while(sSpell != "")

      {

       sSpell = GetTokenByPosition(sSpellsKnown,"¬"iPos);

         //Do whatever you want to do to sSpell between here



        // And here

        iPos++;

      }





#18
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Baaleos wrote...


#include "x0_i0_stringlib"
string sSpellsKnown = NWNXFuncs_GetKnownSpells(oPC, 9, 0, "¬");
string sSpell = "a Spell"; // Just to kick of the initial loop
int iPos = 0;
while(sSpell != "")
{
sSpell = GetTokenByPosition(sSpellsKnown,"¬"iPos);
//Do whatever you want to do to sSpell between here

// And here
iPos++;
}


That in itself is a little ineffecent.  Where GetTokenByPosition is great (At leas in My book, I know The Krit cringed every time I used it.) for getting a single token from a string.  To use it in a loop is highly ineffecent.  The loop through all the 500+ spells is possiable more effecent then using this function in a loop.   it would be better to use the base functions from that libary instead of the By position one.  

#include "x0_i0_stringlib"
void main()
{
   struct sStringTokenizer sSpellsKnown =
      GetStringTokenizer(NWNXFuncs_GetKnownSpells(oPC, 9, 0, "¬"), "¬");

    string sSpell;
 
   while(HasMoreTokens(sSpellsKnown))
   {
      AdvanceToNextToken(sSpellsKnown);
      sSpell = GetNextToken(sSpellsKnown); // Or  sSpell = sSpellsKnown.sLastTok;
     
      //Do whatever you want to do to sSpell between here


     // And here
   }
}


Still even with that using StringParse from x3_inc_string would prabable be even more effecent.

Modifié par Lightfoot8, 17 août 2011 - 03:47 .


#19
Baaleos

Baaleos
  • Members
  • 1 330 messages
Still, I just think its better to loop through the spells we know we have, rather than the 500+ that we dont have.

Iterating through 500 rows can cause a slight freeze in server performance, and if multiple players were doing it, it would be really noticable.

#20
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Baaleos wrote...

Still, I just think its better to loop through the spells we know we have, rather than the 500+ that we dont have.

Iterating through 500 rows can cause a slight freeze in server performance, and if multiple players were doing it, it would be really noticable.


Agreed.

#21
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Only have five players on the Server, only one is a wizard (which is the only class this fires for) - so "inefficiency" isn't really an issue; its as efficient as I need it to be.