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); } }
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); } } }
/// <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(); } } }
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(); } }
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); }
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(); }