drgbase
drgbase copied to clipboard
DRG Nextbots struggle to climb up on terrain geometry
DRG Nextbots seem to struggle to climb up on cliff/ledges, it seems to work slightly better in singleplayer. I've attached a video (on a server + gamemode) as an example. I've also attached the relevant map and code (and models).
https://github.com/user-attachments/assets/bb29e3df-0b0e-411c-82f5-acfd6be56cad
Map - https://steamcommunity.com/sharedfiles/filedetails/?id=2442244710
sv_cheats 1; setpos 4491.984375 -6580.143555 -862.054932;setang 70.255936 86.783928 0.000000
to get to the cliff shown in video
Models - https://steamcommunity.com/sharedfiles/filedetails/?id=2790936125
Code can be found at https://github.com/DETrooper/Begotten-III but I've attached the code for the particular nextbot below
if not DrGBase then return end -- return if DrGBase isn't installed
ENT.Base = "drgbase_nextbot" -- DO NOT TOUCH (obviously)
-- Misc --
ENT.PrintName = "Eddie"
ENT.Category = "Begotten DRG"
ENT.Models = {"models/begotten/thralls/eddie.mdl"}
ENT.BloodColor = BLOOD_COLOR_RED
ENT.RagdollOnDeath = true;
-- Sounds --
ENT.OnDamageSounds = {"begotten/npc/grunt/attack_claw01.mp3", "begotten/npc/grunt/attack_claw02.mp3", "begotten/npc/grunt/attack_claw03.mp3"}
ENT.OnDeathSounds = {"begotten/npc/grunt/amb_idle_scratch01.mp3", "begotten/npc/grunt/amb_idle_scratch02.mp3", "begotten/npc/grunt/amb_idle_scratch03.mp3"}
ENT.PainSounds = {"begotten/npc/grunt/attack_launch01.mp3", "begotten/npc/grunt/attack_launch02.mp3"};
-- Stats --
ENT.SpawnHealth = 500
ENT.SpotDuration = 20
-- AI --
ENT.RangeAttackRange = 0
ENT.MeleeAttackRange = 120
ENT.ReachEnemyRange = 60
ENT.AvoidEnemyRange = 0
ENT.HearingCoefficient = 0.5
ENT.SightFOV = 300
ENT.SightRange = 1024
ENT.XPValue = 60;
-- Relationships --
ENT.Factions = {FACTION_ZOMBIES}
-- Movements/animations --
ENT.UseWalkframes = true
ENT.RunAnimation = ACT_RUN
ENT.JumpAnimation = "releasecrab"
ENT.RunAnimRate = 0
-- Climbing --
ENT.ClimbLedges = true
ENT.ClimbProps = true
ENT.ClimbLedgesMaxHeight = 300
ENT.ClimbLadders = true
ENT.ClimbSpeed = 100
ENT.ClimbUpAnimation = "run_all_grenade"--ACT_ZOMBIE_CLIMB_UP --pull_grenade
ENT.ClimbOffset = Vector(-14, 0, 0)
ENT.ArmorPiercing = 55;
ENT.Damage = 50;
-- Detection --
ENT.EyeBone = "ValveBiped.Bip01_Spine4"
ENT.EyeOffset = Vector(7.5, 0, 5)
-- Possession --
ENT.PossessionEnabled = true
ENT.PossessionMovement = POSSESSION_MOVE_8DIR
ENT.PossessionViews = {
{
offset = Vector(0, 30, 20),
distance = 100
},
{
offset = Vector(7.5, 0, 0),
distance = 0,
eyepos = true
}
}
ENT.PossessionBinds = {
[IN_ATTACK] = {{
coroutine = true,
onkeydown = function(self)
self:EmitSound("begotten/npc/grunt/attack_launch0"..math.random(1, 3)..".mp3", 100, self.pitch)
self:PlayActivityAndMove(ACT_MELEE_ATTACK1, 1, self.PossessionFaceForward)
end
}}
}
if (CLIENT) then
end;
if SERVER then
function ENT:OnSpotted()
local curTime = CurTime();
if (!self.nextNotice or self.nextNotice < curTime) then
self.nextNotice = curTime + 20
self:EmitSound("begotten/npc/grunt/enabled0"..math.random(1, 4)..".mp3", 100, self.pitch)
end;
-- self:Jump(100)
end
function ENT:OnLost()
local curTime = CurTime();
if (!self.nextLo or self.nextLo < curTime) then
self.nextLo = curTime + 20
self:EmitSound("begotten/npc/grunt/amb_alert0"..math.random(1, 3)..".mp3", 100, self.pitch)
end;
end
function ENT:OnParried()
self.nextMeleeAttack = CurTime() + 2;
end
-- Init/Think --
function ENT:CustomInitialize()
self:SetDefaultRelationship(D_HT)
self:EmitSound("begotten/npc/grunt/enabled0"..math.random(1, 4)..".mp3");
end
-- AI --
function ENT:OnMeleeAttack(enemy)
if !self.nextMeleeAttack or self.nextMeleeAttack < CurTime() then
self:EmitSound("begotten/npc/grunt/attack_launch0"..math.random(1, 3)..".mp3", 100, self.pitch)
self:PlayActivityAndMove(ACT_MELEE_ATTACK1, 1, self.FaceEnemy)
end
end
function ENT:OnReachedPatrol()
self:Wait(math.random(3, 7))
end
function ENT:ShouldIgnore(ent)
if ent:IsPlayer() and (ent.possessor or ent.victim) then
return true;
end
end
function ENT:WhilePatrolling()
self:OnIdle()
end
function ENT:OnIdle()
local curTime = CurTime();
if (!self.nextId or self.nextId < curTime) then
self.nextId = curTime + 10
self:EmitSound("begotten/npc/grunt/amb_idle0"..math.random(1, 5)..".mp3", 100, self.pitch)
self:AddPatrolPos(self:RandomPos(1500))
end;
end
-- Damage --
function ENT:OnDeath(dmg, delay, hitgroup)
end
function ENT:OnRagdoll(dmg)
local ragdoll = self;
if IsValid(ragdoll) then
ParticleEffectAttach("doom_dissolve", PATTACH_POINT_FOLLOW, ragdoll, 0);
timer.Simple(1.6, function()
if IsValid(ragdoll) then
ParticleEffectAttach("doom_dissolve_flameburst", PATTACH_POINT_FOLLOW, ragdoll, 0);
ragdoll:Fire("fadeandremove", 1);
ragdoll:EmitSound("begotten/npc/burn.wav");
if cwRituals and cwItemSpawner then
local randomItem;
local spawnable = cwItemSpawner:GetSpawnableItems(true);
local lootPool = {};
for _, itemTable in ipairs(spawnable) do
if itemTable.category == "Catalysts" then
if itemTable.itemSpawnerInfo and !itemTable.itemSpawnerInfo.supercrateOnly then
table.insert(lootPool, itemTable);
end
end
end
randomItem = lootPool[math.random(1, #lootPool)];
if randomItem then
local itemInstance = item.CreateInstance(randomItem.uniqueID);
if itemInstance then
local entity = Clockwork.entity:CreateItem(nil, itemInstance, ragdoll:GetPos() + Vector(0, 0, 16));
entity.lifeTime = CurTime() + config.GetVal("loot_item_lifetime");
table.insert(cwItemSpawner.ItemsSpawned, entity);
end
end
end
end;
end)
return true;
end
end
function ENT:Makeup()
end;
ENT.ModelScale = 1
ENT.pitch = 100
function ENT:CustomThink()
if (!self.lastStuck and self:IsStuck()) then
self.lastStuck = CurTime() + 2;
end;
if (self.lastStuck and self.lastStuck < CurTime()) then
if (self:IsStuck()) then
--self:Jump(500)
self:MoveForward(5000, function() return true end)
end;
self.lastStuck = nil
end;
end
-- Animations/Sounds --
function ENT:OnNewEnemy()
self:EmitSound("begotten/npc/grunt/notice0"..math.random(1,4)..".mp3", 100, self.pitch)
end
function ENT:OnChaseEnemy()
local curTime = CurTime();
if (!self.nextId or self.nextId < curTime) then
self.nextId = curTime + math.random(7, 15)
self:EmitSound("begotten/npc/grunt/amb_hunt0"..math.random(1,4)..".mp3", 100, self.pitch)
end;
end
function ENT:OnLandedOnGround()
end;
function ENT:OnAnimEvent()
local sha = false
if self:IsAttacking() and self:GetCycle() > 0.3 then
self:Attack({
damage = self.Damage,
type = DMG_SLASH,
viewpunch = Angle(20, math.random(-10, 10), 0)
}, function(self, hit)
if #hit > 0 then
self:EmitSound("begotten/npc/grunt/attack_claw_hit0"..math.random(1,3)..".mp3", 100, self.pitch)
else self:EmitSound("Zombie.AttackMiss") end
end)
--[[elseif math.random(2) == 1 then
self:EmitSound("npc/zombie_poison/pz_right_foot1.wav")
else
self:EmitSound("npc/zombie_poison/pz_left_foot1.wav")]]--
end
end
end
-- DO NOT TOUCH --
AddCSLuaFile()
DrGBase.AddNextbot(ENT)
If you prefer to speak on steam, add me here https://steamcommunity.com/id/totallysprite/