Author Topic: Semi-Permanent Level Drain  (Read 498 times)

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Semi-Permanent Level Drain
« on: May 30, 2016, 05:04:54 pm »


               

I'd like to apply level drain to a PC that can only be removed after a certain amount of time has passed.


 


Resting, restoration, and relogging (and other ways of removing level drain by the player) should have no effect.


 


The player must wait for the duration to end, and then the level drain would automatically be removed. I'm using this as a respawn penalty.


 


I've been wanting to implement this for years now, but I couldn't find a solution on my own.


 


Any help will be appreciated.



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #1 on: May 30, 2016, 06:25:20 pm »


               

The only way I know of doing this would be to have a scripted method set the pc's xp's to the amount desired, then after a delay restore the xp's removed. There are dangers in this approach. Unless you use an external database or have a persistent local storage system , ie a no drop item to store the info on, should a pc log out and a server reset occur, the xp's are permanently lost. You can use the default BW store campaign methods, but I just never use them myself.


 


Let me know what persistent system you use and I, or someone else, can create the desired code np.



               
               

               
            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #2 on: May 30, 2016, 07:45:44 pm »


               

Well, I know this is possible using the level drain status effect, because years ago a server I played on had the same system. I just never could figure out how they did it.


 


My server is running nwnx odbc on linux.


 


Just halving a PC's XP wouldn't work in this case, because my server is local vault.



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #3 on: May 30, 2016, 09:14:25 pm »


               

it is still doable on a local vault, but much trickier cause you need to do a check against player, character from on leave to verify no xp modification between leave and enter. Still, it's a messy situation when local vault allowed. What if a player exits and plays on their own machine, then comes back.....that would break the purpose. What you would effectively be doing is forcing a server vault effect on a local vault.


 


Another way to get what you want would be to modify all scripts for potions, spells, etc that remove the specific effect and modify the scripts applying the effect to include a delayed remove effect timer. Much more work to find all references involved.



               
               

               
            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #4 on: May 30, 2016, 11:48:01 pm »


               

Thanks for the responses KMdS '<img'>


 


Yes, it gets trickier with local vault. Wouldn't stripping XP also cause the player in question to have to relevel once the XP is regained? As a respawn penalty this would be too cumbersome IMO...


 


Here is the beginning of my testing:



#include "NW_I0_GENERIC"

void main()
{
    object oTarget = GetLastUsedBy();
    int iLevel = GetCharacterLevel(oTarget);
    int iHalfLvl = iLevel / 2;
    effect eDrain = SupernaturalEffect(EffectNegativeLevel(iHalfLvl));
    effect eVis = EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY);

    SendMessageToPC(oTarget, IntToString(iHalfLvl));

    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);

    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDrain, oTarget);
}

Unfortunately SupernaturalEffect still enables the PC to remove the level drain via restoration or greater restoration. Resting won't remove it with SupernaturalEffect though, which is good.



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #5 on: May 31, 2016, 01:20:29 am »


               

Yes, the pc would need to re-level if you modified their xp's, but the second option of modifying scripts is something that can be done without negative impact on your server as the effect would be gone on server reset and a recursive loop could be programmed for should the player log out and relog later during the same session. It is more work though. Spells could be hooked though to simplify things.



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #6 on: May 31, 2016, 01:26:13 am »


               

Oh yes, just remembered something....


 


Modify the script to have an npc apply the effect, have this npc in a non playable area where no one but a dm could access. this way you could still allow the level drain effect occur and be dispellable by regular means, just have the dispel effect check for the creater of the effect and no process if the nps created the effect. Have the instances that are created by the npc run off the timer mentioned above.


 


I know, this is a bit of work, but just offered in case you thought you might want to do it.



               
               

               
            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #7 on: May 31, 2016, 01:30:31 am »


               

Interesting ideas...


 


How would you recommend scripting the timer? Does DelayCommand(); still work through player relogs? How would you create the "recursive loop?"



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #8 on: May 31, 2016, 02:49:12 am »


               

The simplest way is to place a check to see if the object you are running the delayed method on is not valid..if(!GetIsObjectValid(OBJECT_SELF))... if not, run the delayed method again passing the same object, setting the delay loop to whatever delay you wish. the loop will run until either the pc logs back or the server resets.


 


