Author Topic: Help with this script  (Read 353 times)

Legacy_Tonden_Ockay

  • Hero Member
  • *****
  • Posts: 891
  • Karma: +0/-0
Help with this script
« on: July 08, 2015, 12:29:52 pm »


               

Ok I downloaded a module plan to use to play NWN with and to help me learn some thing about NWN scripting. I picked this module because it was a large PW that was mostly all done and it has some really nice scripts in it like the following





void fCheckItemBreakage(object oItem, int iBonus=0)
    {
    int iChance;
    int iCharges = GetItemCharges(oItem);
    object oPC = GetItemPossessor(oItem);

    if(iCharges==0)
        {
        iCharges=50;
        }

    iCharges = iCharges - (d8(2));
    iChance = -(iCharges) + iBonus + 20;

    string sName = GetName(oItem);

    if (d100(1)<=iChance || iCharges<=0)
        {

        DestroyObject(oItem);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_RESTORATION), oPC);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), oPC);
        AssignCommand(oPC, PlaySound("as_cv_claybreak3"));
        DelayCommand(2.0, FloatingTextStringOnCreature(sName + " shatters!", oPC, FALSE));
        }
    else
        {
        SetItemCharges(oItem, iCharges);
        DelayCommand(2.0, FloatingTextStringOnCreature(sName + " was damaged!", oPC, FALSE));
        }

    }

void fDoItemBreakage(object oPC)
    {

    //SendMessageToPC(oPC, "DEBUG - Durability check fired...");

    if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC),30);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC),30);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_NECK, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_NECK, oPC),10);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC),10);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_BELT, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_BELT, oPC),10);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC),20);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC),30);}

    }

void fCheckDurabilityItem(object oItem, int iCombat)
    {
    if(!GetIsObjectValid(oItem))
        {return;}

    //int iDurTicker = 1; // How many hits before a charge minus
    int iRandom;
    if (iCombat==1)
        {iRandom=d4(1);}
    else
        {iRandom=(d8(2)-1);}

    if (iRandom==1) //supposed to be ==1
        {

        int iCharges = GetItemCharges(oItem);
        if(iCharges==0)
            {
            SetItemCharges(oItem, 50);
            return;
            }

        /*
        int iCurrTick = GetLocalInt(oItem, "durability_ticker");
        if (iCurrTick==0)
            {
            SetLocalInt(oItem, "durability_ticker",iDurTicker);
            }
        else
            {
            SetLocalInt(oItem, "durability_ticker",iCurrTick-1);
            //SendMessageToPC(GetItemPossessor(oItem), "Durability tick " + GetName(oItem));

            return;
            }
        */

        //SendMessageToPC(GetItemPossessor(oItem), "Durability " + GetName(oItem));
        int iNewCharges = GetItemCharges(oItem)-1;
        if (iNewCharges<=0)
            {iNewCharges==0;}

        object oPC = GetItemPossessor(oItem);
        switch(iNewCharges)
            {
            case 49:

                FloatingTextStringOnCreature(GetName(oItem) + " is no longer pristine condition", oPC, FALSE);
                break;

            case 40:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 35:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 30:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 25:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 20:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 15:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 10:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 5:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 3:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 2:

                FloatingTextStringOnCreature(GetName(oItem) + " at " + IntToString(iNewCharges*2) + "%", oPC, FALSE);
                break;

            case 1:

                FloatingTextStringOnCreature(GetName(oItem) + " is about to fall apart", oPC, FALSE);
                break;

            case 0:

                FloatingTextStringOnCreature(GetName(oItem) + " has fallen apart!", oPC, FALSE);
                break;

            }

        if (iNewCharges<=0)
            {
            DestroyObject(oItem);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_RESTORATION), oPC);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), oPC);
            AssignCommand(oPC, PlaySound("as_cv_claybreak3"));
            }
        else
            {
            DelayCommand(1.0, SetItemCharges(oItem, iNewCharges));
            }

        }
    }

void fDoDurabilityCheck(object oPC)
    {

    //SendMessageToPC(oPC, "DEBUG - Durability check fired...");

    int iCombat;
    if (GetIsInCombat(oPC))
        {iCombat=1;}

    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_BELT, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC), iCombat);
    fCheckDurabilityItem(GetItemInSlot(INVENTORY_SLOT_NECK, oPC), iCombat);

    }

