Animals that eat prey animals they kill (RunUO 2.2)

Aschnyder26

Squire
Jul 6, 2016
280
27
28
Atlanta, GA
Shard Name
Europa UO
So I have set up opposition groups for the wildlife on my server. This way the carnivores hunt and kill the herbivores and weaker prey based similarly on what they would eat in the wild. There are a few things I would like to do. The first is somehow add a hunger measurement to the animals. The hungrier they are the higher chance they have of attacking their prey animals. I think this could be done using a switch that changes their FightMode from "Aggresor" to "Closest" at a certain hunger level. Thus switching on their aggression to their opposition group. Additionally when they do kill their prey animal they should fill their hunger back up just like when a player eats a food item. Also switching their FightMode back to "Aggressor" turning off their opposition aggression. Possibly displaying an overhead message similar to when a monster loots a corpse but instead it says something like * you see the animal eat its prey*

As of right now I am using
C#:
FightMode = Utility.RandomBool() ? FightMode.Closest : FightMode.Aggressor;
to try to balance out the amount of animals that are hunting. This helped but the animals that spawn are still hunting way too much. Basically 50% of the animals that spawn are hunting constantly. There are corpses all over the place. As soon as a prey animal spawns it is attacked and killed by surrounding carnivorous animals.

Also they were attacking players even though humans were not part of their opposition when their fightmode is set to "closest". I have added
C#:
public override bool IsEnemy( Mobile m )
        {
            if ( m.BodyValue == 400 || m.BodyValue == 401 )
                return false;

            return base.IsEnemy( m );
        }
and this seems to work well but is there a better way to do this? Here is a sample of how my animals are set up. Any help with working out the ideas mentioned above would be greatly appreciated.

C#:
using System;
using Server.Mobiles;

namespace Server.Mobiles
{
    [CorpseName( "a grizzly bear corpse" )]
    [TypeAlias( "Server.Mobiles.Grizzlybear" )]
    public class GrizzlyBear : BaseCreature
    {
        [Constructable]
        public GrizzlyBear() : base( AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
        {
            Name = "a grizzly bear";
            Body = 212;
            BaseSoundID = 0xA3;
       
            Tag = "Animal";

            FightMode = Utility.RandomBool() ? FightMode.Closest : FightMode.Aggressor;
       
            SetStr( 126, 155 );
            SetDex( 81, 105 );
            SetInt( 16, 40 );

            SetHits( 127, 155 );
            SetMana( 0 );

            SetDamage( 8, 13 );

            SetDamageType( ResistanceType.Physical, 100 );

            SetResistance( ResistanceType.Physical, 25, 35 );
            SetResistance( ResistanceType.Cold, 15, 25 );
            SetResistance( ResistanceType.Poison, 5, 10 );
            SetResistance( ResistanceType.Energy, 5, 10 );

            SetSkill( SkillName.MagicResist, 25.1, 40.0 );
            SetSkill( SkillName.Tactics, 70.1, 100.0 );
            SetSkill( SkillName.Wrestling, 45.1, 70.0 );
       
            Fame = 1000;
            Karma = 0;

            VirtualArmor = 24;
       
            Tamable = true;
            ControlSlots = 1;
            MinTameSkill = 70.0;
        }

        public override void GenerateLoot()
        {
            //AddLootPouch(LootPack.PoorPouch);
            AddLoot(LootPack.OldDirtPoor);
        }
   
        public override bool CanRummageCorpses{ get{ return true; } }
        public override int Meat{ get{ return 10; } }
        public override int Fur{ get{ return 16; } }
        public override FoodType FavoriteFood{ get{ return FoodType.Fish | FoodType.FruitsAndVegies | FoodType.Meat; } }
        public override PackInstinct PackInstinct{ get{ return PackInstinct.Bear; } }
        public override bool AlwaysMurderer { get { return true; } }

   
        public override OppositionGroup OppositionGroup
        {
            get{ return OppositionGroup.Bears; }
        }
   
        public override bool IsEnemy( Mobile m )
        {
            if ( m.BodyValue == 400 || m.BodyValue == 401 )
                return false;

            return base.IsEnemy( m );
        }
   
   
   
        public GrizzlyBear( Serial serial ) : base( serial )
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize( writer );

            writer.Write( (int) 0 );
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize( reader );

            int version = reader.ReadInt();
        }
    }
}
 
Last edited:

Vorspire

Vita-Nex: Core
Admin
ServUO Developer
Jul 29, 2013
1,177
289
83
33
United Kingdom
core.vita-nex.com
Shard Name
Ultima Shards: Multiverse
Donate
Donate money to this user
IMO, for a system like this, you need a grand illusion instead of standard logical mechanics.

The predators technically wouldn't be out and about if they're not hunting for food, but that depends on their species.
Having a hunger meter would make sense so long as their AI is constantly running, even when players are not around.
Otherwise, I think the best course of action would be to spawn and despawn the predators and prey, as needed, when players are in the general area.
Have them perform scripted attacks on prey, just for the sake of the show for any nearby players.

In WoW, wolves can appear out of nowhere, kill and eat a rabbit, then vanish back into the bushes just as fast - but this will only happen if you're nearby and can see it.
It's a scripted play of events, an illusion of predation.

Anyway, to answer your question "is there a better way to do this?"

