logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Creature->DoDamage hook
Goto page Previous  1, 2
 
Post new topic   Reply to topic    nwnx.org Forum Index -> Windows development
View previous topic :: View next topic  
Author Message
Baaleos



Joined: 02 Sep 2007
Posts: 816

PostPosted: Sat Sep 14, 2013 20:52    Post subject: Reply with quote

Hi Guys,
Took your advice on board.

I moved the new char[] statement above the if statement - and have it deleted now before exiting the hook.


I also managed to map the EffectDamage ints with the help in this thread.


Quote:


0 = Bludgeoning
1 = Piercing
2 = Slashing
3 = Magical
4 = Acid
5 = Cold
6 = Divine
7 = Electrical
8 = Fire
9 = Negative
10 = Positive
11 = Sonic


In many ways, this hook is more advanced than the inbuilt onDamaged event that creatures have - as this actually allows you to manipulate the damage numbers before they enter the damage/combat calculation system.

Eg: Now you can do proper elemental healing.
eg: Fire Damage Heals.
(Before - the best you could do, would be to endure the fire damage, and then heal the fire damage x 2, which was bad - because the original damage could have killed you etc - in which case its not real healing.)

Now you can analyse the damage type, amount, and source of the damage, and determine if the damage should be cancelled altogether.


Code:

int __fastcall CNWSEffectListHandler__OnApplyDamage( void * pThis, void*, CNWSObject * obj, CGameEffect * effect, int iArg )
{
   CNWSCreature * cre = (CNWSCreature *)obj;
   char * cData = new char[25];
   if(cre != NULL)
   {
      if(cre->cre_is_pc == 1)
      {
         ResetParameters();
         Cool.frames++;
         Cool.Event = 101;
         Cool.oTarget = cre->obj.obj_generic.obj_id;
         Cool.oTarget2 = effect->eff_creator;
         
                  int i;
               for (i=0; i< 12; i++)
               {
                  
                  //string sVar = "damage_%d";
                  sprintf( cData, "damage_%d", i );
                  int iNum = effect->eff_integers[i];
                  obj->obj_vartable.SetInt(CExoString( cData ),iNum,0);
                  
               }

         Cool.ScriptRunning = true;
         (*NWN_VirtualMachine)->Runscript(&CExoString("nwnx_cool"), cre->obj.obj_generic.obj_id );
         Cool.ScriptRunning = false;                   

            if( Cool.ByPass )
            {
               for (i=0; i< 12; i++)
               {
                  sprintf( cData, "damage_%d", i );
                  int nDamAmount = obj->obj_vartable.GetInt( CExoString( cData ) );
                  effect->eff_integers[i] = nDamAmount;
               }
            Cool.ByPass = false;
            //return Cool.nRetn;
            }
            
         
      }

   }
   delete cData;
   return CNWSEffectListHandler__OnApplyDamageNext(pThis,NULL,obj,effect,iArg);
}


That's the hook

Here is the nwscript


Code:


else if( nEvent == 101){
          if(GetIsPC(OBJECT_SELF))
          {
            int iDamage = -1;
            string sBuffer = "";
            int iter = 0;
            for(iter=0;iter<12;iter++)
            {
              iDamage = GetLocalInt(OBJECT_SELF,"damage_"+IntToString(iter));
              sBuffer += IntToString(iDamage)+"|";

            }
            string oAttacker = GetName( GetEventTargetSecond( ));
            PrintString("Damage Inflicted to:"+GetName(OBJECT_SELF)+" before calculations - "+sBuffer+" \nAttacker:"+oAttacker);

            //ByPass( );

          }
    }






If you change the value of SetLocalInt(OBJECT_SELF,"damage_"+x,iAmount);
And then call ByPass() - it will then use your modified damage amounts.


eg:

I hit myself with 50 Fire Damage

I can mitigate it altogether (nothing in the combat log) by using
SetLocalInt(OBJECT_SELF,"damage_8",-1);
ByPass();

or
I can change it from Fire Damage, to Cold Damage mid calculation
int iDamage = GetLocalInt(OBJECT_SELF,"damage_8");
SetLocalInt(OBJECT_SELF,"damage_8",-1);
SetLocalInt(OBJECT_SELF,"damage_5",iDamage);
ByPass();

The result is that the damage is converted from Fire to Cold - and Fire shouldn't appear in the log.


Im hoping I can use this to create new item properties etc in my PW

eg: Damage conversion etc
25% of Bludgeoning Damage is converted to X Damage Type etc
(A Damage type you might have more resistance to etc)
Back to top
View user's profile Send private message
ShaDoOoW