void fItemDurabilityHB(object oPC)
    {
    //SendMessageToPC(oPC, "Durability HB fired");
    if (!GetIsDead(oPC) && GetCommandable(oPC))
        {
        if (d3(1)==1)
            {
            DelayCommand(IntToFloat(d3(1)), fDoDurabilityCheck(oPC));
            return;
            }
        }
    }


int fGetResRefQuality(object oItem)
    {
    return StringToInt(GetStringRight(GetResRef(oItem),3));
    }


//void main(){}


First to me it looks like items have a %1 chance out of d100 to brake at 49, 40, 35, 30, 25, 20, 15, 10, 5, 3, 2, 1, 0. Am I right on this? Because if so I only want there to be a chance to brake on 0. So I that is the case then I should just be able to delete all the other lines right?


 


Second it looks to me that each item has 50 charges. because of the following lines I see in the script


 


if(iCharges==0)

{

iCharges=50;

}


 


and 


 


int iCharges = GetItemCharges(oItem);

if(iCharges==0)

{

SetItemCharges(oItem, 50);

return;

}


 


 


I'm no scripter so I am just trying to read this and understand it. But these lines lead me to believe each items starts with 50 charges.


 


However I'm not sure what the lines are for or do


 


iCharges = iCharges - (d8(2));

    iChance = -(iCharges) + iBonus + 20;

 

 

 

 

Now looking at the following lines

 

if (iCombat==1)

{iRandom=d4(1);}

else

{iRandom=(d8(2)-1);}

 

I'm also guessing that an item loses 1 + 1d4 or 1d8 charges per combat. Is that per creature they are in combat with? or is that per combat round? So if a fight lasts 10 rounds they would loss this each round?

 

 

So am I reading this right? I would like to make some changes to it but first I would like to know that I am reading it right so I could make the correct changes I would like to make.


               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Help with this script
« Reply #1 on: July 08, 2015, 02:10:08 pm »


               


First to me it looks like items have a %1 chance out of d100 to brake at 49, 40, 35, 30, 25, 20, 15, 10, 5, 3, 2, 1, 0. Am I right on this? Because if so I only want there to be a chance to brake on 0. So I that is the case then I should just be able to delete all the other lines right?




 


No, that's for doing feedback. It reports when your item reaches one of those charge levels (2 percent per charge) and reports the new status of the item. It already destroys the item only when it reaches 0 charges.


 


There seem to be two mechanisms in there. One is not used by that code. It may be called somewhere else, like from taking fireball damage or falling or whatever. That's the fDoItemBreakage and fCheckItemBreakage part.


 


The code setting the charges to 50 is to initialize the item. This means the builder does not have to go through and change all the item blueprints to have 50 charges to make them in pristine shape. This system never allows an item to survive with 0 charges so any item found with 0 must be new. 


 


Each time the HB fires there is a chance to check each item. If an item is checked there is a further chance that it may take damage.


If so it takes 1 charge of damage.  The second chance is this code



if (iCombat==1)
{iRandom=d4(1);}
else
{iRandom=(d8(2)-1);}

So each round of combat there is a 1 in 3 chance of checking, and then for each item there is a 1 in 4 if in combat or 1 in 15 if not chance of taking a charge damage.


 


This is a somewhat interesting system where did you find it?


 


There are some quirks though, like if you equip a magic staff that has charges it will be losing charges this way and it's status will be based on the charges it has for casting spells.  It could be done with a local variable instead of the charges.  But then you would have to add something to report status not just when it takes damage. I suppose the number of charges shows up in game even if the item does not have a property that uses charges, but I have not checked.


               
               

               
            

Legacy_Tonden_Ockay

  • Hero Member
  • *****
  • Posts: 891
  • Karma: +0/-0
Help with this script
« Reply #2 on: July 08, 2015, 04:42:03 pm »


               

“No, that's for doing feedback. It reports when your item reaches one of those charge levels (2 percent per charge) and reports the new status of the item. It already destroys the item only when it reaches 0 charges."


 


 Ok got that


 


