internal static void AddTemple(Temple temple) { if (!_temples.ContainsKey(temple.Location)) { _temples.Add(temple.Location, temple); } }
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); }
/// <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; } }