C#:
FightMode = Utility.RandomList(FightMode.Closest, FightMode.Aggressor);
C#:
public override bool IsEnemy( Mobile m )
{
    if ( m.Body.IsHuman )
        return false;

    return base.IsEnemy( m );
}
 

Aschnyder26

Squire
Jul 6, 2016
280
27
28
Atlanta, GA
Shard Name
Europa UO
IMO, for a system like this, you need a grand illusion instead of standard logical mechanics.

The predators technically wouldn't be out and about if they're not hunting for food, but that depends on their species.
Having a hunger meter would make sense so long as their AI is constantly running, even when players are not around.
Otherwise, I think the best course of action would be to spawn and despawn the predators and prey, as needed, when players are in the general area.
Have them perform scripted attacks on prey, just for the sake of the show for any nearby players.

In WoW, wolves can appear out of nowhere, kill and eat a rabbit, then vanish back into the bushes just as fast - but this will only happen if you're nearby and can see it.
It's a scripted play of events, an illusion of predation.

Anyway, to answer your question "is there a better way to do this?"

C#:
FightMode = Utility.RandomList(FightMode.Closest, FightMode.Aggressor);
C#:
public override bool IsEnemy( Mobile m )
{
    if ( m.Body.IsHuman )
        return false;

    return base.IsEnemy( m );
}
Thanks Vorspire! I never thought about just creating the illusion. You make a good point though the illusion of the predator vs prey is really all I need, it doesn't mechanically serve any practical use. It will still change the experience of the player when they are out and about in the wild. Also thank you for cleaning that code up. If I do this using smart spawners I assume that means tediously hand placing special spawners across the entire map. I guess I was hoping to avoid this and use what I've already got. With that said it would also probably be better to create duplicate animal scripts just for that purpose wouldn't you think? This way the normal animals would roam around the map behaving normally and the duplicate "predatory" animals could be used only for the special smart spawns. Didn't you make a random encounter system Vorspire? Could I use something like that to accomplish this? Or is that driven solely through your Vita-Nex:Core?
Post automatically merged:

IMO, for a system like this, you need a grand illusion instead of standard logical mechanics.

The predators technically wouldn't be out and about if they're not hunting for food, but that depends on their species.
Having a hunger meter would make sense so long as their AI is constantly running, even when players are not around.
Otherwise, I think the best course of action would be to spawn and despawn the predators and prey, as needed, when players are in the general area.
Have them perform scripted attacks on prey, just for the sake of the show for any nearby players.

In WoW, wolves can appear out of nowhere, kill and eat a rabbit, then vanish back into the bushes just as fast - but this will only happen if you're nearby and can see it.
It's a scripted play of events, an illusion of predation.

Anyway, to answer your question "is there a better way to do this?"

C#:
FightMode = Utility.RandomList(FightMode.Closest, FightMode.Aggressor);
C#:
public override bool IsEnemy( Mobile m )
{
    if ( m.Body.IsHuman )
        return false;

    return base.IsEnemy( m );
}
When I use:
C#:
FightMode = Utility.RandomList(FightMode.Closest, FightMode.Aggressor);
I get an error. Looks like it is expecting an integer value instead.
C#:
Errors:
 + Mobiles/Animals/Bears/GrizzlyBear.cs:
    CS1502: Line 19: The best overloaded method match for 'Server.Utility.RandomList(params int[])' has some invalid arguments
    CS1503: Line 19: Argument 1: cannot convert from 'Server.Mobiles.FightMode' to 'int'
    CS1503: Line 19: Argument 2: cannot convert from 'Server.Mobiles.FightMode' to 'int'
 
Last edited:

Vorspire

Vita-Nex: Core
Admin
ServUO Developer
Jul 29, 2013
1,177
289
83
33
United Kingdom
core.vita-nex.com
Shard Name
Ultima Shards: Multiverse
Donate
Donate money to this user
try this instead
Code:
            FightMode = Utility.RandomBool() ? FightMode.Closest : FightMode.Aggressor;
That's the code they had originally, Utility.cs needs updated for generic support with this change;
C#:
		public static T RandomList<T>( params T[] list )
		{
			return list[RandomImpl.Next(list.Length)];
		}
That will make it support any given type, not just ints.

Thanks Vorspire! I never thought about just creating the illusion. You make a good point though the illusion of the predator vs prey is really all I need, it doesn't mechanically serve any practical use. It will still change the experience of the player when they are out and about in the wild. Also thank you for cleaning that code up. If I do this using smart spawners I assume that means tediously hand placing special spawners across the entire map. I guess I was hoping to avoid this and use what I've already got. With that said it would also probably be better to create duplicate animal scripts just for that purpose wouldn't you think? This way the normal animals would roam around the map behaving normally and the duplicate "predatory" animals could be used only for the special smart spawns. Didn't you make a random encounter system Vorspire? Could I use something like that to accomplish this? Or is that driven solely through your Vita-Nex:Core?
I don't think you need to have two separate scripts for the animals, you can just use the existing animals and modify them after spawn via code, in a similar way you would with [add and then [props

I don't have a random encounter system for an example, sorry.

Instead of spawners, I would probably code it into the way regions work.
Regions have a spawning api that's rarely used, perhaps that would be a good place to start?