Exemplo n.º 1
0
    /// <summary>
    /// Gets the nearest chunk. And builds a list on chunkList
    /// </summary>
    /// <returns>The nearest chunk item.</returns>
    /// <param name="allChunks">All chunks the AI knows of.</param>
    private FloatingChunk GetNearestChunkItem(List <FloatingChunk> allChunks)
    {
        FloatingChunk chosenChunk = null;

        Vector3 testPosition = new Vector3(0, 0, 0);
        bool    setPosition  = true;

        // Retrieve nearest potential chunk
        foreach (var chunk in allChunks)
        {
            if ((SpeciesOpportunism == Constants.MAX_SPECIES_OPPORTUNISM) ||
                ((microbe.EngulfSize * (SpeciesOpportunism / Constants.OPPORTUNISM_DIVISOR)) >
                 chunk.Size))
            {
                chunkList.Add(chunk);
                var thisPosition = chunk.Translation;

                if (setPosition)
                {
                    testPosition = thisPosition;
                    setPosition  = false;
                    chosenChunk  = chunk;
                }

                if ((testPosition - microbe.Translation).LengthSquared() >
                    (thisPosition - microbe.Translation).LengthSquared())
                {
                    testPosition = thisPosition;
                    chosenChunk  = chunk;
                }
            }
        }

        return(chosenChunk);
    }
Exemplo n.º 2
0
    /// <summary>
    ///   For chasing down and eating chunks in various ways
    /// </summary>
    /// <param name="chunk">Chunk.</param>
    /// <param name="allChunks">All chunks.</param>
    private void DealWithChunks(FloatingChunk chunk, List <FloatingChunk> allChunks)
    {
        // Tick the engulf tick
        ticksSinceLastToggle += 1;

        // TODO: do something with the chunk compounds
        // ReSharper disable once NotAccessedVariable
        CompoundBag compounds;

        try
        {
            // ReSharper disable once RedundantAssignment
            compounds      = chunk.ContainedCompounds;
            targetPosition = chunk.Translation;
        }
        catch (ObjectDisposedException)
        {
            // Turn off engulf if chunk is gone
            targetChunk = null;

            hasTargetPosition  = false;
            targetChunk        = GetNearestChunkItem(allChunks);
            microbe.EngulfMode = false;

            // You got a consumption, good job
            if (!microbe.IsPlayerMicrobe && !microbe.Species.PlayerSpecies)
            {
                microbe.SuccessfulScavenge();
            }

            return;
        }

        microbe.LookAtPoint = targetPosition;
        hasTargetPosition   = true;

        // Always set target Position, for use later in AI
        microbe.MovementDirection = new Vector3(0.0f, 0.0f, -Constants.AI_BASE_MOVEMENT);

        // Turn on engulfmode if close
        if ((microbe.Translation - targetPosition).LengthSquared() <= 300 +
            microbe.EngulfSize * 3.0f &&
            microbe.Compounds.GetCompoundAmount(atp) >= 1.0f &&
            !microbe.EngulfMode &&
            microbe.EngulfSize > Constants.ENGULF_SIZE_RATIO_REQ * chunk.Size &&
            !microbe.Membrane.Type.CellWall)
        {
            microbe.EngulfMode   = true;
            ticksSinceLastToggle = 0;
        }
        else if ((microbe.Translation - targetPosition).LengthSquared() >=
                 500 + microbe.EngulfSize * 3.0f && microbe.EngulfMode && ticksSinceLastToggle >=
                 Constants.AI_ENGULF_INTERVAL)
        {
            microbe.EngulfMode   = false;
            ticksSinceLastToggle = 0;
        }
    }
