void ExecuteQueue() { try{ bool ready=false; foreach(MudCharacter character in NonPlayersInRoom) { character.StartTurn(); } foreach(MudCharacter character in PlayersInRoom) { character.StartTurn(); } //give all characters a chance to put in an action while(!ready) { lock(lockobject){ foreach(MudCharacter character in PlayersInRoom) //test for an action from all characters { ready=false; foreach(CharacterAction action in ActionQueue) { if(action.Character==character) { ready=true; break; } } if(!ready) { break; } } if(DateTime.Now>time) //if time is up execute all actions in the queue { if(ActionQueue.Count==0&&PlayersInRoom.Count>0) { time=DateTime.Now.AddSeconds(timeoutSeconds); }else{ ready=true; } } } Thread.Sleep(100); } lock(lockobject) { while(ActionQueue.Count>0) { CharacterAction action=ActionQueue.Dequeue(); //skip actions by characters no longer in room(probably dead) if(action.Character is PlayerCharacter) { if(!PlayersInRoom.Contains(action.Character as PlayerCharacter)) { continue; } }else{ if(!NonPlayersInRoom.Contains(action.Character)) { continue; } } //skip actions on targets no longer in room if(action is TargetedAction) { TargetedAction ta=(action as TargetedAction); if(ta.Target is PlayerCharacter) { if(!PlayersInRoom.Contains(ta.Target as PlayerCharacter)) { continue; } }else{ if(!NonPlayersInRoom.Contains(ta.Target)) { continue; } } } string msg=action.DoAction(); NotifyPlayers(msg); //test for death //funky loops because the lists we're iterating might be changed foreach(MudCharacter c in GetCharactersInRoom()) { if(c.HitPoints<=0) { NotifyPlayers("\t{0} has died.",c.StatusString()); c.OnDeath(); RemoveCharacter(c); } } } foreach(MudCharacter c in GetCharactersInRoom()) { c.EndTurn(); if(c.HitPoints<=0) { NotifyPlayers("\t{0} has died.",c.StatusString()); c.OnDeath(); RemoveCharacter(c); } } Status=GenerateStatus(); } Thread.Sleep(100); lock(lockobject) { if(PlayersInRoom.Count==0){ ActionQueue.Clear(); ActionTask=null; time=DateTime.MinValue; }else{ time=DateTime.Now.AddSeconds(timeoutSeconds); ActionTask=Task.Factory.StartNew(new Action(ExecuteQueue)); } } }catch(Exception ex){ Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } }