Aller au contenu

Photo

Creature Special Abilities - How Are They Implemented? (hench_i0_itemsp)


  • Veuillez vous connecter pour répondre
14 réponses à ce sujet

#1
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi All,

I know there is a similar post already made in these forums, but my own questions got a little lost within it.

Anyway, my question is basically what is it that determines when and how a creature will use any special abilities listed in the Special Ability section of its template?

E.g. The Drachlich has some settings here, including an Aura of Cold. However, I have never seen the aura present and yet I thought that would be a permanent feature its its abilities.

Can anybody share some insight as to how this section of the game works?

For instance, if I want to set a creature with a permanent aura using this Special Ability setion, how is it done?

EDIT: I am not concerned about companion control, but about monster attacks.

Many Thanks.

Lance.

Modifié par Lance Botelle, 19 mars 2011 - 09:37 .


#2
The Fred

The Fred
  • Members
  • 2 516 messages
It's all done through the AI, which you can delve right into. There are a bunch of functions, mostly the TalentXXX() ones in x0_i0_talent, I think, which run certain categories (the category of an ability is set in the spells.2da), and the order of preference of these categories is generally picked by the ChooseTactics() function, I think, of DetermineCombatRound(). Of course, most of my knowledge of this is from way back when in NWN1 and some things have changed, especially with TonyK's stuff in SoZ.

Auras are categorized as "Persistant Abilities" and so, last time I looked, are normally chosen right at the start of combat, so I'm not sure why they're not using them.

#3
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

The Fred wrote...

It's all done through the AI, which you can delve right into. There are a bunch of functions, mostly the TalentXXX() ones in x0_i0_talent, I think, which run certain categories (the category of an ability is set in the spells.2da), and the order of preference of these categories is generally picked by the ChooseTactics() function, I think, of DetermineCombatRound(). Of course, most of my knowledge of this is from way back when in NWN1 and some things have changed, especially with TonyK's stuff in SoZ.

Auras are categorized as "Persistant Abilities" and so, last time I looked, are normally chosen right at the start of combat, so I'm not sure why they're not using them.


Hi The Fred,

Thanks for this feedback ... I was unaware of the "tactics" functions. Just when I thought I could start to relax and simply get on with the module, it looks like I may have to take a look at this code as well now, and consider doing some AI for my creatures. :? 

I guess auras will be the least of my worries, as they can be easily added at onspawn times. Managing the more unusual properties and any potential items carried, feats etc, are something else.

At least I know where to start looking now, but I think I may wait until I have the energy to look any deeper and address one part of the AI (per creature if possible) at a time.

Lance.

#4
Guest_Chaos Wielder_*

Guest_Chaos Wielder_*
  • Guests
The talent functions are a dark and terrible place. IMO, you're better off scripting each custom creature by hand, individually.

#5
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
For the most part it's custom coded. The AI is very hard to work with because it's very similar to "goto spagetti", with a lot of integers declared in global scope ( most don't realize you can do that ), often 2-3 functions doing almost the same thing, and it's spread out over about 50 include files touching almost every library nss file in the game for at least a function or two.

It also uses a lot of bitwise math and other more advanced programming topics you don't see in

Sometimes it's the talent functions, other times it's iterating ALL possible id's to try to find them, and the reason why it is not working right is something everyone who works with it ( like tonyK ) tried to fix.

#6
The Fred

The Fred
  • Members
  • 2 516 messages
The talent functions ARE rather nasty, but there are some distinctions:

The TalentXXXX(); functions don't NECESSARILY have anything to do with actual talents as per say. As "talent" is a data structure much like a location, vector, effect, itemproperty etc. The TalentXXXX(); functions are just functions from the talent include file which choose some behaviour. Normally they do so using talents, but there's no actual like between the two beyond naming and convention.

The actual talent functions, things like GetCreatureTalentBest() or whatever it's called, give you a "talent" which represents a feat, spell, item usage etc. They do this by looking for all of those things of a category which the creature has, and picking the "best" one (the one with the highest CR in the 2das or something like that, but basically this is why high-level spells tend to be cast before lower ones, because I think it ranks them as better).

These talent functions are indeed a dark and terrible place because you have very little control over them. However, AFAIK, they are the only way you can actually get a creature to, say, drink a potion.

Generally, if you just want to do something like throw up auras, you can do something like this (IIRC) in an override AI script:

#include "x2_inc_switches"
#include "x0_i0_talent"
...
if(TalentPersistentAbilities())
{
    SetCreatureOverrideAIScriptFinished();
    return;
}

Of course, something very similar to this code should be being executed anyway, but if it's not working, maybe it isn't.

#7
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi Everybody,

I do see how delving into this side of the code appears to be very murky indeed. Therefore, as CW says, I will look at coding each creature AI individually. That said, without asking the code to do all sorts of checks to come up with a tactic or special attack, is there a simple way for me to force a creature to use something like a wand or potion?

Have any of you managed to unearth the function or code within all these includes that simply makes a creature take a potion or use a wand on a PC?

I will continue to look myself, but if you know what this is already, it could save me some time. :)

