Difference between revisions of "Fixing AI in multiplayer"

From Valve Developer Community
Jump to: navigation, search
(Forget something)
(Model animations)
Line 77: Line 77:
 
== Model animations ==
 
== Model animations ==
 
If you are using HL2DM as base (320 as SteamAppID in <code>gameinfo.txt</code>) then you are using the models of HL2DM. HL2DM has new models for the metropolice, combine soldiers and rebels. These HL2DM models don't have the animations of the HL2-variants and the AI doesn't like that. For that to work, you need to copy the models over from HL2. Also, new player models are needed, considering the ones from HL2DM won't work anymore.
 
If you are using HL2DM as base (320 as SteamAppID in <code>gameinfo.txt</code>) then you are using the models of HL2DM. HL2DM has new models for the metropolice, combine soldiers and rebels. These HL2DM models don't have the animations of the HL2-variants and the AI doesn't like that. For that to work, you need to copy the models over from HL2. Also, new player models are needed, considering the ones from HL2DM won't work anymore.
 +
 +
{{Note|Since the August 06 SDK update NPCs have new code that need EP1-models}}
  
 
== Function calls ==
 
== Function calls ==

Revision as of 13:13, 6 October 2006

This is an updated article about how to fix NPCs in multiplayer. HL2 has no support for NPCs in multiplayer and HL2DM has certainly broken more of the AI.

Relationships

There are no relationships-table set in HL2DM. Without this table NPCs won't know which entities to hate/like, and if Combine Soldiers likes players, they won't attack them.

This is simple to fix. First go to hl2mp_gamerules.h, under public: add this:
#ifndef CLIENT_DLL 
void InitDefaultAIRelationships( void );
#endif

Next go to hl2_gamerules.cpp and copy the entire InitDefaultAIRelationships function. Paste it in hl2mp_gamerules.cpp. Don't forget to put the copied functions between:

#ifndef CLIENT_DLL
...
#endif

Also add a call to InitDefaultAIRelationships in the constructor of CHL2MPRules.

Weapons

Activities & animation events

The weapons have custom activities and animation events used for the AI in HL2. In the HL2DM-versions of the weapons this is removed.

Open the weapon_hl2mpbase.h file and add the following code after the includes:

#ifndef CLIENT_DLL
	#include "AI_BaseNPC.h"
#endif


Now open the HL2SP files of the AR2, shotgun, SMG1, crowbar, pistol and stunstick (found in dlls/hl2_dll/). The NPCs in HL2 don't use any other weapons. Each weapon has a Operator_HandleAnimEvent and CapabilitiesGet function, which the NPCs use to fire their weapons. Copy these functions and any other functions that are called in Operator_HandleAnimEvent to the HL2DM weaponfiles (found in game_shared/hl2mp/). Don't forget the headers and to put all copied functions between:

#ifndef CLIENT_DLL
...
#endif

Also, you need to copy the activities. Look for m_acttable[] in the HL2SP-variants and copy them to the HL2DM-variants.

SetActivity()

Open basecombatweapon_shared.cpp and look for the function SetActivity. Look for the following code:

//Adrian: Oh man...
#if !defined( CLIENT_DLL ) && defined( HL2MP )
	SetModel( GetWorldModel() );
#endif

int sequence = SelectWeightedSequence( act ); 
	
	// FORCE IDLE on sequences we don't have (which should be many)
	if ( sequence == ACTIVITY_NOT_AVAILABLE )
		sequence = SelectWeightedSequence( ACT_VM_IDLE );

//Adrian: Oh man again...
#if !defined( CLIENT_DLL ) && defined( HL2MP )
	SetModel( GetViewModel() );
#endif

The activities can only be retrieved from weapon world models. However the weapons of players are viewmodels. So with this little hack the models are changed to worldmodel, activies are retrieved and changed back to viewmodel. However considering NPCs don't have to see or work with their viewmodels, this is going to be changed:

	//Adrian: Oh man...
	if ( GetOwner()->IsPlayer() )
		SetModel( GetWorldModel() );
	
	int sequence = SelectWeightedSequence( act ); 
	
	// FORCE IDLE on sequences we don't have (which should be many)
	if ( sequence == ACTIVITY_NOT_AVAILABLE )
		sequence = SelectWeightedSequence( ACT_VM_IDLE );

	//Adrian: Oh man again...
	if ( GetOwner()->IsPlayer() )
		SetModel( GetViewModel() );

Ammotypes

The damage of the weapons need to use the data from skill.cfg. Don't forget the copy HL2's skill.cfg to your mod's cfg directory.

Also, the code needs to be told to use this values. Open hl2_gamerules.cpp again and copy the entire GetAmmoDef function. Replace the same function in hl2mp_gamerules.cpp with the copied code but add the following line:

def.AddAmmoType("slam",				DMG_BURN,					TRACER_NONE,			0,			0,			5,			0,							0 );

HL2 doesn't have the SLAM and without that line the SLAM won't work anymore.

Model animations

If you are using HL2DM as base (320 as SteamAppID in gameinfo.txt) then you are using the models of HL2DM. HL2DM has new models for the metropolice, combine soldiers and rebels. These HL2DM models don't have the animations of the HL2-variants and the AI doesn't like that. For that to work, you need to copy the models over from HL2. Also, new player models are needed, considering the ones from HL2DM won't work anymore.

Note:Since the August 06 SDK update NPCs have new code that need EP1-models

Function calls

Still, most part of the AI is still not suited to use in multiplayer. All calls to the functions AI_GetSinglePlayer, AI_IsSingleplayer and UTIL_GetLocalPlayer would need fixing. Also pieces of code like if ( gpGlobals->maxClients == 1) . There are over 100 calls and it's lots of work to fix this.

Blood

Thanks to the prediction, the blood of NPCs is suppressed. This is because in HL2DM the blood of players is done client-side. This is not the case with NPCs and the prediction needs to "break":

Open util_shared.cpp and look for the function UTIL_BloodDrips. Add to the top of the function:
IPredictionSystem::SuppressHostEvents( NULL );

Conclusion

These are the basic fixes needed for the AI. If you want to use HL2-NPCs in multiplayer, there's a lot of work ahead.