Author Topic: Scripting a "Passive" Feat  (Read 387 times)

Legacy_Raetzain

  • Newbie
  • *
  • Posts: 13
  • Karma: +0/-0
Scripting a "Passive" Feat
« on: October 20, 2015, 10:47:39 pm »


               

Hello forum-goers,


 


I'm trying to implement some passive feats that do some very rudimentary things to skills and the like. I haven't yet written the scripts that actually modify those skills because I'm not quite certain how to. I've implemented active feats in the past, but those have uses and targeting attached that tell the script to fire. My question is whether, with a passive feat, I can just script something simple using EffectSkillIncrease as a static script - or do I have to do something complicated, like bury a whole list of "GetHasFeat"s in the On Module Load script or Heartbeat.


 


This is for a persistent world, so I am partially worried about a few things, like the script firing multiple times and increasing skills every time.


 


Thanks,


Raetzain



               
               

               
            

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Scripting a "Passive" Feat
« Reply #1 on: October 21, 2015, 05:23:19 am »


               

This isn't something I have played with, and the approach may very depending on just how the feat is supposed to work. A simple feat that gives a skill bonus or something as a permanent supernatural effect is one thing. A passive feat that causes all undead nearby to make a will save or flee might might work best with a different implementation.


 


But, it seems that there are a couple of events where many scripted passive feats could be activated without bogging the server down with extra heartbeat checks.  First, the OnPlayerLevelUp event, to catch the feat when it is first acquired. Second, the OnPlayerRespawn event to catch the player revived from death, since most effects are removed on death. Between those two events, you could implement plenty of feats and not require a heartbeat check. And, even with GetHasFeat, a script that only runs on level-up and on respawn should be infrequent enough not to cause lag issues.


 


(Of course, if the scripted feat is intended to work as an item property as well, then you would have to also run checks on the OnAcquireItem/OnUnacquire or OnPlayerEquipItem/OnPlayerUnequipItem events, too.)


 


Anyway, people probably have plenty of other good ideas about this, but that might get you started.



               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Scripting a "Passive" Feat
« Reply #2 on: October 21, 2015, 01:23:14 pm »


               

Passive feats are easy - if you have the right tools.


I am hoping you have nwnx and some sort of event handling plugin.


 


 


On my server, I use a special version of nwnx_cool that I built with a hook that does onDamageEffectHandled


 


Basically allows me to accurately catch damage before it gets applied to the character. I can then negate the damage, or add more damage etc


 


So how does this turn into a passive feat.


 


 


Lets imagine I make a feat called 'Brimstone Blood' - where the bearer of this feat is actually immune to fire, and infact heals from the fire.


 


When damage is applied to the character/creature - the hook will fire.


 


I just need to determine within the hook - do we have a specific feat that affects the damage.


 


if(GetHasFeat(oPC, BRIMSTONE_BLOOD) == true)


{


        effect eHeal = EffectHeal(FireDamage);


        FireDamage = 0;


        ApplyEffectToObject(oPC,DURATION_TYPE_INSTANT,eHeal);


        bOverride = true;


}


 


 


This is somewhat pseudocode of what my hook does - 


basically It assumes at first it will get through the entire hook without having to modify any damage.


But then it hits the 'if' statements.


If any of them result in modifications to damage - then the Override boolean is set to true (from false)


This then tells nwnx to read the new damage value from local vars on the character/creature, and set them before the hook finishes.


 


 


This sounds quite complex - but once you have it setup, its quite flexible.


Adding to the system is as simple as modifying a single script etc


 


I've done things using this system to make it so bosses can do 80% more damage, and certain damage types get negated completely etc


Doing something like that for a boss is as simple as saying


 


 


//oPC is actually the creature running the hook on themselves - so oPC being a boss, refers to damage received by the boss


if(GetResRef(oPC) == "boss_creature")


{


        boss is being damaged, make the battle more difficult by reducing damage numbers by 50%


}


 


//oDamager could be the person/creature inflicting the damage


if(GetResRef(oDamager) =="boss_Creature")


{


      boss did the damage - so increase it by 80%


 


}


 


 


 


One other system I hooked into this hook is a system I called 


'Cursed with the Power'  (I usually give RP names to the systems I develop for Worlds of Rhun)


 


Basically - God players on my server, are able to curse other players with magical powers which are not completely within their control.


I actually got the idea from Frozen and Once Upon a Time - the episodes with Elsa etc


 


Using the above hook, I was able to make it so players who are cursed (ie: have the cursed feat) 


Receive no damage from their element-  but receive 20% more damage from opposing elements.


