Jump to content

Improved Companion AI Project


Xaranth

Recommended Posts

So, as part of the Clarissa Winters project, I ended up having to create a new companion (Characters can be really irritating when they do things like that to you, can't they?). And since I'm really not happy with the basic AI of companions in the game, I'm beginning work on an improved AI script. The goals are to make companions both more self-sufficient (In things like item use, for example. How many times have you taken thirty stimpaks off of Boone's corpse?) and to make them follow player behavior a bit better (Example: If we're sneaking, the companion will switch to a silenced weapon rather than playing with an Anti-Material Rifle).

 

Anyway, the main thrust of this post is: would you lot be interested in me distributing this on the Nexus as a Modder's Resource as it goes along?

 

-X

Link to comment
Share on other sites

*Blinks* Okay, wow. That's a pretty impressive response for three hours.

 

The first iteration is ready for testing. Since I'm a bit OCD about performance, I've made it a quest Script attached to a quest that procs every half-second. I'll see how it runs in game. No upload just yet, but here's the script for those of you who want to try it on your own:

 

scn ICAI01scptQstCompanionAI

ref rCpn

int iStims
int iSupStims
int iDrBags

float fHealth
float fMaxHealth
float fHPercent

float fLegR
float fLegL
float fArmR
float fArmL
float fHead
float fTorso
;float fUniqueLimb ; for Robotic or Insectoid companions!  This corresponds to the combat Inhibitor / antennae

short bCombat
;short bHardcore ; Commented out for the moment.

begin gameMode

Set rCpn to YourCompanionRef ; Replace 'YourCompanionRef' with your companion ref.

if rCpn.GetPlayerTeammate

	Set bCombat to rCpn.isInCombat 	; Checks for combat.  We process different thresholds for healing based on combat/non-combat
;		Set bHardcore to player.isHardcore ; checks for hardcore.  Commented because I used IsSpellTarget instead.  Might use this elsewhere though.

	;Item counts
	Set iStims to rCpn.getItemCount Stimpak
	Set iSupStims to rCpn.getItemCount NVSuperStimpak
	Set iDrBags to rCpn.getItemCount NVDoctorBag

	;overall health
	Set fHealth to rCpn.getActorValue Health
	Set fMaxHealth to rCpn.getPermanentActorValue Health
	Set fHPercent to (fHealth / fMaxHealth)

	;limb health
	Set fArmR to rCpn.getActorValue RightAttackCondition
	Set fArmL to rCpn.getActorValue LeftAttackCondition
	Set fLegR to rCpn.getActorValue RightMobilityCondition
	Set fLegL to rCpn.getActorValue LeftMobilityCondition
	Set fHead to rCpn.getActorValue PerceptionCondition
	Set fTorso to rCpn.getActorValue EnduranceCondition
;		Set fUniqueHealth to rCpn.getActorValue BrainCondition ; For robotic and insectoid companions.  This is the Combat Inhibitor/Antennae bit.

	if bCombat
		if (fHPercent < 0.1)
			if ((iSupStims > 0) && (rCpn.IsSpellTarget NVSuperStimpak != 1)) ;Use a SuperStimpak if you have one.
				rCpn.CIOS NVSuperStimpak
				rCpn.removeItem NVSuperStimpak 1
				ShowMessage MMCA01msgDbgSuperStimpak ; Debug Message, comment out for deployment.
			elseIf ((iStims > 0) && (rCpn.IsSpellTarget Stimpak != 1)) ;Or use a Stimpak.
				rCpn.CIOS StimPak
				rCpn.removeItem StimPak 1
				ShowMessage MMCA01msgDbgStimpak ; Debug Message, comment out for deployment.
			endIf
		elseIf (fHPercent < 0.4)
			if ((iStims > 0) && (rCpn.IsSpellTarget Stimpak != 1)) ;Use a stimpak first.
				rCpn.CIOS StimPak
				rCpn.removeItem StimPak 1
				ShowMessage MMCA01msgDbgStimpak ; Debug Message, comment out for deployment.
			elseif ((iSupStims > 0) && (rCpn.IsSpellTarget NVSuperStimpak != 1)) ;But if you don't have one, use a Super Stimpak
				rCpn.CIOS NVSuperStimpak
				rCpn.removeItem NVSuperStimpak 1
				ShowMessage MMCA01msgDbgSuperStimpak ; Debug Message, comment out for deployment.
			endIf
		elseIf (fHPercent < 0.6)
			if ((iStims >= 4) && (rCpn.IsSpellTarget Stimpak != 1)) ;Only use a stimpak if you have a healthy supply.
				rCpn.CIOS StimPak
				rCpn.removeItem StimPak 1
				ShowMessage MMCA01msgDbgStimpak ; Debug Message, comment out for deployment.
			endIf
		elseIf (fHPercent < 0.75)
			if ((iStims >= 8) && (rCpn.IsSpellTarget Stimpak != 1)) ; You're in good shape, only use a stimpak if you have an embarassment of riches.
				rCpn.CIOS StimPak
				rCpn.removeItem StimPak 1
				ShowMessage MMCA01msgDbgStimpak ; Debug Message, comment out for deployment.
			endIf
		endIf
	else ;This is the non-combat condition block.
		if ((iDrBags > 0) && ((fArmR <= 40) || (fArmL <= 40) || (fLegR <= 40) || (fLegL <= 40) || (fHead <= 40) || (fTorso <= 40))) ;Do I have a Doctor's bag, and do I NEED one?
			rCpn.CIOS NVDoctorBag
			rCpn.removeItem NVDoctorBag 1
			ShowMessage MMCA01msgDbgDrBag ; Debug line, comment out for deployment.
		endIf
		if ((fHPercent <= 0.4) && (iStims >= 4) && (rCpn.isSpellTarget Stimpak != 1)) ; Out of combat, healing's not as important because NPCs heal over time, so we don't burn stimpaks.
			rCpn.CIOS Stimpak
			rCpn.removeItem Stimpak 1
			ShowMessage MMCA01msgDbgStimpak ; Debug line, comment out for deployment.
		endIF
	endIF

endIF

end

 

Edit: Next target - Condition curing. But Clarissa's nagging me that it's time to write up her next entry so it'll be a bit.

Edited by Xaranth
Link to comment
Share on other sites

First alpha build is almost finished. Added an 'I got lost bounce me to the player' block, and antivenom and radaway bits. I don't know if the radAway is at all useful. I know NPCs DON'T get irradiated in the base game, but I don't know if they CAN be irradiated. Until I work that out the radaway stays in.

 

Edit: Also revised all UseStimpak blocks to check for a SuperStimpak before firing. The reverse is not true.

Edited by Xaranth
Link to comment
Share on other sites

Update: Alpha build will be going up sometime within the next couple days. I'm procrastinating because after building Scrambler for the Clarissa Winters story I really don't want to go through all that again. Also RL has some requirements that need to be met.

 

Testing on scrambler with the console has had pleasing results; the out of combat stuff triggers correctly and more importantly BEHAVES correctly, but the in combat stuff isn't tested yet.

 

On that note, does anyone know if it's possible to make the game write a logfile for a mod and if so how? That would improve testing.

Link to comment
Share on other sites

Could create a variable for companion radiation and just link it to the player radiation level.

 

Kinda dirty, cause radiation can be effected by other things. Eating, drinking, centaurs, ect. But you can just pass that off as the fact that you're companions eat, drink and get hit too.

Link to comment
Share on other sites

If I were aiming to increase realism, yeah. But my objective is to make companions more intelligent less stupid.

 

It's in there because if NPCs CAN be irradiated, I'm sure there's a mod that does it, and someone is sure to be playing with it. So companions should use RadAway if they need it. ^.^

Link to comment
Share on other sites

  • Recently Browsing   0 members

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