Quantcast
Channel: Question and Answer » programming
Viewing all articles
Browse latest Browse all 103

Subscriber with many publishers: unsubscribing

$
0
0

I hope this isn’t too general, so I apologize in advance if so. I am creating a console text adventure game. I essentially have many monsters, one per room at the moment. I also have a God object/class, which in essence watches these monsters to see if they die. I have a static eventhandler (“HealthEventHandler”) in the monster class, which I use to add methods to the event. When a monsters dead flag goes to true, a monster method gets called which adds a God to watch this monster (IsWatching list). When the monster dies, DeathCheck is fired once the dead flag gets flipped to true. The instance of OnDeath should be removed from the event(?) handler, as a monster should only ever be sacrificed once (DeathCheck -= this.OnDeath;). Is this the proper way to unsubscribe in a situation like this? I apologize for the poor explanation here as well, which is why I’ve included what should be all relevant code to help you understand what I’m doing better.

The potential issues I’m having is that sometimes the events appear to fire twice. For example, I kill one monster, the God accepts the sacrifice, I then proceed to kill another monster, and the God accepts both the new sacrifice and the monster that should have already been sacrificed. I’m apparently missing something important here, or just going down the wrong path. Any guidance here would be greatly appreciated on how I can implement this event system. I’m just looking for when a monster dies, a God will accept the sacrifice and reward the player with some gold.

Monster Class:

public class monster
    {

        public static player _player;
        private delegate void HealthEventHandler(player _player);
        private static HealthEventHandler DeathCheck; 
        private List<God> IsWatching = new List<God>();

        public bool sacrificed = false; 
        public bool _dead;
        public bool dead
        {
            get { return _dead; }
            set
            {
                if (DeathCheck != null)
                {
                    if (value == true)
                    {
                        _dead = true;

                        if (this.sacrificed == false)
                        {

                            DeathCheck.Invoke(monster._player);
                            DeathCheck -= this.OnDeath;

                        }
                    }

                    else
                    {
                        _dead = value;
                    }
                }
                else                 
                {
                    _dead = value;

                }


            }
        }

        public monster(int _level, string _name)
            {
                DeathCheck += new HealthEventHandler(this.OnDeath);
                level = _level;
                name = _name; 

            }


        public void DeathWatch(God _god)
        {
            IsWatching.Add(_god);
        } 



        public void OnDeath(player _player)
        {

            foreach (God g in IsWatching)
            {
                g.TakeSoul(this, _player);
            }

            this.sacrificed = true;

        }
    }

God Class:

public class God
        {   
            public string name;
            public int soulCount;
            public ConsoleColor color = ConsoleColor.White;


         public God(string _name, string _color)
         {

             name = _name;
             soulCount = 0; 

             if (_color == "blue" || _color == "Blue")
             {
                 color = ConsoleColor.Blue;
             }

             else if (_color == "red" || _color == "Red")
             {
                 color = ConsoleColor.Red;
             }

             else if (_color == "yellow" || _color == "Yellow")
             {
                 color = ConsoleColor.Yellow;
             } 

         }


         public void TakeSoul(monster _monster, player _player)
         {
             System.Threading.Thread.Sleep(200);
             Console.WriteLine("n {0} contemplates whether to accept your offer...n ", this.name);
             System.Threading.Thread.Sleep(600);
             Console.Write("n {0} decides to accept the soul of {1}!", this.name, _monster.name);
             Console.WriteLine(" + {0} gp.n", (_monster.level * 123));
             _player.gp += _monster.level * 123; 

         }

        }

Viewing all articles
Browse latest Browse all 103

Trending Articles