Joined: 20 Aug 2005
Posts: 543

PostPosted: Sat Sep 14, 2013 21:26    Post subject: Reply with quote

good job! adding to my personal copy Rolling Eyes
_________________
Community Patch / NWNX Patch / NWNX Files / NWNX Connect
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 816

PostPosted: Sat Sep 14, 2013 23:09    Post subject: Reply with quote

I've noticed that there might be a crash that occurs if you bash non-creature objects - I am going to see if I can resolve it via adding more checks around the object type etc:

Eg: Only fire the hook, if its object type is of creature etc

That being sure : Im not entirely sure if the crash is related to this hook at all or not.

It could just be unrelated.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 816

PostPosted: Sat Sep 14, 2013 23:28    Post subject: Reply with quote

Not sure if it made much difference:
But I changed my hook to implement Maxrocks style of casting.

I think the CNWSCreature * cre = obj->AsNWSCreature();

Is probably the more safer route to take - as it has internal checks to make sure that the object being cast is infact of type creature.
The crash was probably due to me trying to access cre_is_pc on something that wasn't a Creature.

eg: The property probably doesn't exist for things like placeables etc.

This version should now definitely only fire for creatures.

Note - I had to make modifications to the
CNWSObject.h and cpp
to implement the cast

Code:


//need to include "nwn_consts.h"  at the top

CNWSCreature *CNWSObject_s::AsNWSCreature() {
   CGenericObject obj2  = this->obj_generic;
   
   if (obj2.obj_type2 == OBJECT_TYPE2_CREATURE)
      return (CNWSCreature*)this;
   return NULL;
}


Code:


int __fastcall CNWSEffectListHandler__OnApplyDamage( void * pThis, void*, CNWSObject * obj, CGameEffect * effect, int iArg )
{

   CNWSCreature * cre = obj->AsNWSCreature();
   char * cData = new char[25];
   if(cre)
   {
      if(cre->cre_is_pc == 1)
      {
         ResetParameters();
         Cool.frames++;
         Cool.Event = 101;
         Cool.oTarget = cre->obj.obj_generic.obj_id;
         Cool.oTarget2 = effect->eff_creator;
         
                  int i;
               for (i=0; i< 12; i++)
               {
                  
                  //string sVar = "damage_%d";
                  sprintf( cData, "damage_%d", i );
                  int iNum = effect->eff_integers[i];
                  obj->obj_vartable.SetInt(CExoString( cData ),iNum,0);
                  
               }

         Cool.ScriptRunning = true;
         (*NWN_VirtualMachine)->Runscript(&CExoString("nwnx_cool"), cre->obj.obj_generic.obj_id );
         Cool.ScriptRunning = false;                   

            if( Cool.ByPass )
            {
               for (i=0; i< 12; i++)
               {
                  sprintf( cData, "damage_%d", i );
                  int nDamAmount = obj->obj_vartable.GetInt( CExoString( cData ) );
                  effect->eff_integers[i] = nDamAmount;
               }
            Cool.ByPass = false;
            //return Cool.nRetn;
            }
            
         
      }

   }
   delete cData;
   return CNWSEffectListHandler__OnApplyDamageNext(pThis,NULL,obj,effect,iArg);
}
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 816

PostPosted: Mon Sep 16, 2013 13:52    Post subject: Time to give back Reply with quote

Time for me to give back to the community:
Here is my compiled version of nwnx_cool - with the 2 damage hooks I created.

http://www.azmodan.net/nwnx_output/nwnx_cool_Baaleos.rar


Inside is the dll, a readme doc, and some nss showing how to create a custom damage system: allowing you to modify the damage with custom feats, or even heal your character with fire damage etc.

If anyone gets stuck - let me know.

This version was built using Terra_777's last version of nwnx_cool:
So it also has all the hooks he added as well.
Back to top
View user's profile Send private message
highv priest



Joined: 01 Mar 2013
Posts: 110

PostPosted: Fri Jul 24, 2015 4:53    Post subject: Reply with quote

If you have the inc_cool that would be the last piece of the puzzle I need!
Back to top
View user's profile Send private message
Valbor



Joined: 26 Dec 2016
Posts: 123

PostPosted: Sat Jul 15, 2017 4:35    Post subject: Reply with quote

Hello Baaleos, your OnDamage events is not triggered if the damage is lethal for the PC, could you fix it? And to do so on the nPC, he also triggered?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Windows development All times are GMT + 2 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group