Eg: Cold Immune, but fire weak.


 


The not being in control bit is implied by clumsy accidental bursts of power the player can do.


Eg: They can teleport using the power, but they have a chance of stumbling when they arrive at the destination, resulting in knockdown.


(Continuous use of teleport will reduce the chance of this occuring - as they become more experienced)


 


Other powers include shooting magical blasts of energy with the element of their curse.


Eg: A flame burst if they are cursed with magical fire.


Once again - inexperience in the power can result in accidental backfiring etc


 


Anyway- I kinda got off topic there.


But the system I described is a mix of passive and active feats.


(Well.. technically - the Feat is both - it is usable as an active feat, but it also has passive effects - processed by nwnx_cool )


 


I am unsure if the onDamageEffectHandler is hooked in linux anywhere - if it were, I would be very inclined to move to Linux.


Alas - a few months ago - I don't recall it existing anywhere in linux, so I kept using windows.



               
               

               
            

Legacy_bdtgazo

  • Jr. Member
  • **
  • Posts: 98
  • Karma: +0/-0
Scripting a "Passive" Feat
« Reply #3 on: October 21, 2015, 04:12:56 pm »


               

I would certainly avoid onHeartbeat for checks like that.  For passive feats, you might have a trigger script from the starting/entry zone to wherever the PC ports to after they have entered the mod.  You could put the feat check script on the onenter script for the trigger (or whatever/wherever you handle the porting).  That is what I do for various checks.


               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Scripting a "Passive" Feat
« Reply #4 on: October 21, 2015, 04:44:18 pm »


               

keeping your scripts concise and event driven is usually the best way to go with passive feats.


Eg: If it gives a damage resistance - try to apply that resistance at attack time (via nwnx if you need to)


opposed to refreshing a damage resistance effect every 60 seconds in a loop.


 


 


The one thing I would say about heartbeats for passive effects - is that they are usually useful for integer incrementing for use in larger systems.


Many other systems such as subrace engines already use the default.nss file for heartbeats - so consider putting smaller subroutines in there.


Larger ones might be best left in scripts of their own, and executed sparingly.


 


Eg: I have a god subrace - every 60 seconds he gets faith added to his pool of faith points.


      I also do alot of extra things within that 60 second subroutine.


      EG: Determine if he has run out of faith, if so, remove levels, ability scores, toggle off his immortality, invisibility etc until he has reached a level of existence that he can afford with his faith income.


     


Because this is arguably alot of content for a heartbeat script - I minimize its impact by ensuring it only has one concurrent run per 60 seconds.


 


Eg:


The module runs it on itself


every 60 seconds


it loops through players


if the player is a god, then go into the subroutine


if the player is not a god, do nothing


 


So while I am using God subrace as an example - you could still use the same logic for feat passives.



               
               

               
            

Legacy_Raetzain

  • Newbie
  • *
  • Posts: 13
  • Karma: +0/-0
Scripting a "Passive" Feat
« Reply #5 on: October 21, 2015, 05:01:02 pm »


               

Thanks for the quick and fast replies, forum-dwellers.


 


We do have NWNX and you gave me some seriously cool ideas on other feats that I could possibly code that I actually hadn't put much thought into. So, thank you for that, Baaleos. Since all of these passive feats are just static skill bonuses for classes acquired as a class levels or as a "background" (for now, at least), I think I'm going to take MrZork's suggestion and just slide in a few 'if' statements into the module's OnLevelUp and OnRespawn scripts. If I try and do something bold with damage resistances and making bosses much harder as they start to die, I'll be sure to stop on by and show off my ineptitude at scripting.


 


Thanks,


Raetzain



               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Scripting a "Passive" Feat
« Reply #6 on: October 22, 2015, 05:21:59 am »


               

Im using skin and add bonuses to skills, immunities, and other itemproperties there. Of course, there is an issue with losing skin on relog if your server has ILR or ELC on. However, my community patch fixes this and its not even needed to fix since normally in every event Im cleaning all skin itemproperties and adding them again so if you lose skin you can give new one and everythign will work fine.


 


I have this done in single script which Im executing from OnClientEnter, OnLevelUp, OnLevelDown and possibly few more but I dont remember, either way the advantage of skin is that you dont need to reapply the effect at OnRespawn and OnResurrect (which you need to script too).


 


If you want to make a passive feat with conditions on certain armor/weapon type then you would need to add OnEquip and OnUnequip events into this, or do new script as mostly these feats can give bonuses to the said armor/weapon so there is no need to give this on a skin. But if it would be neccessary its not a problem at all of course.