Jump to content

New AI behavior


EtherealCoder

Recommended Posts

Hi all

 

I'm new to the Skyrim modding scene, though I've done some mods of FPS games in the past (UT2004, etc.).

 

I would like to tweak some of the AI behavior in the game to make it more strategic and challenging. To achieve this goal, I need to collect some data from the game -- specifically, the location of the Aggressor and Target every time an attack lands successfully.

 

I've sketched up a script to save this information as XML in the log so I can parse it later -- however, I'm not sure how to exactly phrase the new OnHit method to get the info I want.

 

I was thinking of setting things up so when the Player enters my target Location, a Quest is started, which would run the following script in the background:

 

Scriptname NewAITestDungeon03Script01 extends ObjectReference

Event OnHit(ObjectReference akAggressor, Form akSource, \
	Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
	bool abBashAttack, bool abHitBlocked)
	
	if akAggressor == game.getPlayer()
		Debug.Trace("<EventOnHit><Aggressor><ID>Player</ID><Location>" \
			+ akAggressor.GetPos axis + "</Location></Aggressor><Target>" \
			+ "<ID>" + **Reference to Target Actor needed here ** \
			+ "</ID><Location>" + ** Reference to Target Location needed here ** \
			+ "</Location></Target></EventOnHit>")
	else
		Debug.Trace("<EventOnHit><Aggressor><ID>" + akAggressor \
			+ "</ID><Location>" + akAggressor.GetPos axis \
			+ "</Location></Aggressor><Target>" \
			+ "<ID>Player</ID><Location>" \
			+ game.getPlayer().GetPos axis \
			+ "</Location></Target></EventOnHit>")
 	endif
  
  
EndEvent

 

I just need to know how to reference the Target when the Aggressor is the Player.

 

Note I'm hypothesizing that running the Papyrus script from a Quest will render the results I want for all Actors. If this isn’t the Best Practice way of doing things, a pointer or web link in the right direction would be much appreciated!

 

Thanks all!

 

E.C.

Link to comment
Share on other sites

Hi all

 

I'm new to the Skyrim modding scene, though I've done some mods of FPS games in the past (UT2004, etc.).

 

I would like to tweak some of the AI behavior in the game to make it more strategic and challenging. To achieve this goal, I need to collect some data from the game -- specifically, the location of the Aggressor and Target every time an attack lands successfully.

 

I've sketched up a script to save this information as XML in the log so I can parse it later -- however, I'm not sure how to exactly phrase the new OnHit method to get the info I want.

 

I was thinking of setting things up so when the Player enters my target Location, a Quest is started, which would run the following script in the background:

 

Scriptname NewAITestDungeon03Script01 extends ObjectReference

Event OnHit(ObjectReference akAggressor, Form akSource, \
	Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
	bool abBashAttack, bool abHitBlocked)
	
	if akAggressor == game.getPlayer()
		Debug.Trace("<EventOnHit><Aggressor><ID>Player</ID><Location>" \
			+ akAggressor.GetPos axis + "</Location></Aggressor><Target>" \
			+ "<ID>" + **Reference to Target Actor needed here ** \
			+ "</ID><Location>" + ** Reference to Target Location needed here ** \
			+ "</Location></Target></EventOnHit>")
	else
		Debug.Trace("<EventOnHit><Aggressor><ID>" + akAggressor \
			+ "</ID><Location>" + akAggressor.GetPos axis \
			+ "</Location></Aggressor><Target>" \
			+ "<ID>Player</ID><Location>" \
			+ game.getPlayer().GetPos axis \
			+ "</Location></Target></EventOnHit>")
 	endif
  
  
EndEvent

 

I just need to know how to reference the Target when the Aggressor is the Player.

 

Note I'm hypothesizing that running the Papyrus script from a Quest will render the results I want for all Actors. If this isn’t the Best Practice way of doing things, a pointer or web link in the right direction would be much appreciated!

 

Thanks all!

 

E.C.

 

 

If by "Papyrus script from a Quest" you mean a script attached to a quest then no it will not have the results you want. I'll point you to a Tutorial on Dynamically attaching scripts to NPCs which should be more...suitable for your application.

Link to comment
Share on other sites

Hi all

 

BotOwned: Thank you for the link! Instead of using a quest to attach the script to both the NPC's and the player, I've just directly attached them to the NPC's. The link you sent should help for an easy attach to the player, thank you very much!

 

GrimyBunyip: Good guess -- the idea is to record spots where the AI is hit relative to player position. I can then use some clustering tecniques to collapse a huge set of data points down to a few dozen -- so when the player is at Point A, the AI knows to avoid Points B, C, and D. When the player moves, the "areas to avoid" change as well.

 

However, I don't want this to be a static solution for just my little mod. The idea is to provide a tool / service for all modders and maps. So, anyone can make a new dungeon, and then use my tool to enhance their AI without having to hard-code in anything themselves. The system will be dynamic and just rely on recorded data from the log.

Link to comment
Share on other sites

BTW, got the code working -- though I want to tweak a few things. This is the Papyrus script I've directly attached to my NPC's.

 

Scriptname NAITD03S01 extends ObjectReference  
{Used for logging the locations of attackers and targets.}

Event OnHit(ObjectReference akAggressor, Form akSource, \
	Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
	bool abBashAttack, bool abHitBlocked)
	if akAggressor == game.getPlayer()
		Debug.Trace("<EventOnHit><Aggressor><ID>Player</ID><Location>" \
			+ akAggressor.GetPositionX() + ","  \
			+ akAggressor.GetPositionY() + ","  \
			+ akAggressor.GetPositionZ() \
			+ "</Location></Aggressor><Target>" \
			+ "<ID>" + Self \
			+ "</ID><Location>" \
			+ Self.GetPositionX() + ","  \
			+ Self.GetPositionY() + ","  \
			+ Self.GetPositionZ() \
			+ "</Location></Target></EventOnHit>")
	else
		Debug.Trace("<EventOnHit><Aggressor><ID>" + akAggressor + "</ID><Location>" \
			+ akAggressor.GetPositionX() + ","  \
			+ akAggressor.GetPositionY() + ","  \
			+ akAggressor.GetPositionZ() \
			+ "</Location></Aggressor><Target>" \
			+ "<ID>" + Self \
			+ "</ID><Location>" \
			+ Self.GetPositionX() + ","  \
			+ Self.GetPositionY() + ","  \
			+ Self.GetPositionZ() \
			+ "</Location></Target></EventOnHit>")
 	endif  
EndEvent
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...