public static void SetTarget(this IAvatar avatar, IAvatar target) { // If the target's target is not null then check to see if the target's target is in the current // place, if not release the target. // Will not need to do this because mobiles are cloned. //IAvatar targetTarget = target.Target as IAvatar; //if (targetTarget != null) //{ // if (targetTarget.Location != target.Location) // { // target.Target = null; // } //} avatar.Target = target; if (target != null) { target.Target = avatar; // Send notification to avatar. avatar.Context.AddRange(avatar.GetRdlProperties(Avatar.TargetIDProperty)); avatar.Context.AddRange(target.ToSimpleRdl()); avatar.Context.Add(new RdlSystemMessage(RdlSystemMessage.PriorityType.None, String.Format(Resources.TargetSet, target.A()))); // Send notification to target target.Context.AddRange(target.GetRdlProperties(Avatar.TargetIDProperty)); target.Context.AddRange(avatar.ToSimpleRdl()); // Do not send a message to the target, not really needed. //target.Context.Add(new RdlSystemMessage(RdlSystemMessage.PriorityType.None, // String.Format(Resources.TargetSet, avatar.A()))); } }
/// <summary> /// Sends the specified message to all avatars in the current place. /// </summary> /// <param name="tag">The RdlTag to send to all avatars in the place.</param> /// <param name="sender">The avatar sending the message.</param> public void SendAll(RdlTag tag, IAvatar sender) { var avatars = (from c in this.Children where c is Avatar select c as Avatar); RdlObject[] senderRdl = sender.ToSimpleRdl(); foreach (var avatar in avatars) { if (avatar.ID != sender.ID) { avatar.Context.Add(tag); } } }
/// <summary> /// Exits the Avatar from a previous Place and enters the current place. Sends notification to other avatars in the Place. /// </summary> /// <param name="who">The Avatar entering the room.</param> /// <param name="direction">The direction from which the avatar is entering.</param> public void Enter(IAvatar who, Direction direction) { if (who.Place != null) { who.Place.Exit(who, direction.CounterDirection); } who.Place = this; this.Children.Add(who); // Clear the target of the current avatar and the avatar's target's target. if (who.Target != null) { IAvatar target = who.Target as IAvatar; if (target != null) { target.Target = null; target.Context.AddRange(target.GetRdlProperties(Avatar.TargetIDProperty)); } who.Target = null; who.Context.AddRange(who.GetRdlProperties(Avatar.TargetIDProperty)); } // Send down the new x,y,z of the current avatar. who.Context.AddRange(who.GetRdlProperties(Avatar.XProperty, Avatar.YProperty, Avatar.ZProperty)); // Raise the OnEnter event on the current place. if (!who.IsBuilder) { this.OnEnter(who, who.Context, direction); if (who is IPlayer) { (who as IPlayer).OnPlaceEntered(); } // Raise an event on all avatar instances in the current place that a new avatar has entered. var avatars = (from c in this.Children where c is IAvatar select c as IAvatar); var whoRdl = who.ToSimpleRdl(); foreach (var avatar in avatars) { if (avatar.ID != who.ID) { avatar.OnEnter(who, who.Context, direction); } } } // Cause the newly entered avatar to look at the place. this.Look(who); }
/// <summary> /// Sends the specified Message to all connected clients. /// </summary> /// <param name="tag">The Tag to send to all connected clients.</param> public void SendAll(RdlTag tag, IAvatar sender) { RdlObject[] senderRdl = sender.ToSimpleRdl(); for (int i = this.Clients.Count - 1; i >= 0; i--) { var client = this.Clients[i]; if (client.Player != null) { if (sender != null && sender.ID == client.Player.ID) { client.Context.Add(tag); } } } }
public override void OnExit(IActor sender, IMessageContext context, Direction direction) { IAvatar avatar = sender as IAvatar; if (avatar != null) { //this.SendAll(new RdlSystemMessage(RdlSystemMessage.PriorityType.None, // String.Format(Resources.PlaceAvatarExits, avatar.FirstName, direction.Name)), // avatar); var avatars = (from c in this.Children where c is IAvatar select c as IAvatar); var whoRdl = avatar.ToSimpleRdl(); foreach (var a in avatars) { if (a.ID != avatar.ID) { // Send down a command to remove this avatar from the the current room. a.Context.Add(new RdlCommand("AVATARREMOVE", avatar.ID)); } } } }
/// <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; } }