Exemplo n.º 3
0
    /// <summary>
    ///   For chasing down and eating chunks in various ways
    /// </summary>
    /// <param name="chunk">Chunk.</param>
    /// <param name="allChunks">All chunks.</param>
    private void DealWithChunks(FloatingChunk chunk, List <FloatingChunk> allChunks)
    {
        // Tick the engulf tick
        ticksSinceLastToggle += 1;

        CompoundBag compounds;

        try
        {
            compounds      = chunk.ContainedCompounds;
            targetPosition = chunk.Translation;
        }
        catch (ObjectDisposedException)
        {
            // Turn off engulf if chunk is gone
            targetChunk = null;

            hasTargetPosition  = false;
            targetChunk        = GetNearestChunkItem(allChunks);
            microbe.EngulfMode = false;

            // You got a consumption, good job
            if (!microbe.IsPlayerMicrobe && !microbe.Species.PlayerSpecies)
            {
                // TODO: fix
                // MicrobeOperations::alterSpeciesPopulation(species,
                //    CREATURE_SCAVENGE_POPULATION_GAIN, "successful scavenge");
            }

            return;
        }

        microbe.LookAtPoint = targetPosition;
        hasTargetPosition   = true;

        // Always set target Position, for use later in AI
        microbe.MovementDirection = new Vector3(0.0f, 0.0f, -Constants.AI_BASE_MOVEMENT);

        // Turn on engulfmode if close
        if ((microbe.Translation - targetPosition).LengthSquared() <= 300 +
            microbe.EngulfSize * 3.0f &&
            microbe.Compounds.GetCompoundAmount(atp) >= 1.0f &&
            !microbe.EngulfMode &&
            microbe.EngulfSize > Constants.ENGULF_SIZE_RATIO_REQ * chunk.Size)
        {
            microbe.EngulfMode   = true;
            ticksSinceLastToggle = 0;
        }
        else if ((microbe.Translation - targetPosition).LengthSquared() >=
                 500 + microbe.EngulfSize * 3.0f && microbe.EngulfMode && ticksSinceLastToggle >=
                 Constants.AI_ENGULF_INTERVAL)
        {
            microbe.EngulfMode   = false;
            ticksSinceLastToggle = 0;
        }
    }
Exemplo n.º 4
0
    /// <summary>
    ///   Clears all the found targets. Currently used for loading from saves
    /// </summary>
    public void ClearAfterLoadedFromSave(Microbe newParent)
    {
        microbe = newParent;
        chunkList?.Clear();
        predator = null;
        predatoryMicrobes.Clear();
        prey = null;
        preyMicrobes.Clear();
        targetChunk = null;

        // Probably should clear this
        preyPegged = false;
    }
Exemplo n.º 5
0
    /// <summary>
    ///   A bit on the lighter save properties copying,
    ///   the spawn function used to create this needs to set some stuff beforehand
    /// </summary>
    public void ApplyPropertiesFromSave(FloatingChunk chunk)
    {
        NodeGroupSaveHelper.CopyGroups(this, chunk);

        VentPerSecond = chunk.VentPerSecond;
        Dissolves     = chunk.Dissolves;
        Size          = chunk.Size;
        Damages       = chunk.Damages;
        DeleteOnTouch = chunk.DeleteOnTouch;
        Mass          = chunk.Mass;
        Radius        = chunk.Radius;
        ChunkScale    = chunk.ChunkScale;

        ContainedCompounds = chunk.ContainedCompounds;
        Transform          = chunk.Transform;
        LinearVelocity     = chunk.LinearVelocity;
        AngularVelocity    = chunk.AngularVelocity;
    }
Exemplo n.º 6
0
    public void Think(float delta, Random random, MicrobeAICommonData data)
    {
        _ = delta;

        // SetRandomTargetAndSpeed(random);

        // Clear the lists
        predatoryMicrobes.Clear();
        preyMicrobes.Clear();
        chunkList.Clear();

        prey = null;

        // 30 seconds about
        if (boredom == (int)random.Next(SpeciesFocus * 2, 1000.0f + SpeciesFocus * 2))
        {
            // Occasionally you need to reevaluate things
            boredom = 0;
            if (RollCheck(SpeciesActivity, 400, random))
            {
                lifeState = LifeState.PLANTLIKE_STATE;
            }
            else
            {
                lifeState = LifeState.NEUTRAL_STATE;
            }
        }
        else
        {
            boredom++;
        }

        switch (lifeState)
        {
        case LifeState.PLANTLIKE_STATE:
            // This ai would ideally just sit there, until it sees a nice opportunity pop-up unlike neutral,
            // which wanders randomly (has a gather chance) until something interesting pops up
            break;

        case LifeState.NEUTRAL_STATE:
        {
            // Before these would run every time, now they just run for the states that need them.
            boredom    = 0;
            preyPegged = false;
            prey       = null;
            if (predator == null)
            {
                GetNearestPredatorItem(data.AllMicrobes);
            }

            // Peg your prey
            if (!preyPegged)
            {
                prey = null;
                prey = GetNearestPreyItem(data.AllMicrobes);
                if (prey != null)
                {
                    preyPegged = true;
                }
            }

            if (targetChunk == null)
            {
                targetChunk = GetNearestChunkItem(data.AllChunks);
            }

            EvaluateEnvironment(random);
            break;
        }

        case LifeState.GATHERING_STATE:
        {
            // In this state you gather compounds
            if (RollCheck(SpeciesOpportunism, 400.0f, random))
            {
                lifeState = LifeState.SCAVENGING_STATE;
                boredom   = 0;
            }
            else
            {
                DoRunAndTumble(random);
            }

            break;
        }

        case LifeState.FLEEING_STATE:
        {
            if (predator == null)
            {
                GetNearestPredatorItem(data.AllMicrobes);
            }

            // In this state you run from predatory microbes
            if (predator != null)
            {
                DealWithPredators(random);
            }
            else
            {
                if (RollCheck(SpeciesActivity, 400, random))
                {
                    lifeState = LifeState.PLANTLIKE_STATE;
                    boredom   = 0;
                }
                else
                {
                    lifeState = LifeState.NEUTRAL_STATE;
                }
            }

            break;
        }

        case LifeState.PREDATING_STATE:
        {
            // Peg your prey
            if (!preyPegged)
            {
                prey = null;
                prey = GetNearestPreyItem(data.AllMicrobes);
                if (prey != null)
                {
                    preyPegged = true;
                }
            }

            if (preyPegged && prey != null)
            {
                DealWithPrey(data.AllMicrobes, random);
            }
            else
            {
                if (RollCheck(SpeciesActivity, 400, random))
                {
                    lifeState = LifeState.PLANTLIKE_STATE;
                    boredom   = 0;
                }
                else
                {
                    lifeState = LifeState.NEUTRAL_STATE;
                }
            }

            break;
        }

        case LifeState.SCAVENGING_STATE:
        {
            if (targetChunk == null)
            {
                targetChunk = GetNearestChunkItem(data.AllChunks);
            }

            if (targetChunk != null)
            {
                DealWithChunks(targetChunk, data.AllChunks);
            }
            else
            {
                if (!RollCheck(SpeciesOpportunism, 400, random))
                {
                    lifeState = LifeState.NEUTRAL_STATE;
                    boredom   = 0;
                }
                else
                {
                    lifeState = LifeState.SCAVENGING_STATE;
                }
            }

            break;
        }
        }

        // Run reflexes
        DoReflexes();

        // Clear the absorbed compounds for run and rumble
        microbe.TotalAbsorbedCompounds.Clear();
    }