Another way is to use a local variables flag, SetLocalInt(GetModule(), "DELEVEL_TIMER_DELAY_DONE", TRUE) for example;  if the pc is not found at the end of the delay, add a method to or add code withing the on enter script to search for the flag signifying the delay has ended and remove the effect. This way you don't have a looped routine running the rest of the time the server is up.


 


The later is the cleanest way to run this, but unless you have a very large server load, either would be satisfactory.



               
               

               
            

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #9 on: May 31, 2016, 05:47:14 am »


               

Would it be possible to simply apply the level decrease effect as a temporary supernatural effect of whatever duration you intend and whose creator has tag q6e_ShaorisFellTemple? That's the tag of the creator whose effects the Restoration line of spells is already scripted not to remove because it is part of the plot on Shaori's Fell in Chapter 2 of HotU. I think may make good use of code that already exists in the Restoration spells and should avoid issues with toons who log out before the effect is removed, since it will simply expire when you have set it to. You might simply create an object somewhere in the module (possibly in a DM area, possibly even an invisible one) with that tag and have it apply the effect to the toon when he respawns.


 


It's worth noting, of course, that the HotU script that applies the effect takes care to have the toon unequip items with immunity to ability drain as a property before applying the effect. In fact, you could start with the code that's already in q6e_area_ud.nss for most of this. Just change the duration type to temporary and give whatever duration you wand. Then pare off the other parts you don't need.


 


(BTW, I am assuming that you are open to simply applying a level decrease effect and actually removing XP isn't a necessary party of this.)



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #10 on: May 31, 2016, 06:19:20 am »


               

Absolutely, that is what I thought you were doing. Sounds like a good way to re-purpose existing code. I would take a look and study the code to be sure it has nothing you don't want included though.



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #11 on: May 31, 2016, 09:20:54 am »


               You could change the spell scripts, adding a final command which reinstates the supernatural effect if the PC has the flag set.

The scripts can be identified by searching for "restoration" in spells.2da.

Purists may prefer spell hooking.
               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #12 on: May 31, 2016, 04:00:30 pm »


               


Purists may prefer spell hooking.




Purists.......funny idea '<img'> , but you are right, hooking is cleaner and is better practice. Also, should there ever be an update from BW or a third party, let's not hold our breaths for a BW update  '<img'> , it would avoid having your scripts possibly written over by the update.


               
               

               
            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #13 on: May 31, 2016, 04:06:49 pm »


               

I used the q6e_ShaorisFellTemple tag to apply the level drain effect. It works flawlessly.


 




The simplest way is to place a check to see if the object you are running the delayed method on is not valid..if(!GetIsObjectValid(OBJECT_SELF))... if not, run the delayed method again passing the same object, setting the delay loop to whatever delay you wish. the loop will run until either the pc logs back or the server resets.




 


I'm having trouble creating the DelayCommand loop that checks for an invalid PC object (eg. logged off PC). Could give me a code example, KMdS?



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Semi-Permanent Level Drain
« Reply #14 on: May 31, 2016, 06:39:05 pm »


               

void foo(object oPC, float fDelay = 60.0f)
{
    if(!GetIsValid(oPC))
    {
        DelayCommand(fDelay, foo(oPC));
    }
    else
        *your code to reinstate the pc
}

 


Since the delay is predefined in the method parameters, the call to foo only needs to have the object oPC passed to it. This would be an include to whatever method you use.


 


Alternately, should you perform the above routine by using an "ExecuteScript" method from your script, the following would be an example


 


//foo.nss
 
void main()
{
    oPC = OBJECT_SELF;
    if(!GetIsValid(oPC))
    {
        DelayCommand(60.0f, ExecuteScript(oPC, "foo"));
    }
    else
        *your code to reinstate the pc
}

 


This second option does not directly allow you to set the delay interval unless you set up some local variable you can retrieve from the script by adding code and modifying the delay t the retrieved local.


 


I did this w/o reference material and w/o using a text editor so forgive any missed semi colons or other minor stuff.