Marlingaming

Gmod Lua Basic Grunt Script V1 - Gmod Commanding System

Dec 10th, 2021 (edited)
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.11 KB | None | 0 0
  1. AddCSLuaFile()
  2.  
  3. local HasSurrendered = false
  4. local SquadCommandState = 3
  5.  
  6. ENT.Base = "base_nextbot"
  7. ENT.Spawnable = true
  8.  
  9. function ENT:Initialize()
  10.  
  11. self:SetModel( "models/hunter.mdl" )
  12.  
  13. self.LoseTargetDist = 2000 -- How far the enemy has to be before we lose them
  14. self.SearchRadius = 1000 -- How far to search for enemies
  15. NPC:setSquad("JMCS_BaseSquad")
  16. local name = NPC:getNearestSquadMember()
  17. NPC:give("GM_SMG")
  18. NPC:give("gm_grenade")
  19. NPC:give("gm_crowbar")
  20. NextBot:setFOV(20)
  21.  
  22. end
  23.  
  24. ----------------------------------------------------
  25. -- ENT:Get/SetEnemy()
  26. -- Simple functions used in keeping our enemy saved
  27. ----------------------------------------------------
  28. function ENT:SetEnemy(ent)
  29. self.Enemy = ent
  30. end
  31. function ENT:GetEnemy()
  32. return self.Enemy
  33. end
  34.  
  35. ----------------------------------------------------
  36. -- ENT:HaveEnemy()
  37. -- Returns true if we have a enemy
  38. ----------------------------------------------------
  39. function ENT:HaveEnemy()
  40. -- If our current enemy is valid
  41. if ( self:GetEnemy() and IsValid(self:GetEnemy()) ) then
  42. -- If the enemy is too far
  43. if ( self:GetRangeTo(self:GetEnemy():GetPos()) > self.LoseTargetDist ) then
  44. -- If the enemy is lost then call FindEnemy() to look for a new one
  45. -- FindEnemy() will return true if an enemy is found, making this function return true
  46. return self:FindEnemy()
  47. -- If the enemy is dead( we have to check if its a player before we use Alive() )
  48. elseif ( self:GetEnemy():IsPlayer() and !self:GetEnemy():Alive() ) then
  49. return self:FindEnemy() -- Return false if the search finds nothing
  50. end
  51. -- The enemy is neither too far nor too dead so we can return true
  52. return true
  53. else
  54. -- The enemy isn't valid so lets look for a new one
  55. return self:FindEnemy()
  56. end
  57. end
  58.  
  59. ----------------------------------------------------
  60. -- ENT:FindEnemy()
  61. -- Returns true and sets our enemy if we find one
  62. ----------------------------------------------------
  63. function ENT:FindEnemy()
  64. -- Search around us for entities
  65. -- This can be done any way you want eg. ents.FindInCone() to replicate eyesight
  66. local _ents = ents.FindInSphere( self:GetPos(), self.SearchRadius )
  67. -- Here we loop through every entity the above search finds and see if it's the one we want
  68. for k,v in ipairs( _ents ) do
  69. if ( v:IsPlayer() ) then
  70. -- We found one so lets set it as our enemy and return true
  71. self:SetEnemy(v)
  72. return true
  73. end
  74. end
  75. -- We found nothing so we will set our enemy as nil (nothing) and return false
  76. self:SetEnemy(nil)
  77. return false
  78. end
  79.  
  80. ----------------------------------------------------
  81. -- ENT:RunBehaviour()
  82. -- This is where the meat of our AI is
  83. ----------------------------------------------------
  84.  
  85. function ENT:CommandStructureUpdate()
  86. if SquadCommandState == 0 then
  87. HasSurrendered = true
  88. NPC:DropWeapon( Weapon weapon = nil, Vector target = nil, Vector velocity = nil )
  89. NPC:FearSound()
  90. NPC:SetActivity(ACT_COWER)
  91. elseif SquadCommandState == 1 then
  92. NPC:FearSound()
  93. NPC:SetActivity(ACT_RUN_SCARED)
  94. elseif SquadCommandState == 2 then
  95.  
  96. elseif SquadCommandState == 3 then
  97.  
  98. end
  99. end
  100.  
  101. function ENT:RunBehaviour()
  102. -- This function is called when the entity is first spawned. It acts as a giant loop that will run as long as the NPC exists
  103. while ( true ) do
  104. local Victim = NextBot:OnOtherKilled()
  105. if Victim == nil then
  106.  
  107. else
  108. if Victim.GetSquad() == self.GetSquad() then
  109. if Victim.GetName() == "JMCS_SquadLeader" then
  110. print("a Unit has noticed their Squad Leader is dead, Lowering Organization")
  111. SquadCommandState = 1
  112. ENT:CommandStructureUpdate()
  113. end
  114. end
  115. end
  116. if ( NPC:HasCondition(HP < 5) == true and SquadCommandStructure < 2 ) then
  117. SquadCommandState = 0
  118. ENT:CommandStructureUpdate()
  119. end
  120. -- Lets use the above mentioned functions to see if we have/can find a enemy
  121. if ( self:HaveEnemy() && HasSurrendered == false ) then
  122. -- Now that we have an enemy, the code in this block will run
  123. self.loco:FaceTowards(self:GetEnemy():GetPos()) -- Face our enemy
  124. self:PlaySequenceAndWait( "plant" ) -- Lets make a pose to show we found a enemy
  125. self:PlaySequenceAndWait( "hunter_angry" )-- Play an animation to show the enemy we are angry
  126. self:PlaySequenceAndWait( "unplant" ) -- Get out of the pose
  127. self:StartActivity( ACT_RUN ) -- Set the animation
  128. self.loco:SetDesiredSpeed( 450 ) -- Set the speed that we will be moving at. Don't worry, the animation will speed up/slow down to match
  129. self.loco:SetAcceleration(900) -- We are going to run at the enemy quickly, so we want to accelerate really fast
  130. self:ChaseEnemy( ) -- The new function like MoveToPos.
  131. self.loco:SetAcceleration(400) -- Set this back to its default since we are done chasing the enemy
  132. self:PlaySequenceAndWait( "charge_miss_slide" ) -- Lets play a fancy animation when we stop moving
  133. self:StartActivity( ACT_IDLE ) --We are done so go back to idle
  134. -- Now once the above function is finished doing what it needs to do, the code will loop back to the start
  135. -- unless you put stuff after the if statement. Then that will be run before it loops
  136. else
  137. -- Since we can't find an enemy, lets wander
  138. -- Its the same code used in Garry's test bot
  139. self:StartActivity( ACT_WALK ) -- Walk anmimation
  140. self.loco:SetDesiredSpeed( 200 ) -- Walk speed
  141. self:MoveToPos( self:GetPos() + Vector( math.Rand( -1, 1 ), math.Rand( -1, 1 ), 0 ) * 400 ) -- Walk to a random place within about 400 units (yielding)
  142. self:StartActivity( ACT_IDLE )
  143. end
  144. -- At this point in the code the bot has stopped chasing the player or finished walking to a random spot
  145. -- Using this next function we are going to wait 2 seconds until we go ahead and repeat it
  146. coroutine.wait(2)
  147.  
  148. end
  149.  
  150. end
  151.  
  152. ----------------------------------------------------
  153. -- ENT:ChaseEnemy()
  154. -- Works similarly to Garry's MoveToPos function
  155. -- except it will constantly follow the
  156. -- position of the enemy until there no longer
  157. -- is one.
  158. ----------------------------------------------------
  159. function ENT:ChaseEnemy( options )
  160.  
  161. local options = options or {}
  162. local path = Path( "Follow" )
  163. path:SetMinLookAheadDistance( options.lookahead or 300 )
  164. path:SetGoalTolerance( options.tolerance or 20 )
  165. path:Compute( self, self:GetEnemy():GetPos() ) -- Compute the path towards the enemies position
  166.  
  167. if ( !path:IsValid() ) then return "failed" end
  168.  
  169. while ( path:IsValid() and self:HaveEnemy() ) do
  170.  
  171. if ( path:GetAge() > 0.1 ) then -- Since we are following the player we have to constantly remake the path
  172. path:Compute(self, self:GetEnemy():GetPos())-- Compute the path towards the enemy's position again
  173. end
  174. path:Update( self ) -- This function moves the bot along the path
  175.  
  176. if ( options.draw ) then path:Draw() end
  177. -- If we're stuck, then call the HandleStuck function and abandon
  178. if ( self.loco:IsStuck() ) then
  179. self:HandleStuck()
  180. return "stuck"
  181. end
  182.  
  183. coroutine.yield()
  184.  
  185. end
  186.  
  187. return "ok"
  188.  
  189. end
  190.  
  191. list.Set( "NPC", "JMCS_Rifleman", {
  192. Name = "Rifle Infantry",
  193. Class = "simple_nextbot",
  194. Category = "Nextbot"
  195. })
Add Comment
Please, Sign In to add comment