Fixing AI in multiplayer
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.
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
#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
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
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.
basecombatweapon_shared.cpp and look for the function
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() );
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
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.
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.
Still, most part of the AI is still not suited to use in multiplayer. All calls to the functions
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.
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.cppand look for the function
UTIL_BloodDrips. Add to the top of the function:
IPredictionSystem::SuppressHostEvents( NULL );
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.