“The code setting the charges to 50 is to initialize the item. This means the builder does not have to go through and change all the item blueprints to have 50 charges to make them in pristine shape. This system never allows an item to survive with 0 charges so any item found with 0 must be new.”


 


Ok so I could just change the 50 to lest say 100 then items would have 100 charges right?


 


“Each time the HB fires there is a chance to check each item.”


 


Is this the (iRandom=d4 (1) ; } if so I could just change the d4 to say a d10 to make it have a less of a chance to check?


 


“If an item is checked there is a further chance that it may take damage.”


 


Is this the (iRandom=(d8(2)


 


“If so it takes 1 charge of damage.  The second chance is this code”


 


Is this the -1);}



if (iCombat==1)
{iRandom=d4(1);}
else
{iRandom=(d8(2)-1);}

"So each round of combat there is a 1 in 3 chance of checking"


 


I am guessing your talking about the following



//SendMessageToPC(oPC, "DEBUG - Durability check fired...");

    if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC),30);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC),30);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_NECK, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_NECK, oPC),10);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC));}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC),10);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_BELT, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_BELT, oPC),10);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC)) && d3(1)==1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC),20);}

    else if (GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) && d3(1)!=1)
        {fCheckItemBreakage(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC),30);}


So I could just change the d3 to say a d10 which would make it happen less often.


 


"then for each item there is a 1 in 4 if in combat"


 


I take it that you are talking about the following.



//int iDurTicker = 1; // How many hits before a charge minus
    int iRandom;
    if (iCombat==1)
        {iRandom=d4(1);}

"or 1 in 15 if not chance of taking a charge damage."


 


I didn't see the 1 in 15 chance


               
               

               
            

Legacy_Tonden_Ockay

  • Hero Member
  • *****
  • Posts: 891
  • Karma: +0/-0
Help with this script
« Reply #3 on: July 08, 2015, 04:45:07 pm »


               

Oh and the script came from the World of Torr PW module here on the vault. Drdread made the module a long with all his own scripts. I talked with him and he said I could do what I want with the module. So I am looking to use it and tweak it a bit for my style of play.


 


Thanks for the insight on the script  meaglyn



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Help with this script
« Reply #4 on: July 08, 2015, 06:50:09 pm »


               

Ok so I could just change the 50 to lest say 100 then items would have 100 charges right?


 


No. I think 50 is as high as you can set charges but I may be mistaken about that. He's using 50 * 2 to make a range up to 100%.


 


“Each time the HB fires there is a chance to check each item.”


 


Is this the (iRandom=d4 (1) ; } if so I could just change the d4 to say a d10 to make it have a less of a chance to check?


 


No... that's the if (d3(1)==1) in fItemDurabilityHB.


 


“If an item is checked there is a further chance that it may take damage.”


 


Is this the (iRandom=(d8(2)


 


No... this is the stuff near the beginning of fCheckDurabilityItem. If in combat it does it one in 4, if not in combat it's 1 in 15. Remember the HB will fire every 6 seconds regardless of whether or not combat is going on (assuming fItemDurabilityHB, as the name implies is called from something running on the heartbeat).


 


 


“If so it takes 1 charge of damage.  The second chance is this code”


 


Is this the -1);}


 


No, it's here (yes, it's a -1 but no it's not that one you showed).



int iNewCharges = GetItemCharges(oItem)-1;


"So each round of combat there is a 1 in 3 chance of checking"


 


I am guessing your talking about the following


 



 


 


No. I should not have said each round of combat although it would be about that. I should have said each time the HB routine runs.


See above.


 


 




"then for each item there is a 1 in 4 if in combat"


 


I take it that you are talking about the following.


 


"or 1 in 15 if not chance of taking a charge damage."


 


I didn't see the 1 in 15 chance


 


 



 


d8(2) - 1  from here



int iRandom;
if (iCombat==1)
{iRandom=d4(1);}
else
{iRandom=(d8(2)-1);}

if (iRandom==1)

The frist two routines fCheckItemBreakage and fDoItemBreakage are not part of the HB system. You can ignore those for now.  As I said it looks like that part is designed to damage to all the PC's equipment when something really bad happens. But fDoItemBreakage would need to be called by some other script. It is not used here.


 


 


P.S. please use colors that show up, whatever you are using there I have to highlight it to see it.