View previous topic :: View next topic |
Author |
Message |
Baaleos
Joined: 02 Sep 2007 Posts: 830
|
Posted: Sat Sep 14, 2013 20:52 Post subject: |
|
|
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 |
|
|
ShaDoOoW
Joined: 20 Aug 2005 Posts: 584
|
Posted: Sat Sep 14, 2013 21:26 Post subject: |
|
|
good job! adding to my personal copy _________________ Community Patch / NWNX Patch / NWNX Files / NWNX Connect |
|
Back to top |
|
|
Baaleos
Joined: 02 Sep 2007 Posts: 830
|
Posted: Sat Sep 14, 2013 23:09 Post subject: |
|
|
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 |
|
|
Baaleos
Joined: 02 Sep 2007 Posts: 830
|
Posted: Sat Sep 14, 2013 23:28 Post subject: |
|
|
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 |
|
|
Baaleos
Joined: 02 Sep 2007 Posts: 830
|
Posted: Mon Sep 16, 2013 13:52 Post subject: Time to give back |
|
|
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 |
|
|
highv priest
Joined: 01 Mar 2013 Posts: 111
|
Posted: Fri Jul 24, 2015 4:53 Post subject: |
|
|
If you have the inc_cool that would be the last piece of the puzzle I need! |
|
Back to top |
|
|
Valbor
Joined: 26 Dec 2016 Posts: 145
|
Posted: Sat Jul 15, 2017 4:35 Post subject: |
|
|
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 |
|
|
|
|
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
|