Diego

Member
Hi,
I modded the OnEnemy function of a particular guard adding this:
Code:
if( m_CityStone.Check(1)  )
{
	((BaseGuardian)this).ForceMove( m, "jail");
        this.Say( "You're under arrest!" );
}
else if( m_CityStone.Check(2)  )
{
        ((BaseGuardian)this).ForceMove( m, m_CityStone.Town.ToString() );
        this.Say( "Stop!" );
}
else if( m_CityStone.Check(3) )
{
        this.Say( "Die!" );
}
return true;

and this is the ForceMove function:
Code:
public void ForceMove( Mobile from, string where )
{
	string name = where;
        Map map;

        for ( int i = 0; i < Map.AllMaps.Count; ++i )
        {
        	map = Map.AllMaps[i];

                if ( map.MapIndex == 0x7F || map.MapIndex == 0xFF )
                    continue;

                if ( Insensitive.Equals( name, map.Name ) )
                {
                	from.Map = map;
                	return;
                }
        }

        Dictionary<string, Region> list = from.Map.Regions;

        foreach( KeyValuePair<string, Region> kvp in list )
        {
        	Region r = kvp.Value;

                if ( Insensitive.Equals( r.Name, name ) )
                {
                	from.Location = new Point3D( r.GoLocation );
                    	return;
                }
        }

        for( int i = 0; i < Map.AllMaps.Count; ++i )
        {
        	Map m = Map.AllMaps[i];

                if( m.MapIndex == 0x7F || m.MapIndex == 0xFF || from.Map == m )
                    continue;

                foreach( Region r in m.Regions.Values )
                {
                	if( Insensitive.Equals( r.Name, name ) )
                    	{
                        	from.MoveToWorld( r.GoLocation, m );
	                        return;
                    	}
                }
        }
}

The problem is that when ForceMove() is executed the server crashes for this reason:

System.InvalidOperationException: Collection was modified: enumeration operation may not execute.
in System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
in System.Collections.Generic.List`1.Enumerator.MoveNextRare()
in System.Linq.Enumerable.WhereListIterator`1.MoveNext()
in System.Linq.Enumerable.<SelectManyIterator>d__16`2.MoveNext()
in Server.Mobiles.BaseAI.AcquireFocusMob(Int32 iRange, FightMode acqType, Boolean bPlayerOnly, Boolean bFacFriend, Boolean bFacFoe)
in Server.Mobiles.MageAI.DoActionWander()
in Server.Mobiles.BaseAI.AITimer.OnTick()
in Server.Timer.Slice() in C:\Users\Notebook\Documents\RunUO_Core\Server\Timer.cs:riga 387
in Server.Core.Main(String[] args) in C:\Users\Notebook\Documents\RunUO_Core\Server\Main.cs:riga 577
 
Last edited:
Yes, I overrided the OnEnemy function of a guard adding these new checks (if a player is an outlaw or he is exiled from a city the guards should send him automatically in jail or outside the city).
In the ForceMove function I copied the original code of the [go command.

If I comment the ForceMove part, guards say the speech without problems, but they kill the player.. if I de-comment that functions the server crashes.. maybe moving away the player from the guards during the onEnemy breaks any cycle? How/Where sould I put these checks?
 
Last edited:
Something somewhere is looping through a list, and modifying the list at the same time.

Code:
foreach (stuffs in thing)
{
	thing.add(X);
}

See those for reference:
http://stackoverflow.com/questions/1813557/listt-concurrent-removing-and-adding
http://stackoverflow.com/questions/37030628/concurrent-access-to-generic-list-property
http://stackoverflow.com/questions/9995266/how-to-create-a-thread-safe-generic-list
http://stackoverflow.com/questions/5874317/thread-safe-listt-property
http://igoro.com/archive/overview-of-concurrency-in-net-framework-35/
http://www.drdobbs.com/parallel/concurrent-programming-with-chain-lockin/240149442

Judging from the code sample you gave, i'm not sure what would cause that.
Perhaps debugging using breakpoints or spamming test messages would be an options.
 
I managed to do that putting the ForceMove function outside the foreach cycle.
During the foreach cycle all the mobiles in range are scanned to check if they are enemy or not.. if they are enemy they are stored in a variable.
After the end of the cycle, I run the ForceMove only for these stored mobiles.

Po0Ka has right, but I thought that a simply MoveTo would not break the list or the foreach.. I was wrong
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back