Exemplo n.º 7
0
 public void TriggerOnChunkSpawned(FloatingChunk chunk, bool environmental)
 {
     OnChunkSpawned?.Invoke(chunk, environmental);
 }
Exemplo n.º 8
0
    private FloatingChunk GetNearestChunkItem(List <FloatingChunk> allChunks, List <Microbe> allMicrobes, Random random)
    {
        FloatingChunk chosenChunk = null;

        // If the microbe cannot absorb, no need for this
        if (microbe.Membrane.Type.CellWall)
        {
            return(null);
        }

        // Retrieve nearest potential chunk
        foreach (var chunk in allChunks)
        {
            if (microbe.EngulfSize > chunk.Size * Constants.ENGULF_SIZE_RATIO_REQ &&
                (chunk.Translation - microbe.Translation).LengthSquared()
                <= (20000.0 * SpeciesFocus / Constants.MAX_SPECIES_FOCUS) + 1500.0)
            {
                if (chunk.ContainedCompounds.Compounds.Any(x => microbe.Compounds.IsUseful(x.Key)))
                {
                    if (chosenChunk == null ||
                        (chosenChunk.Translation - microbe.Translation).LengthSquared() >
                        (chunk.Translation - microbe.Translation).LengthSquared())
                    {
                        chosenChunk = chunk;
                    }
                }
            }
        }

        // Don't bother with chunks when there's a lot of microbes to compete with
        if (chosenChunk != null)
        {
            var rivals          = 0;
            var distanceToChunk = (microbe.Translation - chosenChunk.Translation).LengthSquared();
            foreach (var rival in allMicrobes)
            {
                if (rival != microbe)
                {
                    var rivalDistance = (rival.GlobalTransform.origin - chosenChunk.Translation).LengthSquared();
                    if (rivalDistance < 500.0f &&
                        rivalDistance < distanceToChunk)
                    {
                        rivals++;
                    }
                }
            }

            int rivalThreshold;
            if (SpeciesOpportunism < Constants.MAX_SPECIES_OPPORTUNISM / 3)
            {
                rivalThreshold = 1;
            }
            else if (SpeciesOpportunism < Constants.MAX_SPECIES_OPPORTUNISM * 2 / 3)
            {
                rivalThreshold = 3;
            }
            else
            {
                rivalThreshold = 5;
            }

            // In rare instances, microbes will choose to be much more ambitious
            if (RollCheck(SpeciesFocus, Constants.MAX_SPECIES_FOCUS, random))
            {
                rivalThreshold *= 2;
            }

            if (rivals > rivalThreshold)
            {
                chosenChunk = null;
            }
        }

        return(chosenChunk);
    }