Garry's Mod Wiki

Revision Difference

GM:StartCommand#511210

<function name="StartCommand" parent="GM" type="hook">⤶ <ishook>yes</ishook>⤶ <description>⤶ Allows you to change the players inputs before they are processed by the server.⤶ ⤶ ⤶ ⤶ ⤶ This is basically a shared version of <page>GM:CreateMove</page>.⤶ ⤶ <note>This function is also called for bots, making it the best solution to control them so far</note>⤶ ⤶ <note>This hook is predicted, but not by usual means, this hook is called when a <page>CUserCmd</page> is generated on the client, and on the server when it is received, so it is necessary for this hook to be called clientside even on singleplayer</note>⤶ </description>⤶ <realm>Shared</realm>⤶ <predicted>Yes</predicted>⤶ <hidepredictionwarning>Disable automatic prediction warning</hidepredictionwarning>⤶ <args>⤶ <arg name="ply" type="Player">The player</arg>⤶ <arg name="ucmd" type="CUserCmd">The usercommand</arg>⤶ </args>⤶ </function>⤶ ⤶ <example>⤶ <description>⤶ Example of how you'd control a bot using this hook.⤶ ⤶ The example causes all bots to go kill any players they can get to with crowbars.⤶ </description>⤶ <code>⤶ hook.Add( "StartCommand", "StartCommandExample", function( ply, cmd )⤶ ⤶ -- If the player is not a bot or the bot is dead, do not do anything⤶ -- TODO: Maybe spawn the bot manually here if the bot is dead⤶ if ( !ply:IsBot() or !ply:Alive() ) then return end⤶ ⤶ -- Clear any default movement or actions⤶ cmd:ClearMovement() ⤶ cmd:ClearButtons()⤶ ⤶ -- Bot has no enemy, try to find one⤶ if ( !IsValid( ply.CustomEnemy ) ) then⤶ -- Scan through all players and select one not dead⤶ for id, pl in pairs( player.GetAll() ) do⤶ if ( !pl:Alive() or pl == ply ) then continue end -- Don't select dead players or self as enemies ⤶ ply.CustomEnemy = pl⤶ end⤶ -- TODO: Maybe add a Line Of Sight check so bots won't walk into walls to try to get to their target⤶ -- Or add path finding so bots can find their way to enemies⤶ end⤶ ⤶ -- We failed to find an enemy, don't do anything⤶ if ( !IsValid( ply.CustomEnemy ) ) then return end⤶ ⤶ -- Move forwards at the bots normal walking speed⤶ cmd:SetForwardMove( ply:GetWalkSpeed() )⤶ ⤶ -- Aim at our enemy⤶ if ( ply.CustomEnemy:IsPlayer() ) then⤶ cmd:SetViewAngles( ( ply.CustomEnemy:GetShootPos() - ply:GetShootPos() ):GetNormalized():Angle() )⤶ else⤶ cmd:SetViewAngles( ( ply.CustomEnemy:GetPos() - ply:GetShootPos() ):GetNormalized():Angle() )⤶ end⤶ ⤶ -- Give the bot a crowbar if the bot doesn't have one yet⤶ if ( SERVER and !ply:HasWeapon( "weapon_crowbar" ) ) then ply:Give( "weapon_crowbar" ) end⤶ ⤶ -- Select the crowbar⤶ cmd:SelectWeapon( ply:GetWeapon( "weapon_crowbar" ) )⤶ ⤶ -- Hold Mouse 1 to cause the bot to attack⤶ cmd:SetButtons( IN_ATTACK )⤶ ⤶ -- Enemy is dead, clear our enemy so that we may acquire a new one⤶ if ( !ply.CustomEnemy:Alive() ) then⤶ ply.CustomEnemy = nil⤶ end⤶ ⤶ end )⤶ </code>⤶ ⤶ </example>