Author Topic: Applying Bonus Damage/Duration/Radius to Spells via token items  (Read 375 times)

Legacy_SKIPPNUTTZ

  • Full Member
  • ***
  • Posts: 148
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« on: November 27, 2011, 07:42:45 am »


               In the persistent world Aventia they use token items in the player's inventory to emulate the damage/duration/radius of all the spells based on how much xp over level 40 they have. This can be applied to any integer inside a spell script but is mostly used for these three examples.

Now the below function shows how this is done, which to me looks like it would run into overhead problems, especially if the player has a large inventory. I am considering just writing a variable on the player when the players login/levelup/rest instead so that inventory loops can be avoided as much as possible. Like I said, from reviewing this function and seeing how frequently it is used in almost every spell makes me cringe at how much overhead this must take. I for one have huge inventories on some of my higher level characters to item swap a lot for tougher areas, including a couple dozen bags of holding. I can only imagine how gameplay would improve if this were to be done another way.

I thought I would just ask the community what they thought in hopes of possibly finding yet an even better method to achieve the same results.


// Applies post 40 bonus to nNumber based on xp of oPlayer
int Level40PlusMagicBuff(int nNumber, object oPlayer)
{
  if ( GetHitDice( oPlayer ) >= 40 )
  {
    int nBonus;
    float fBonus;
    int nXP = GetXP(oPlayer);
    int nLevel = FloatToInt(( sqrt(( IntToFloat( nXP ) * 20 ) + 2500 ) / 100 ) + 0.5 );
    effect eBuff;

    nBonus = ( nLevel - 40 );
    fBonus = IntToFloat( nBonus ) / 100.0;

    //Checks to see if Player has a Level 4 Magic Rune
    if (GetItemPossessedBy(oPlayer, "av_itm_magerune4") != OBJECT_INVALID )
    {
      fBonus *= 2.0; //2% bonus per post40 lvl
    }
    //Checks to see if Player has a Level 3 Magic Rune
    else if (GetItemPossessedBy(oPlayer, "av_itm_magerune3") != OBJECT_INVALID )
    {
      fBonus *= 1.75; //1.75% bonus per post40 lvl
    }
    //Checks to see if Player has a Level 2 Magic Rune
    else if (GetItemPossessedBy(oPlayer, "av_itm_magerune2") != OBJECT_INVALID )
    {
      fBonus *= 1.5; //1.5% bonus per post40 lvl
    }
    //Checks to see if Player has a Level 1 Magic Rune
    else if (GetItemPossessedBy(oPlayer, "av_itm_magerune1") != OBJECT_INVALID )
    {
      fBonus *= 1.25; //1.25% bonus per post40 lvl
    }
    nNumber = FloatToInt( IntToFloat( nNumber ) * ( fBonus + 1.0 ));
  }
  return nNumber;
}



I am also interested in any feedback you all have on a good way of hooking in NPC increases here, I was thinking of just using a variable on particular boss mobs specifically, but an extra bonus for normal mobs at lvl 60 caster level would be nice too.
               
               

               


                     Modifié par SKIPPNUTTZ, 27 novembre 2011 - 08:12 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #1 on: November 27, 2011, 06:56:12 pm »


               I imagine this will work fine as is, unless you don't have a limit on inventory count (we cap at 150 items/stacks). If you're using a custom hak, I would go with feats instead.Otherwise, I would suggest using variables, the only real downside of which is that they're not readily apparent to the player unless you give them some way to check them, like a command.

If you're not limiting item count, or are worried about the overhead, you could save cycles by looping through items once at startup, looking for those runes, and setting a variableon the pc at that time (updating it when they gain a rune, obviously).

Funky
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #2 on: November 27, 2011, 10:24:03 pm »


               I Agree with funky, I just do not see the need to ever loop through the items. Every time a PC enters the game (logs in) he aquires every item he has. So all you need to do is give the items OnAquireItem and OnUnAquireItem events to set you local on the PC.

I would also say to just pack all of the items as flags(Have/NotHave) into a single Int. So you just have to retrive one Local Int to see if they have any of the items.

i,e,
const int RUNE_1 = 0x01;
const int RUNE_2 = 0x02;
const int RUNE_3 = 0x04;
const int RUNE_4 = 0x08;

So your check to see if they had level 4 magic would be as simple as.

int nMagicData = GetLocalInt ( oPC,"nMagicData");
//Checks to see if Player has a Level 4 Magic Rune
if (nMagicData & RUNE_4) fBonus *= 2.0; //2% bonus per post40 lvl
               
               

               


                     Modifié par Lightfoot8, 27 novembre 2011 - 10:26 .
                     
                  


            

Legacy_SKIPPNUTTZ

  • Full Member
  • ***
  • Posts: 148
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #3 on: November 27, 2011, 11:51:03 pm »


               This is what I put in OnAcquire:

