Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- AddCSLuaFile("shared.lua")
- ENT.Base = "base_nextbot"
- ENT.Type = "nextbot"
- ENT.Spawnable = true
- ENT.PrintName = "Super Metropolice"
- ENT.Author = "Oploz"
- ENT.Contact = ""
- ENT.Instruction = ""
- ENT.Idle = ACT_IDLE
- ENT.Walk = ACT_WALK
- ENT.Run = ACT_RUN
- ENT.StandRifle = ACT_IDLE_ANGRY_SMG1
- ENT.StandPistol = ACT_IDLE_ANGRY_PISTOL
- ENT.Primary = {} --Weapon for long distance
- ENT.Primary.Sound1 = "Weapon_357.Single"
- ENT.Primary.Sound2 = "Weapon_Pistol.NPC_Single"
- ENT.Primary.Reload1 = "Weapon_357.Spin"
- ENT.Primary.Reload2 = "Weapon_Pistol.Reload"
- ENT.Primary.ReloadSequence = "reload_pistol"
- ENT.Primary.Act = ACT_GESTURE_RANGE_ATTACK_PISTOL
- ENT.Primary.ReloadAct = ACT_GESTURE_RELOAD_PISTOL
- util.PrecacheSound(ENT.Primary.Sound1)
- util.PrecacheSound(ENT.Primary.Reload1)
- util.PrecacheSound(ENT.Primary.Sound2)
- util.PrecacheSound(ENT.Primary.Reload2)
- function ENT:SetWeaponInfo()
- self.Primary.Name = "weapon_357" --Weapon classname
- self.Primary.Clip = 18 --Clip size
- self.Primary.Num = 1 --Amount of bullets per shot
- self.Primary.Spread = 5 --Spread
- self.Primary.Damage = 5 --Damage per bullets
- self.Primary.AmmoType = "357" --Ammo type
- self.Primary.Delay = 0.4 --Fire rate
- self.Primary.ReloadSoundDelay = 0.8 --Reloading sound delay
- self.Primary.MuzzleProbability = 0.5 --Probability of emitting muzzle flash
- self.Primary.MuzzleScale = 1 or 0.6 --Scale of muzzle flash
- self.Primary.Sound = self.Primary.Sound1 or self.Primary.Sound2 --Shooting sound
- self.Primary.Reload = self.Primary.Reload1 or self.Primary.Reload2 --Reloading sound
- self.Primary.Ammo = 200 --Ammo that the weapon now has
- end
- function ENT:Initialize()
- self:SetModel( "models/player/jesus/jesus.mdl" ) -- Remember
- self:SetHealth(125)
- self:SetWeaponInfo() -- Give Jesus his weapon
- self:ClearUserStuck()
- self.LoseTargetDist = 2000 -- How far the enemy has to be before we lose them
- self.SearchRadius = 1000 -- How far to search for enemies
- end
- -- Called when NPC thinks it is stuck
- function ENT:OnStuck()
- print(self, "OnStuck" )
- end
- -- Clears stuck
- function ENT:HandleStuck()
- self.loco:ClearStuck()
- print("No longer stuck")
- end
- -- Saves enemy as entity
- function ENT:SetEnemy( ent )
- self.Enemy = ent
- end
- -- Retrieve saved enemy
- function ENT:GetEnemy()
- return self.Enemy
- end
- -- Ensures we have an enemy
- function ENT:HaveEnemy()
- if ( self:GetEnemy() and IsValid( self:GetEnemy() ) ) then -- If our current enemy is valid
- if ( self:GetRangeTo( self:GetEnemy():GetPos() ) > self.LoseTargetDist ) then -- If the enemy is too far
- -- If the enemy is lost then call FindEnemy() to look for a new one
- -- FindEnemy() will return true if an enemy is found, making this function return true
- return self:FindEnemy()
- -- If the enemy is dead( we have to check if its a player before we use Alive() )
- elseif ( self:GetEnemy():IsPlayer() and !self:GetEnemy():Alive() ) then
- return self:FindEnemy() -- Return false if the search finds nothing
- end
- -- The enemy is neither too far nor too dead so we can return true
- return true
- else
- -- The enemy isn't valid so lets look for a new one
- return self:FindEnemy()
- end
- end
- -- Returns true and sets our enemy if we find one
- function ENT:FindEnemy()
- -- Search around us for entities
- local _ents = ents.FindInSphere( self:GetPos(), self.SearchRadius )
- if _ents != nil then
- for k, v in pairs( _ents ) do -- Here we loop through every entity the above search finds and see if it's the one we want
- if ( v:IsPlayer() and self:IsLineOfSightClear(v) and false ~= v:IsTraitor()) then
- -- We found a non traitor we can see so lets set it as our enemy and return true
- local lastdis = 2000
- local vdis = GetRangeTo(v)
- if vdis < lastdis then -- Ensures Jesus shoots at the closest target to him
- lastdis = vdis
- self:SetEnemy( v )
- end
- end
- end
- return true
- end
- self:SetEnemy( nil ) -- We found nothing so we will set our enemy as nil ( nothing ) and return false
- return false
- end
- --Gets a position for aiming at the enemy
- function ENT:GetTargetPos(aiming, target)
- -- for k, v in pairs(ents.FindInSphere(self:GetPos(), 200)) do
- -- if v:GetClass() == "npc_grenade_frag" then
- -- return v:GetPos()
- -- end
- -- end
- local e = target
- if not IsValid(e) then e = self:GetEnemy() end
- if not IsValid(e) then
- return self:GetEye().Pos + self:GetForward() * self.NearDistance
- end
- local dir, attach, bone = e:GetPos(), 0, nil
- if e:GetClass():find("headcrab") then
- return e:GetPos() + Vector(0, 0, 8)
- end
- if e:LookupBone("ValveBiped.Bip01_Head1") then
- attach = nil
- bone = e:LookupBone("ValveBiped.Bip01_Head1")
- dir = e:GetBonePosition(bone)
- elseif e:LookupBone("ValveBiped.Bip01_Neck1") then
- attach = nil
- bone = e:LookupBone("ValveBiped.Bip01_Neck1")
- dir = e:GetBonePosition(bone)
- elseif e:LookupBone("Bip01 Head") then --for Half-Life Source NPCs
- attach = nil
- bone = e:LookupBone("Bip01 Head")
- dir = e:GetBonePosition(bone)
- elseif e:LookupBone("Bip01 Neck") then --for Half-Life Source NPCs
- attach = nil
- bone = e:LookupBone("Bip01 Neck")
- dir = e:GetBonePosition(bone)
- elseif e:LookupBone("TorSkel Head") then --for Half-Life: Renaissance Tor
- attach = nil
- bone = e:LookupBone("TorSkel Head")
- dir = e:GetBonePosition(bone)
- elseif e:LookupAttachment("eyes") and e:LookupAttachment("eyes") > 0 then --for most human
- attach = e:LookupAttachment("eyes")
- dir = e:GetAttachment(attach).Pos
- elseif e:LookupAttachment("light") and e:LookupAttachment("light") > 0 then --for manhack
- attach = e:LookupAttachment("light")
- dir = e:GetAttachment(attach).Pos
- elseif e:GetAttachments() and #e:GetAttachments() > 0 then
- if aiming then
- self.aimattach = self.aimattach + 1
- if self.aimattach > #e:GetAttachments() then
- self.aimattach = 1
- end
- end
- attach = self.aimattach
- dir = e:GetAttachment(attach or 1).Pos
- end
- return dir
- end
- function ENT:FireWeapon(smg)
- if not (IsValid(self:GetEnemy()) or IsValid(self.Weapon)) then return end
- if not self.shoot then return end
- if self.Weapon:GetForward():Dot(self:GetAimVector()) < 0.9 then
- .loco:FaceTowards(self.lastsaw) return
- end
- if self.Weapon:GetNoDraw() then
- .Weapon:SetNoDraw(false)
- end
- local wep = self.Weapon
- local shootPos = self:GetMuzzle().Pos
- local WeaponInfo = self.havepistol and self.Primary or self.Secondary
- local delay = math.Clamp(WeaponInfo.Delay + self:XorRand(-0.1, 0.1), 0.05, 3)
- if WeaponInfo.Ammo <= 0 then
- return
- end
- if CurTime() < self.Time.Fired then
- return
- end
- self:AddGesture(WeaponInfo.Act)
- WeaponInfo.Ammo = WeaponInfo.Ammo - 1
- wep:EmitSound(WeaponInfo.Sound)
- local dir = self:GetTargetPos(true)
- -- local t = util.TraceLine({start = shootPos, endpos = dir, filter = {self, wep}})
- -- debugoverlay.Line(t.StartPos, t.HitPos, 1, Color(0, 255, 0, 255), false)
- local bullet = {
- Attacker = self,
- Num = WeaponInfo.Num,
- Src = shootPos,
- Dir = dir - shootPos,
- Spread = Vector(WeaponInfo.Spread, WeaponInfo.Spread, 0),
- Force = 10000,
- Tracer = 1,
- TracerName = "Tracer",
- Damage = WeaponInfo.Damage,
- AmmoType = WeaponInfo.AmmoType,
- Callback = function(attacker, tr, dmginfo)
- if not IsValid(attacker:GetEnemy()) then return end
- if not IsValid(tr.Entity) then return end
- if tr.Entity ~= attacker:GetEnemy() then return end
- dmginfo:SetInflictor(wep)
- local c = tr.Entity:GetClass()
- local health, maxhealth = tr.Entity:Health(), tr.Entity:GetMaxHealth()
- if health <= 0 then health = 1 end
- if maxhealth <= 0 then maxhealth = 1 end
- local speak_flag = health / maxhealth < 0.25
- if c == "npc_turret_floor" then
- -- tr.Entity:Fire("SelfDestruct")
- speak_flag = false
- elseif c == "npc_rollermine" then
- util.BlastDamage(wep, self, tr.Entity:GetPos(), 1, 1)
- speak_flag = false
- end
- if speak_flag then
- self:Speak(self.Sentence.EnemyHurt, self:CanSpeak())
- end
- end
- }
- self:FireBullets(bullet)
- self:MuzzleFlash()
- wep:MuzzleFlash()
- self.Time.Fired = CurTime() + delay
- self.Time.Moved = CurTime() + delay / 5
- local ef = EffectData()
- ef:SetOrigin( shootPos )
- ef:SetAngles( self:GetMuzzle().Ang )
- ef:SetScale( WeaponInfo.MuzzleScale )
- ef:SetEntity( wep )
- ef:SetEntIndex( wep:EntIndex() )
- ef:SetAttachment( wep:LookupAttachment( "muzzle" ) )
- if self:XorRand() < WeaponInfo.MuzzleProbability then
- util.Effect("MuzzleEffect", ef)
- end
- ef:SetAngles(self:GetMuzzle().Ang - Angle(0, 90, 0))
- ef:SetOrigin( shootPos - self:GetMuzzle().Ang:Forward() * 8 )
- ef:SetStart(self:GetRight())
- if eject then
- util.Effect("RifleShellEject", ef)
- end
- end
- function ENT:RunBehaviour()
- while ( true ) do
- if self:HaveEnemy() then -- Find or remember an enemy
- self.lastSeen = GetEnemy()
- else
- self.lastSeen = FindEnemy()
- end
- if IsValid( self.lastSeen ) and GetRangeTo( self.lastSeen ) < self.LoseTargetDist and self:IsLineOfSightClear( self.lastSeen ) then
- self.loco:FaceTowards(self.lastSeen)
- self:Aim(self.lastSeen)
- self:FireWeapon()
- end
- coroutine.yield() -- The function is done here
- end
- end
- list.Set( "NPC", "jesus_nextbot", {
- Name = "Simple bot",
- Class = "jesus_nextbot",
- Category = "NextBot"
- } )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement