Пример #1
0
        protected void Walk()
        {
            if ((DateTime.Now - _lastTimeWalked).TotalMilliseconds <= Server.MobWalkInterval)
            {
                return;
            }

            _lastTimeWalked = DateTime.Now;

            var room = RoomHelper.GetPlayerRoom(Location);

            // get allowed exits
            var allowedExits = room.Exits.Where(e => AllowedRooms.Contains(e.Value.LeadsTo) && e.Value.IsOpen).ToList();

            if (allowedExits.Any() && Server.Current.Random.NextDouble() < 0.5)
            {
                var exit = allowedExits.Skip(Server.Current.Random.Next(allowedExits.Count())).FirstOrDefault();

                room.RemoveNpc(this);
                var newRoom = RoomHelper.GetPlayerRoom(exit.Value.LeadsTo);
                newRoom.AddNpc(this);
                Location = newRoom.Key;
                room.SendPlayers(string.Format("{0} heads {1}.", Name, DirectionHelper.GetDirectionWord(exit.Key)),
                                 null, null, null);
                newRoom.SendPlayers(
                    string.Format("{0} arrives from the {1}.", Name, DirectionHelper.GetOppositeDirection(exit.Key)),
                    null, null, null);
            }
        }
Пример #2
0
        protected void Talk()
        {
            if ((DateTime.Now - _lastTimeTalked).TotalMilliseconds <= MinimumTalkInterval)
            {
                return;
            }

            // set the new interval
            _lastTimeTalked = DateTime.Now;

            // talk at random
            double prob = Server.Current.Random.NextDouble();

            if (prob < TalkProbability && Phrases != null && Phrases.Length > 0)
            {
                var phrase = Phrases[Server.Current.Random.Next(Phrases.Length)];

                // say it to the room
                var room = RoomHelper.GetPlayerRoom(Location);
                if (room != null)
                {
                    string message = string.Format("{0} says, \"{1}\"", Name, phrase);
                    room.SendPlayers(message, null, null, null);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// initially, spawn all mobs
        /// </summary>
        private void mudBoot()
        {
            // get all MobTemplates
            foreach (var mob in Server.Current.Database.GetAll <MobTemplate>())
            {
                // copy into NonPlayer, mapping generates inventory and equipped
                foreach (var location in mob.RespawnRoom)
                {
                    var npc = Mapper.Map <NonPlayer>(mob);
                    npc.Location = location;

                    // get room, put in room
                    RoomHelper.GetPlayerRoom(location).AddNpc(npc);
                    Server.Current.Database.Save(npc);
                }
            }

            foreach (var area in Server.Current.Areas)
            {
                area.LastRepop = DateTime.Now;
                foreach (var roomKey in area.Rooms)
                {
                    var room = Server.Current.Database.Get <Room>(roomKey);
                    room.RepopItems();
                }
            }
        }
Пример #4
0
        private void doSkillLoop(object sender, ElapsedEventArgs e)
        {
            _skillLoopStarted = true;
            _skillReady       = true;

            if (HitPoints > 0) // don't try to hit if dead
            {
                // get random skill and delay
                var keys     = new List <string>(Skills.Keys);
                var size     = Skills.Count;
                var skillKey = keys[Server.Current.Random.Next(size)];
                var skill    = Server.Current.CombatSkills.FirstOrDefault(s => s.Key == skillKey);
                var command  = Server.Current.CommandLookup.FindCommand(skillKey, true);

                if (skill == null || command == null)
                {
                    Server.Current.Log(string.Format("Can't find NPC skill: {0}", skillKey));
                    return;
                }

                var frequency     = Skills[skillKey].Item1;
                var effectiveness = Skills[skillKey].Item2;
                // if frequency check hits
                if (Server.Current.Random.NextDouble() < frequency)
                {
                    // find the fight
                    var fight = Server.Current.CombatHandler.FindFight(this);

                    if (fight == null)
                    {
                        return;
                    }

                    // get random player to hit
                    var playerToHit = fight.GetFighters().OrderBy(x => Guid.NewGuid()).FirstOrDefault();

                    if (playerToHit == null)
                    {
                        return;
                    }

                    // get room
                    var room = RoomHelper.GetPlayerRoom(playerToHit.Location);

                    // if effectiveness hits
                    if (Server.Current.Random.NextDouble() < effectiveness)
                    {
                        // do skill hit
                        var damage       = Server.Current.Random.Next(skill.MinDamage, skill.MaxDamage + 1);
                        var damageAction = CombatHelper.GetDamageAction(playerToHit, damage);

                        // message
                        playerToHit.Send(string.Format("{0}{1} {2} {3} you for {4} damage!", Name, Name.EndsWith("s") ? "'" : "'s", skillKey.ToLower(), damageAction.Plural, damage), null);
                        playerToHit.HitPoints -= damage;

                        room.SendPlayers(
                            string.Format("{0}{1} {2} {3} {4}",
                                          Name, Name.EndsWith("s") ? "'" : "'s", skillKey.ToLower(), damageAction.Plural, playerToHit.Forename),
                            playerToHit, null, playerToHit);


                        // check if player dead
                        if (playerToHit.HitPoints <= 0)
                        {
                            // almost identical code used in combat handler when mob kills player in normal combat
                            playerToHit.Die(); // changes status

                            var statusText = Player.GetStatusText(playerToHit.Status).ToUpper();

                            var playerText = string.Format("You are {0}!!!", statusText);
                            if (playerToHit.HitPoints < Server.DeadHitPoints)
                            {
                                playerText += " You have respawned, but you're in a different location.\n" +
                                              "Your corpse will remain for a short while, but you'll want to retrieve your\n" +
                                              "items in short order.";

                                playerToHit.DieForReal();
                            }

                            var groupText = string.Format("{0} is {1}!!!", playerToHit.Forename, statusText);

                            playerToHit.Send(playerText, null);
                            room.SendPlayers(groupText, playerToHit, null, playerToHit);

                            fight.RemoveFromCombat(playerToHit);

                            if (!fight.GetFighters().Any())
                            {
                                fight.End();
                                return; // so timer doesn't start again
                            }
                        }
                    }
                    else
                    {
                        // miss message
                        playerToHit.Send(string.Format("{0}{1} {2} misses you!", Name, Name.EndsWith("s") ? "'" : "'s", skillKey.ToLower()), null);
                        room.SendPlayers(
                            string.Format("{0}{1} {2} misses {3}", Name, skillKey.EndsWith("s") ? "'" : "'s",
                                          skillKey.ToLower(),
                                          playerToHit.Forename), playerToHit, null,
                            playerToHit);
                    }
                }

                _skillReady = false;

                // set delay and call this method again
                var t = new Timer()
                {
                    AutoReset = false,
                    Interval  = (long)command.TickLength,
                };

                t.Elapsed += doSkillLoop;
                t.Start();
            }
        }
Пример #5
0
        public CombatRound Die(bool shutdown = false)
        {
            var round = new CombatRound();

            if (!shutdown)
            {
                // create a corpse item with .ContainsItems equal to whatever was held/equipped
                var corpseTemplate = Server.Current.Database.Get <Template>("corpse");
                var dupedCorpse    = Mapper.Map <PlayerItem>(corpseTemplate);
                foreach (var item in Inventory
                         .Select(i => new KeyValuePair <string, string>(i.Key, i.Value))
                         .Union(Equipped.Values.Select(e => new KeyValuePair <string, string>(e.Key, e.Name))))
                {
                    var corpseItem = Server.Current.Database.Get <PlayerItem>(item.Key);
                    dupedCorpse.ContainedItems[corpseItem.Key] = corpseItem.Name;
                }

                dupedCorpse.Name        = string.Format("The corpse of {0}", Name);
                dupedCorpse.Description = string.Format("The corpse of {0}", Name.ToLower());
                dupedCorpse.Keywords    = new List <string>()
                {
                    "corpse", Name
                }.ToArray();
                dupedCorpse.WearLocation = Wearlocation.Corpse;
                dupedCorpse.Gold         = getRandomGold(Gold);

                // put corpse in room
                var room = RoomHelper.GetPlayerRoom(Location);
                room.AddItem(dupedCorpse);
                Console.WriteLine("NEW CORPSE: {0}", dupedCorpse.Key);
                room.CorpseQueue[dupedCorpse.Key] = DateTime.Now.AddMilliseconds(Server.CorpseDecayTime);

                // must cache since we're not saving
                Server.Current.Database.Put(dupedCorpse);

                // delete mob
                room.RemoveNpc(this);
                Server.Current.Database.Delete <NonPlayer>(Key);

                round.AddText(null, string.Format("`R{0} is DEAD!!!", Name), CombatTextType.Room);

                // get area from this.RespawnRoom
                var area = Server.Current.Areas.FirstOrDefault(a => a.Key == room.Area);

                // add to .RepopQueue
                area.RepopQueue.Add(MobTemplateKey);
            }
            else
            {
                // delete inventory/equipped items' .db files
                foreach (var key in Inventory.Keys.Union(Equipped.Values.Select(e => e.Key)))
                {
                    ItemHelper.DeleteItem(key);
                }
            }

            // delete .db file
            Server.Current.Database.Delete <NonPlayer>(Key);

            return(round);
        }
Пример #6
0
        private void DoRepop(object sender, ElapsedEventArgs e)
        {
            _timer.Stop();

            foreach (var area in Server.Current.Areas)
            {
                if ((DateTime.Now - area.LastRepop).TotalMilliseconds > area.RepopTime)
                {
                    try
                    {
                        // broadcast repop message to players in area
                        foreach (var roomKey in area.Rooms)
                        {
                            var room = RoomHelper.GetPlayerRoom(roomKey);
                            room.RepopItems();
                            foreach (var player in room.GetPlayers())
                            {
                                player.Send(area.RepopMessage, null);
                            }
                        }


                        foreach (var key in area.RepopQueue.ToArray())
                        {
                            var mob       = Server.Current.Database.Get <MobTemplate>(key);
                            var npc       = Mapper.Map <NonPlayer>(mob);
                            var repopRoom = npc.GetRespawnRoom();
                            npc.Location = repopRoom;
                            RoomHelper.GetPlayerRoom(repopRoom).AddNpc(npc);
                            area.RepopQueue.Remove(key);
                        }

                        area.LastRepop = DateTime.Now;
                    }
                    catch (Exception ex)
                    {
                        var log = string.Format("Respawn Error: {0}", ex.StackTrace);
                        Console.WriteLine(log);
                        Server.Current.Log(LogType.Error, log);
                    }
                }

                // handle corpses
                foreach (var key in area.Rooms)
                {
                    var room = Server.Current.Database.Get <Room>(key);
                    foreach (var corpse in room.CorpseQueue.Where(k => k.Value < DateTime.Now).ToArray())
                    {
                        var corpseItem = Server.Current.Database.Get <PlayerItem>(corpse.Key);

                        room.SendPlayers(string.Format("{0} withers and blows away...", corpseItem.Name), null, null, null);

                        room.CorpseQueue.Remove(corpse.Key);
                        room.Items.Remove(corpse.Key);

                        // delete corpse and all items in it
                        ItemHelper.DeleteItem(corpseItem.Key);
                    }
                }
            }

            // fixme: this is going to get dead/old npc's as well
            foreach (var npc in Server.Current.Database.GetAll <NonPlayer>())
            {
                npc.TalkOrWalk();
            }

            _timer.Start();
        }