Dadido3 / D3bot

A very primitive AI for GMod bots designed to work with Jetboom's Zombie Survival gamemode.
38 stars 27 forks source link

Bots creating a nests #127

Open SeekerTheTruth opened 3 months ago

SeekerTheTruth commented 3 months ago

Is it possible to create a specific parameter for a node, for example "Nest", which would allow the bot to search for a specific point on the map? One of the bots (with a given class/name) must specifically search for this specific node, and when it is found, the bot writes the “kill” command to the console, thereby creating a nest next to the node.

I managed to find a function responsible for nest spawning, and successfully added it in the class of a specific zombie. However, some problems arose, more precisely, the uncontrolled respawning of nests, including right in front of the barricades. I'll try to add conditions for the distance to the players and sigils. Taking into account the fact that you can create your own network of nodes for bots, it would be possible to precisely control the creation of nests through it.

How difficult would such a task be?

Dadido3 commented 3 months ago

Hi,

The parameter approach should be doable. The first thing you need to do is to add the key/value pair to the table of available parameters: https://github.com/Dadido3/D3bot/blob/7ed12dc8a51e74f98ae82703f2c4885afc415e36/lua/d3bot/1_navmesh.lua#L50-L74

(Technically it's not necessary to add anything to this table, its only use is automatic correction of parameter names)

After that you can use the !bot setparam ... command to set your custom parameter to navmesh nodes (or links).

Then it's up to you how you use your parameter in your bot handler. You can iterate over all nodes and find the closest node that has your "nest". Just set that as NodeTgt of your bot. Once the bot reaches that target it kills itself or does whatever it needs to do to spawn a nest.

Some details:

SeekerTheTruth commented 3 months ago

I apologize for not saying hello, ^_^

Thank you for your answer, I will try to finish what I planned earlier over the next week. If I achieve success, I will post here and also attach the code.

Dadido3 commented 3 months ago

I apologize for not saying hello, ^_^

If that's in response to my oversized Hi, that wasn't on purpose. For some reason GitHub added a heading to my markdown, without me noticing.

And yeah, feel free to ask questions or post any progress here. This may also be helpful for other users who want to implement something similar.

SeekerTheTruth commented 2 months ago

Unfortunately, I didn’t have time to work on nodes this week. I'll get to it later.

But, I was able to add a check for the distance between bots and sigils, but it works relatively stably with only one sigil on the map. If at least a sigil (out of three) with a distance of less than 900 units appears in the calculation, then the condition is met and the nest appears. I'll think about how to fix this later.

Code added to fresh_creeper.lua

if SERVER then function CLASS:OnKilled(pl, attacker, inflictor, suicide, headshot, dmginfo)

    local CheckDist = false
        for _, pl in pairs(team.GetPlayers(TEAM_UNDEAD)) do -- check all z
            local b = pl:GetPos()   
                b1 = math.Round(b[1], 1) --x coordinat
                b2 = math.Round(b[2], 1) --y coordinat
                b3 = math.Round(b[3], 1) --z coordinat
            if pl:Team() == TEAM_UNDEAD and pl:GetZombieClassTable().Name == "Flesh Creeper" then --check for special class
                for _, sigs in pairs(ents.FindByClass("prop_obj_sigil")) do -- check for avaible sigils
                    local c = sigs:GetPos() 
                    c1 = math.Round(c[1], 1) --x coordinat
                    c2 = math.Round(c[2], 1) --y coordinat
                    c3 = math.Round(c[3], 1) --z coordinat
                    local h1 = c1-b1 
                    local h2 = c2-b2
                    local h3 = c3-b3
                    local dist2 = math.sqrt(h1*h1 + h2*h2 + h3*h3)  --final distance calculation

                        if dist2 > 900 then --range condition
                            CheckDist = true
                        else
                            CheckDist = false
                        end                 
                end
            end
        end

    local ent = pl:FakeDeath(pl:LookupSequence("Flip1"), self.ModelScale, math.Rand(0.45, 0.5))
    if ent:IsValid() then
        ent:SetMaterial("models/flesh")
    end

        if CheckDist == true then --section of code responsible for the appearance of the socket
                local CpNs = ent:GetPos(ent)
                local ent2 = ents.Create("prop_creepernest")
                    if ent2:IsValid() then
                        ent2:SetPos(CpNs)
                        ent2:Spawn()
                        ent2.OwnerUID = uid
                        ent2:SetNestHealth(800 * math.random(0.6, 1)) --450
                        ent2:SetNestBuilt(true)
                        end
                    end
    return true
end end

It is worth noting that the appearance of nests leads to endless “blobs of meat”, which in the first waves leads to defeat. Only level 5 guns with 5 upgrades can somehow solve the situation. Attached a video of what happens when there is a ratio of 7 people to 22 zombies