Fixing AI in multiplayer

As a courtesy, please do not edit this while this message is displayed.
If this page has not been edited for at least several hours to a few days, please remove this template. This message is intended to help reduce edit conflicts; please remove it between editing sessions to allow others to edit the page.
The person who added this notice will be listed in its edit history should you wish to contact them.
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. With this table NPCs don't know which entities to hate/like. And if a Combine Soldiers likes players, he won't shoot them.
This is simpel to fix. Go to hl2_gamerules.cpp
and copy the entire InitDefaultAIRelationships
function. Past it in hl2mp_gamerules.cpp
and add a call to the new function in the constructor of the HL2DM gamerules.
Weapons
Activities & animation events
The weapons have custom activities and animation events in HL2DM. 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
function, which the NPCs use to fire their weapons. Copy this function and any other functions that are called in this function 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</code> Also, you need to copy the activities. Look for <code<m_acttable[]</code> in the HL2SP-variants and copy them to the HL2DM-variants. === SetActivity() === Open <code>basecombatweapon_shared.cpp</code> and look for the function <code>SetActivity</code>. Look for the following code: <pre>//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 hl2_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.
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 );