-----
//Magic Runes

 //Checks to see if Player has a Level 4 Magic Rune
 if (sTag == "av_itm_magerune4")
 {SetLocalInt(oPC, "PC_SPELL_BONUS", 4);}

 //Checks to see if Player has a Level 3 Magic Rune
 else if (sTag == "av_itm_magerune3")
 {SetLocalInt(oPC, "PC_SPELL_BONUS", 3);}

 //Checks to see if Player has a Level 2 Magic Rune
 else if (sTag == "av_itm_magerune2")
 {SetLocalInt(oPC, "PC_SPELL_BONUS", 2);}

 //Checks to see if Player has a Level 1 Magic Rune
 else if (sTag == "av_itm_magerune1")
 {SetLocalInt(oPC, "PC_SPELL_BONUS", 1);}
-----

Then in the core function i use:

-----
   //Checks to see if Player has a Level 4 Magic Rune
   if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 4)
   {fBonus *= 2.0;} //2% bonus per post40 lvl

   //Checks to see if Player has a Level 3 Magic Rune
   else if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 3)
   {fBonus *= 1.75;} //1.75% bonus per post40 lvl

   //Checks to see if Player has a Level 2 Magic Rune
   else if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 2)
   {fBonus *= 1.5;} //1.5% bonus per post40 lvl

   //Checks to see if Player has a Level 1 Magic Rune
   else if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 1)
   {fBonus *= 1.25;} //1.25% bonus per post40 lvl

-----

All the items are undroppable/plot and can only have one at any given time. So the above should work fine right? I plan on players having to improve their runes as they progress through content and succeed at certain challenges. So the transition from a lvl 1 rune to a lvl 2 rune should work fine without even editting the unacquire event unless I am missing something >.>

I appreciate your feedback fellas, trying to refine this relic system as much as a can. Aventia has been around a very long time and needs a few updates here and there to make things more efficient.

I also added this little section for NPCs, if I wanted to give certain monsters increased dmg. Any thoughts? All spells are uncapped, so they already gain a little advantage by having 60 caster lvls on damage dice, etc.. but I figured for my more elite areas I wanted a little something special in place to compensate for the fact that I haven't found a way to give them more than 60 caster lvls. I was hoping to do this by editting monster blueprints in leto but it hasnt seemed to produce any results yet.

-----
 else if (!GetIsPC(oPlayer) && nHD >= 60)
 {
   nBonus = ( nHD - 60 );
   fBonus = IntToFloat( nBonus ) / 100.0;

   //NPC Level 5 Spell Bonus
   if      (GetLocalInt(OBJECT_SELF, "NPC_SPELL_BONUS") == 5)
   {fBonus *= 25.00;} //25% bonus per post60 lvl

   //NPC Level 4 Spell Bonus
   else if (GetLocalInt(OBJECT_SELF, "NPC_SPELL_BONUS") == 4)
   {fBonus *= 20.00;} //20% bonus per post60 lvl

   //NPC Level 3 Spell Bonus
   else if (GetLocalInt(OBJECT_SELF, "NPC_SPELL_BONUS") == 3)
   {fBonus *= 15.00;} //15% bonus per post60 lvl

   //NPC Level 2 Spell Bonus
   else if (GetLocalInt(OBJECT_SELF, "NPC_SPELL_BONUS") == 2)
   {fBonus *= 10.00;} //10% bonus per post60 lvl

   //NPC Level 1 Spell Bonus
   else if (GetLocalInt(OBJECT_SELF, "NPC_SPELL_BONUS") == 1)
   {fBonus *= 5.00;} //5% bonus per post60 lvl

   nNumber = FloatToInt( IntToFloat( nNumber ) * ( fBonus + 1.0 ));
 }
 return nNumber;
               
               

               


                     Modifié par SKIPPNUTTZ, 28 novembre 2011 - 12:04 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #4 on: November 28, 2011, 12:27:23 am »


               Yes you can go that route.  But you can cut the code down and make it easier to expland later if needed. 
First on the  aquire script:  

SKIPPNUTTZ wrote...

//Magic Runes

//Checks to see if Player has a Level 4  Magic Rune
if (sTag == "av_itm_magerune4")
{SetLocalInt(oPC, "PC_SPELL_BONUS", 4);}

//Checks to see if Player has a Level 3 Magic Rune
else if (sTag == "av_itm_magerune3")
{SetLocalInt(oPC, "PC_SPELL_BONUS", 3);}

//Checks to see if Player has a Level 2 Magic Rune
else if (sTag == "av_itm_magerune2")
{SetLocalInt(oPC, "PC_SPELL_BONUS", 2);}

//Checks to see if Player has a Level 1 Magic Rune
else if (sTag == "av_itm_magerune1")
{SetLocalInt(oPC, "PC_SPELL_BONUS", 1);}
-----



