Пример #1
0
 internal static void AddTemple(Temple temple)
 {
     if (!_temples.ContainsKey(temple.Location))
     {
         _temples.Add(temple.Location, temple);
     }
 }
Пример #2
0
        public static Temple FindTemple(Point3 location)
        {
            // There should typically be one temple in any given area.
            double curDistance = -1;
            Temple curTemple   = null;

            foreach (var item in _temples)
            {
                double distance = Math.Sqrt(location.X - location.Y) + Math.Sqrt(item.Key.X - item.Key.Y);
                if (curDistance == -1)
                {
                    curDistance = distance;
                    curTemple   = item.Value;
                }

                if (distance < curDistance)
                {
                    curTemple = item.Value;
                    break;
                }
            }
            return(curTemple);
        }
Пример #3
0
        /// <summary>
        /// Causes the user to attack its current target with the current Item as the weapon. If the user's target is a mobile
        /// a counter attack check will occur and if successful the mobile will counter attack.
        /// </summary>
        /// <param name="weapon">The current item to use as a weapon.</param>
        /// <param name="user">The actor instance using the item as a weapon.</param>
        public static void Attack(this Item weapon, IActor user)
        {
            //if (user is IAvatar)
            //{
            //    if ((user as IAvatar).CombatMatch != Guid.Empty)
            //    {
            //        // Already engaged in combat, ignore the command.
            //    }
            //    else
            //    {
            //        // If the target is already engaged then join the match??
            //    }
            //}

            try
            {
                IAvatar avatar, target;
                IAvatar defender = null;
                IAvatar attacker = null;

                avatar = user as IAvatar;
                if (avatar != null)
                {
                    if (avatar.Target != null && avatar.Target is IAvatar)
                    {
                        target = avatar.Target as IAvatar;

                        // If the target is the user then exit.
                        if (avatar.ID == target.ID)
                        {
                            avatar.Context.Add(new RdlErrorMessage(Resources.CanNotAttackSelf));
                            return;
                        }

                        // Target must also have the avatar targeted or be set to null.
                        if (target.Target == null)
                        {
                            target.Target = avatar;
                        }
                        else if (target.Target.ID != avatar.ID)
                        {
                            avatar.Context.Add(new RdlErrorMessage(String.Format(Resources.TargetEngaged, target.TheUpper())));
                            return;
                        }

                        // Check for death and unconsioussness.
                        if (avatar.IsDead)
                        {
                            avatar.Context.Add(new RdlErrorMessage(Resources.PlayerDead));
                            return;
                        }
                        if (avatar.IsUnconscious)
                        {
                            avatar.Context.Add(new RdlErrorMessage(Resources.PlayerUnconscious));
                            return;
                        }

                        if (target.IsDead)
                        {
                            avatar.Context.Add(new RdlErrorMessage(Resources.TargetDead));
                            return;
                        }

                        // Can not attack certain mobiles, need to check for safe mobiles.
                        if (target is PerenthiaMobile && !(target as PerenthiaMobile).CanAttack)
                        {
                            avatar.Context.Add(new RdlErrorMessage(String.Format(Resources.ActionCanNotPerform, target.A())));
                            return;
                        }

                        // Can not attack a Character unless the IsPvpEnabled is set to true.
                        if (target is Character)
                        {
                            if (avatar is Character && !(target as Character).IsPvpEnabled)
                            {
                                avatar.Context.Add(new RdlErrorMessage(String.Format(Resources.ActionCanNotPerform, target.A())));
                                return;
                            }
                        }

                        // Increase the skill of the player using the item.
                        IPlayer currentPlayer = null;
                        string  skill         = null;
                        if (avatar is IPlayer)
                        {
                            currentPlayer = avatar as IPlayer;
                            skill         = weapon.GetOffensiveSkill();
                        }
                        else if (target is IPlayer)
                        {
                            currentPlayer = target as IPlayer;
                            skill         = target.GetDefensiveSkill();
                        }
                        if (weapon is Spell)
                        {
                            skill = weapon.Skill;
                        }
                        if (currentPlayer != null && !(weapon is Spell))
                        {
                            // NOTE: Skill advancement occuring in combat and magic manager classes.
                            // Advance the skill of the current player.
                            //SkillManager.AdvanceSkill(currentPlayer, skill, weapon.SkillLevelRequiredToEquip, currentPlayer.Context);
                        }

                        bool performCounterAttack = false;
                        if (weapon is Spell)
                        {
                            // CAST A SPELL
                            CastResults results = MagicManager.PerformCast((ISpell)weapon, avatar, target);
                            if (results.TargetDied)
                            {
                                attacker = avatar;
                                defender = target;
                            }
                            else
                            {
                                // If the target is a mobile then counter attack.
                                if (!avatar.IsDead && target is IMobile && !target.IsDead && !target.IsUnconscious)
                                {
                                    performCounterAttack = true;
                                }
                            }
                        }
                        else
                        {
                            // USE A WEAPON
                            if (CombatManager.PerformSimpleCombatTurn(
                                    avatar,
                                    (IWeapon)weapon,
                                    target,
                                    target.GetDefensiveSkill(),
                                    AttributeType.Dexterity,
                                    0))
                            {
                                // Killed defender.
                                attacker = avatar;
                                defender = target;
                            }
                            else
                            {
                                // DUAL WIELD
                                // If attacker has dual wield skill and an equipped second weapon then
                                // perform another attack.
                                IWeapon secondaryWeapon = avatar.GetSecondaryWeapon();
                                if (secondaryWeapon != null)
                                {
                                    if (CombatManager.PerformSimpleCombatTurn(
                                            avatar,
                                            secondaryWeapon,
                                            "Dual Wield",
                                            target,
                                            target.GetDefensiveSkill(),
                                            AttributeType.Dexterity,
                                            0))
                                    {
                                        // Killed defender.
                                        attacker = avatar;
                                        defender = target;
                                    }
                                    else
                                    {
                                        // Defender counter attack.
                                        // Only counter if a mobile.
                                        if (target is IMobile && !target.IsDead && !target.IsUnconscious)
                                        {
                                            performCounterAttack = true;
                                        }
                                    }
                                }
                                else
                                {
                                    // Defender counter attack.
                                    // Only counter if a mobile.
                                    if (target is IMobile && !target.IsDead && !target.IsUnconscious)
                                    {
                                        performCounterAttack = true;
                                    }
                                }
                            }
                        }

                        if (performCounterAttack)
                        {
                            if (!target.IsStunned && !target.IsFrozen && !avatar.IsDead)
                            {
                                // TODO: Have mobiles attack with spells??
                                // USE A WEAPON
                                if (CombatManager.PerformSimpleCombatTurn(
                                        target,
                                        target.GetWeapon(),
                                        avatar,
                                        avatar.GetDefensiveSkill(),
                                        AttributeType.Dexterity,
                                        0))
                                {
                                    // Killed attacker.
                                    attacker = target;
                                    defender = avatar;
                                }

                                // Update the mobile's last attack time.
                                (target as PerenthiaMobile).LastAttackTime = DateTime.Now;
                            }
                        }

                        // Send down stats for both attacker and defender.
                        var attackerProps = avatar.GetRdlProperties(Avatar.BodyProperty, Avatar.MindProperty);
                        var defenderProps = target.GetRdlProperties(Avatar.BodyProperty, Avatar.MindProperty);
                        avatar.Context.AddRange(attackerProps);
                        avatar.Context.AddRange(defenderProps);
                        target.Context.AddRange(attackerProps);
                        target.Context.AddRange(defenderProps);

                        if (defender != null && attacker != null)
                        {
                            if (attacker is IPlayer)
                            {
                                //=========================================================================================
                                // PLAYER KILLED MOBILE
                                //=========================================================================================
                                // The mobile dies, cause it to respawn at a later date.
                                PerenthiaMobile mob = defender as PerenthiaMobile;
                                if (mob != null)
                                {
                                    // Mobile is a clone but is stored as an instance on the mobile object.
                                    DateTime killTime = DateTime.Now;
                                    mob.RespawnTime = killTime.Add(mob.RespawnDelay);
                                    mob.KilledBy.AddKilledBy(attacker.ID, killTime);
                                }
                                attacker.Context.AddRange(defender.ToSimpleRdl());

                                // Since the player killed the mobile, give them some experience.
                                Character player = attacker as Character;
                                if (player != null && mob != null)
                                {
                                    int xp = LevelManager.GetXpForMobileKill(player.Level, mob.Level);
                                    if (xp > 0)
                                    {
                                        player.Experience      += xp;
                                        player.TotalExperience += xp;
                                        player.Context.Add(new RdlSystemMessage(RdlSystemMessage.PriorityType.Positive,
                                                                                String.Format(Resources.ExperienceGained, xp)));
                                    }

                                    // Raise an event indicating that the player has killed something.
                                    player.World.OnAvatarKilledAvatar(player, mob);

                                    // Raise an internal event on the player instance for quests and awards.
                                    player.OnKilledActor(mob);

                                    // Cause the player to advance if the required experience requirements are met.
                                    LevelManager.AdvanceIfAble(player);

                                    // Mobiles should drop random items, mostly items related to crafting.
                                    mob.GenerateRandomDropItems();

                                    // Send down changed properties.
                                    player.Context.AddRange(player.GetRdlProperties(
                                                                Character.ExperienceProperty,
                                                                Character.ExperienceMaxProperty,
                                                                Character.CurrencyProperty));

                                    // Save the player instance.
                                    player.Save();
                                }
                            }
                            else if (defender is IPlayer)
                            {
                                //=========================================================================================
                                // MOBILE KILLED PLAYER
                                //=========================================================================================
                                // A player died, dock some experience.
                                // Only loose experience after level 5.
                                Character player = defender as Character;
                                if (player != null && player.Experience > 0 && player.Level > 5)
                                {
                                    int penaltyXp = player.Level * 50 + (Dice.Roll(player.Level, 10));
                                    if (penaltyXp > player.Experience)
                                    {
                                        penaltyXp = player.Experience - 2;
                                    }
                                    player.Experience      -= penaltyXp;
                                    player.TotalExperience -= penaltyXp;
                                    player.Context.Add(new RdlSystemMessage(RdlSystemMessage.PriorityType.Negative,
                                                                            String.Format(Resources.ExperienceLost, penaltyXp)));

                                    // Send down changed properties.
                                    player.Context.AddRange(player.GetRdlProperties(
                                                                Character.ExperienceProperty,
                                                                Character.ExperienceMaxProperty));
                                }

                                // Raise an event on the player for quests and awards.
                                if (defender != null)
                                {
                                    player.OnDied(defender);
                                }

                                if (attacker != null && defender != null)
                                {
                                    // Raise an event indicating that the defender has killed the attacker.
                                    defender.World.OnAvatarKilledAvatar(attacker, defender);
                                }

                                // Find the nearest temple and resurrect the player there.
                                Temple temple = Game.FindTemple(defender.Location);
                                if (temple != null)
                                {
                                    temple.Resurrect(defender);
                                }
                                else
                                {
                                    // Otherwise, spaw a temple right above the player's starting location and send them there.
                                    Race   race      = defender.World.Races[defender.Race];
                                    Temple newTemple = new Temple()
                                    {
                                        Location = new Point3(race.StartingLocation.X, race.StartingLocation.Y, race.StartingLocation.Z + 1),
                                        Name     = "Temple",
                                        World    = defender.World,
                                        Terrain  = defender.World.Terrain[1].ID,
                                    };
                                    newTemple.Exits.SetValue(KnownDirection.Down, true);
                                    defender.World.Places.Add(newTemple.Location, newTemple);
                                    Game.AddTemple(newTemple);
                                }

                                // Save the player instance.
                                defender.Save();
                            }
                            // Do not reset targets after combat as the target might be clone of a mob and will need
                            // to remain set for proper looting.
                            // Reset targets.
                            //attacker.Target = null;
                            //defender.Target = null;
                            //attacker.Context.AddRange(attacker.GetRdlProperties(Avatar.TargetIDProperty));
                            //defender.Context.AddRange(defender.GetRdlProperties(Avatar.TargetIDProperty));
                        }
                    }
                    else
                    {
                        avatar.Context.Add(new RdlErrorMessage(String.Format("You must have a target selected to use {0}.", weapon.The())));
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }