Beispiel #1
0
        public CombatRound Hit(Player player)
        {
            var round = new CombatRound();

            // roll to hit, if success, then hit
            if (Server.Current.Random.Next(HitRoll) + 1 >= player.Armor)
            {
                // hit
                var damage = Server.Current.Random.Next(DamRoll) + 1;
                player.HitPoints -= damage;

                var damageAction = CombatHelper.GetDamageAction(player, damage);

                var playerText = string.Format("{0} {1} you for {2} damage!\n", Name, damageAction.Plural, damage);
                round.AddText(player, playerText, CombatTextType.Player);

                var groupText = string.Format("{0} {1} {2}!\n", Name, damageAction.Plural, player.Forename);
                round.AddText(player, groupText, CombatTextType.Group);
            }
            else
            {
                // miss
                var playerText = string.Format("{0} misses you!", Name);
                round.AddText(player, playerText, CombatTextType.Player);

                var groupText = string.Format("{0} misses {1}!\n", Name, player.Forename);
                round.AddText(player, groupText, CombatTextType.Group);
            }

            if (!_skillLoopStarted && Skills.Count > 0)
            {
                doSkillLoop(null, null);
            }

            return(round);
        }
Beispiel #2
0
        public override void Execute(Session session, CommandContext context)
        {
            if (string.IsNullOrEmpty(context.ArgumentString))
            {
                session.WriteLine("{0} what?", context.CommandName);
                return;
            }

            var arg1 = context.ArgumentString.ToLower();

            // command lookup, should never be null or command lookup will handle
            // level check should already be done by command lookup
            var skill = Server.Current.Database.Get <CombatSkill>(realCommandName);

            // skill check i.e. does player have it?
            if (!session.Player.Skills.ContainsKey(skill.Key))
            {
                session.WriteLine("You haven't practiced that yet.");
                return;
            }

            // status check, start combat if not already there
            if (session.Player.Status != GameStatus.Fighting && session.Player.Status != GameStatus.Standing)
            {
                session.WriteLine("You can't do that right now.");
                return;
            }

            // target check
            var room   = RoomHelper.GetRoom(session.Player.Location);
            var target = room.GetNpcs().FirstOrDefault(n => n.Keywords.Contains(arg1));

            if (target == null)
            {
                session.WriteLine("You can't find that here.");
                return;
            }

            // combat check
            var fight = Server.Current.CombatHandler.FindFight(session.Player);

            if (fight == null)
            {
                // start fight, since npc is found
                fight = new Game.Combat();
                fight.AddFighter(session.Player);
                fight.AddMob(target);
                Server.Current.CombatHandler.StartFight(fight);
            }

            // do it
            if (Server.Current.Random.NextDouble() < session.Player.Skills[skill.Key])
            {
                // get damage
                var damage = Server.Current.Random.Next(skill.MinDamage, skill.MaxDamage + 1);
                // hit
                target.HitPoints -= damage;

                // increase skill effectiveness
                if (session.Player.Skills[skill.Key] < skill.MaxEffectiveness)
                {
                    session.Player.Skills[skill.Key] += skill.HitEffectivenessIncrease + target.HitPoints <= 0
                                                            ? skill.KillingBlowEffectivenessIncrease
                                                            : 0;
                }

                var damageAction = CombatHelper.GetDamageAction(target, damage);

                // message
                session.WriteLine("Your {0} {1} {2} for {3} damage!", realCommandName, damageAction.Plural, target.Name, damage);
                // room message
                room.SendPlayers(
                    string.Format("{0}{1} {2} {3} {4}!", session.Player.Forename,
                                  session.Player.Forename.ToLower().EndsWith("s") ? "'" : "s", skill.Key, damageAction.Plural, target.Name),
                    session.Player,
                    null,
                    session.Player);

                // dead check
                // this feels hacky since it sort of duplicates some of the work of Combat.DoPlayerHits()
                if (target.HitPoints <= 0)
                {
                    fight.RemoveFromCombat(target);
                    target.Die();
                    var deadText = string.Format("`R{0} is DEAD!!!", target.Name);
                    session.WriteLine(deadText);
                    room.SendPlayers(deadText, session.Player, null, session.Player);
                }
            }
            else
            {
                // message
                session.WriteLine("Your {0} misses {1}!", realCommandName, target.Name);
                // room message
                room.SendPlayers(string.Format("{0}{1} {2} misses {3}!", session.Player.Forename,
                                               session.Player.Forename.ToLower().EndsWith("s") ? "'" : "s", skill.Key,
                                               target.Name),
                                 session.Player, null,
                                 session.Player);
                // increase skill effectiveness by less
                session.Player.Skills[skill.Key] += skill.MissEffectivenessIncrease;
            }
        }
Beispiel #3
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();
            }
        }