Of course, I may be looking at the way this works all wrong.

Lance.

EDIT: The Fred - I tried that code, but it did not appear to work. I tried it as a one line of code .. TalentPersistenAbilities() ... within its OnSpawn, but it did not work.

UPDATE: OK, Even trying to apply a simple AOE effect (effect eAOE = EffectAreaOfEffect(AOE_MOB_FROST);) from the creatures OnSpawn does not do anything, as if this AOE does not actually exist in NWN2. Do I really have to define my own, even for this basic aura?!

Furthermore, I could not find any function to apply the SPELLABILITY_AURA_COLD. Does anybody know what function applies this "spellability"?

UPDATE 2: I searched out the Aura of Cold spell (196) and tracked down the scripts it uses (nw_s1_auracold and nw_s1_auracoldc - the heartbeat script for the supposed aura of cold spell) and tried applying the spell to a creature within its on spawn. (The nw_s1_auracoldc has the SPELLABILITY_AURA_COLD part by the way.)  It still did not work! This makes me think that this aura and similar auras that rely on SPELLABILITY code simply do not work. I will now try putting together my own version of these scripts to see if I can add an aura effect that works. Will post when done.

Furthermore, it looks like the original aura VFX are no longer supported. :( I can see some others that might work as an alternative though.

Modifié par Lance Botelle, 19 mars 2011 - 01:37 .


#8
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
You use the cast functions with a spell id, this is what is used for buffing. There is a flag to tell the ai to do this as well.


			
			//Combat Protections
			if ( !CSLGetHasEffectSpellIdGroup( oTarget, SPELL_SHADES, SPELL_GREATER_VISAGE_OF_THE_DEITY, SPELL_PREMONITION, SPELL_GREATER_STONESKIN, SPELL_Nixies_Grace, SPELL_Visage_Deity, SPELL_STONESKIN, SPELL_PROTECTION_FROM_ARROWS  ) )
			{
				if( GetHasSpell(SPELL_SHADES, oCaster))
				{
					bHasShades = TRUE;
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_SHADES_TARGET_CASTER, oTarget, METAMAGIC_NONE, bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
				else if(GetHasSpell(SPELL_GREATER_VISAGE_OF_THE_DEITY, oCaster))
				{
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_GREATER_VISAGE_OF_THE_DEITY, oTarget, METAMAGIC_NONE, bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
				else if( GetHasSpell(SPELL_PREMONITION, oCaster))
				{
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_PREMONITION, oTarget, METAMAGIC_NONE, bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
				else if( GetHasSpell(SPELL_GREATER_STONESKIN, oCaster))
				{
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_GREATER_STONESKIN, oTarget, METAMAGIC_NONE, bCheat, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
				else if(GetHasSpell(SPELL_Nixies_Grace, oCaster))
				{
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_Nixies_Grace, oTarget, METAMAGIC_NONE, bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
				else if(GetHasSpell(SPELL_Visage_Deity, oCaster))
				{
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_Visage_Deity, oTarget, METAMAGIC_NONE, bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
				else if(GetHasSpell(SPELL_STONESKIN, oCaster))
				{
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_STONESKIN, oTarget, METAMAGIC_NONE, bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
				else if(GetHasSpell(SPELL_PROTECTION_FROM_ARROWS, oCaster))
				{
					AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_PROTECTION_FROM_ARROWS, oTarget, METAMAGIC_NONE, bCheat, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantSpell) );
					iMaxEffects--;
				}
			}
			


#9
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi Everybody,

I managed to make an aura effect work for a creature after some playing around. Here is my approach and scripts for those interested. I have an example of a creature that I wanted to add a COLD AURA to. Please note, this is only one small aspect of determining creature AI and having it use certain abilities. This part simply activates an aura if it has one.

ONSPAWN
=======

First I add a single line to see if the creature spawning requires an aura:




if(GetTag(OBJECT_SELF) == "alb_empguard_red"){ExecuteScript("alb_aura_cold", OBJECT_SELF);}

COLD AURA ACTIVATE SCRIPT
====================

Please note that this activates a small pulsating visual ring (that I created in the effects editor) around the creature as well. The ring pulsates between visible and non visible and is meant to represent the PCs acknowledgement that the creature has an aura of some kind. (I could not find any permenent aura visual effects like NWN had to use.)

EDIT: The default AOE effect scripts *do* work when applied this way. I had made an error in my testing. Retesting proves they work as is, but only when added at spawn time as I have here.

// GIVE CREATURE THE COLD AURA WITH VISUAL EFFECT
#include "NW_I0_SPELLS"
void main()
{   
    effect eAOE = EffectAreaOfEffect(AOE_MOB_FROST); 
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAOE, OBJECT_SELF);
 effect Aura = EffectNWN2SpecialEffectFile("AuraRing");
 ApplyEffectToObject(DURATION_TYPE_PERMANENT, Aura, OBJECT_SELF); 
}


========================

As I say, this is just one minor aspect of the creature AI and special abilities they have. I believe the code to make a creature use a certain item is a bit trickier to track down.

Any help here would be appreciated.

Lance.

Modifié par Lance Botelle, 19 mars 2011 - 11:44 .


#10
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

painofdungeoneternal wrote...

You use the cast functions with a spell id, this is what is used for buffing. There is a flag to tell the ai to do this as well.

<SNIP>


Hi painofdungeoneternal,

I had a feeling it would be something like this ... and from your extract, I located the same script myself now. Well, that would account for buffing and spells, but what about ...

Using items .... ?

Any idea how that is handled?

e.g. If I give an orc wizard a wand of magic missiles, van I have it use it against the PCs?

Lance.

#11
The Fred

The Fred
  • Members
  • 2 516 messages
To use a spell-like ability, simply use it as you would a spell, with the ActionCastSpellXXX(); functions. For nSpell, simply use SPELLABILITY_XXXXX as you would use any SPELL_XXXXX constant - it's just a reference to the line in the 2da. HOWEVER, since the ability is not memorized as a spell, I'm not sure if you can enforce its use in the conventional sense. What you can do is set the bCheat flag to TRUE, which will allow it to be cast whether the creature actually has it or not, and use a local variable to track whether it's been used yet.

That said, for something like a persistant aura, you're as good just applying the effect OnSpawn - I'm not sure why the OnSpawn script wasn't working for you, as it's used to apply other effects such as the incorporeal ones.

Item usage, however, is a whole different kettle of fish. As far as I know, there is no actual way to use the items other than the talent functions. So, enemies will often use them by themselves (melee enemies especially often open a battle by drinking a potion, and enemies heal themselves with them). However, there's no way to force it. What you can do is simulate the item use by forcing the creature to cheat-cast the spell, and then removing the item from its inventory. It's messy, though, and they are a lot of things to worry about, such as the animations and the feedback strings.

#12
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi The Fred,

I did a quick test with the OnSpawn (by adding some debug feedback to the cold aura code), but did not see it working. I had added the Special Ability (Cold Aura) to the creature via the toolset and added your code to the creatures OnSpawn, but it did not seem to work. I even tried looking to see how the OC handled auras, but could not see where they implemented it for any of their creatures - I could not even find a creature that was supposed to have an aura - do you know of one? (That's an official creature, as opposed to one that has been created by someone else.)

However, the aura code did not have a visual and neither would it have an impact on a PC unless it was considered an enemy, so I may have simply not met the conditions during my testing - and not seen anything anyway, but I am fairly certain I did have it right. If you manage to see it working, then please let me know and I will try again. :)

I have since made my own aura code more generic so that I can simply attach a string variable to a creature (E.g. COLD or FIRE to enable a cold or fire aura, etc.) at the moment of spawning. As they all use the aura visual I made, it is simple enough to see that the aura is actually in place - and damage / bad affect is appplied if the PC is considered an enemy and within range.

ITEM USAGE: You say that you have seen melee enemies "open a battle by drinking a potion". Are you able to point me to the actual piece of code that does this, or is it hard-coded somewhere? My idea, of course, is if I can intercept that code, then I may be able to add my own AI hook at that point.

I think I am at the following stages:-

1) Auras - Done. (Example code above.)
2) Spell like abilities - Done. (Use ActionCastSpell at self using CHEAT TRUE as you say and as PoeD.)
3) Items - Some - Maybe fudging code checks for items and applying results/removing items.

I suppose if magic items are rare, then items may not be something I need to worry too much about. Unless there is a better way of handling this, then I guess it is something I can look at on a one to one basis.

Many thanks.

Lance.

Modifié par Lance Botelle, 19 mars 2011 - 08:33 .


#13
The Fred

The Fred
  • Members
  • 2 516 messages
The aura visuals were cut for NWN2, and I think it's possible that auras generally may have been, although I'm sure I've seen creatures with them - I'd have to check.

As for item usage, I definately remember seeing it all the time in NWN1 (generally where a potion was created as random treasure on an enemy, who then drank it) and I think the functionality has carried over to NWN2. However, as far as I know, the only way to get an NPC to drink a potion is to use the talent functions (there are self-buff and self-heal categories which seem to cover both abilities and items). The TalentXXXX() wrapper functions from the talent include should handle it, but as I said, I don't know of any way to force item use.

#14
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

The Fred wrote...

The aura visuals were cut for NWN2, and I think it's possible that auras generally may have been, although I'm sure I've seen creatures with them - I'd have to check.

As for item usage, I definately remember seeing it all the time in NWN1 (generally where a potion was created as random treasure on an enemy, who then drank it) and I think the functionality has carried over to NWN2. However, as far as I know, the only way to get an NPC to drink a potion is to use the talent functions (there are self-buff and self-heal categories which seem to cover both abilities and items). The TalentXXXX() wrapper functions from the talent include should handle it, but as I said, I don't know of any way to force item use.


Hi The Fred,

This tends to suggest the code checks something "hard-wired" when using the Talent functions then, comparing items and abilities from some hidden priority table perhaps?

I will try taking a closer look at the Talent functions then ... if I discover anything, I will let you know.

Lance.

UPDATE: I think the "hench_i0_itemsp" script may have something to do with using items, but the code is beyond my current understanding. It has this at the top of the script, "This file contains routines used for casting spells, using feats, items (potions, scrolls, and rods by companions and monsters. Several options are tried and the highest weighted options is what is finally cast."

Modifié par Lance Botelle, 19 mars 2011 - 09:36 .


#15
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

The Fred wrote...

<SNIP>That said, for something like a persistant aura, you're as good just applying the effect OnSpawn - I'm not sure why the OnSpawn script wasn't working for you, as it's used to apply other effects such as the incorporeal ones. <SNIP>


Hi The Fred,

The debug checking was an error on my part. After checking again, the default scripts did work as long as I applied the AOE at spawn time for the creature.

Glad you questioned me here. :)

Lance.