you can me it look more like this:
 
 //Checks to see if Player has a  Magic Rune
if (GetStringLeft(sTag,15) == "av_itm_magerune")
   SetLocalInt(oPC, "PC_SPELL_BONUS", StringToInt(GetStringRight(sTag,1)));

That will take of the runes from 1 to 9
----

then since your bonus increase is following a liner format you can change  all of this:

//Checks to see if Player has a Level 4 Magic Rune
if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 4)
{fBonus *= 2.0;} //2% bonus per post40 lvl

//Checks to see if Player has a Level 3 Magic Rune
else if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 3)
{fBonus *= 1.75;} //1.75% bonus per post40 lvl

//Checks to see if Player has a Level 2 Magic Rune
else if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 2)
{fBonus *= 1.5;} //1.5% bonus per post40 lvl

//Checks to see if Player has a Level 1 Magic Rune
else if(GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS") == 1)
{fBonus *= 1.25;} //1.25% bonus per post40 lvl


To:

//We dont even need to check if it is set or not.
fBonus *= 0.25*GetLocalInt(OBJECT_SELF, "PC_SPELL_BONUS")+ 1 ;

You can also do the same thing with your one for NPC's since it is also liner. 
               
               

               
            

Legacy_SKIPPNUTTZ

  • Full Member
  • ***
  • Posts: 148
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #5 on: November 28, 2011, 01:25:43 am »


               Very nice points, thanks a lot Lightfoot. I really need to get in the habit of simplifying things and keeping the code to a minimum, but that will come in practice. I would have eventually done this '<img'>

I haven't found a way to give them more than 60 caster lvls. I was hoping to do this by editting monster blueprints in leto but it hasnt seemed to produce any results yet.


However, i still really want to find a way to give them more caster lvls for other game mechanics. Is this at ALL possible? I swear I have seen some DM avatars that had like 120 in a single class lvl...... That could have been the drugs I was taking back then though >.>

Also interested in knowing about any temp hp or max hp overflow values I might encounter. I think HP are stored as a 16 bit integer so.. would that allow me to give up to 65,535 hp? Or would it be from −32,768 to 32,767. 32k Hp isnt a aweful lot when players can do so much dmg in my PW, even with %immunes and other dmg mitigation, that would severely limit life expectancy of bosses.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #6 on: November 28, 2011, 02:14:08 am »


               You can code casterlevels as high as you like, but you have to recode all your spells - it's a major project.

As for temp hit points, they aren't much use, since they can't be healed, if you're talking numbers that large. You can use massive regeneration to effect varying degrees of boss difficulty, though. Just apply it as a Su effect - we've used up to 500/round, though that's on Demogorgon, and was his primary defensive attribute.

Funky
               
               

               
            

Legacy_SKIPPNUTTZ

  • Full Member
  • ***
  • Posts: 148
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #7 on: November 28, 2011, 02:35:14 am »


               Yah I currently use massive regen combined with %immunes. Only time I utilize temporary hit points is to create an "absorb" type effect on certain encounters to make players have to dps down a shield before they can start hacking at the boss's true health, I guess it is kinda like an Epic Warding vs ALL dmg. However without leto editting the monster's CON to 242, effective health pool caps somewhere around 21k with feats. Im guessing there is a way to set this CON value to 242 via scripting, just havent bothered with it yet. That gets me closer to 32k i think.

-----

I guess these features will work if I implement a new system for lvl40+ bonus dmg increases to apply to weapons instead of using EffectDamageIncrease(). As it is now, melee characters can get up to +20 damage in every single type using this function. I think all damage types except physical will ignore immunity/resists, so that leaves endgame players dealing a guaranteed 180+ dmg per hit on monsters that are 100% immune to all damage. >.>

I am currently thinking about what you told me Funky, where I should check the players weapon for X damage type, and then add this extra bonus damage they recieve as their post40 bonus to what is already on their weapon. But that seems complicated to me. I do have the iprp_damagecost 2da you sent me, sounds like that will be the only way around this problem since I use windows/nwx2.
               
               

               


                     Modifié par SKIPPNUTTZ, 28 novembre 2011 - 02:38 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #8 on: December 17, 2011, 10:41:17 am »


               Just for the record, this individual (Skippnutz) does not represent Av3.
               
               

               


                     Modifié par Lazarus Magni, 17 décembre 2011 - 08:46 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Applying Bonus Damage/Duration/Radius to Spells via token items
« Reply #9 on: December 17, 2011, 11:32:31 am »


               

FunkySwerve wrote...

You can code casterlevels as high as you like, but you have to recode all your spells - it's a major project.


Not anymore, my unofficial Patch allows to override caster level, metamagic or DC via variable to any desired value and what is best - no scripting required to do that.
               
               

               


                     Modifié par ShaDoOoW, 17 décembre 2011 - 12:22 .