/// <summary> /// Apply effect on target or do spell action if non duration spell /// </summary> /// <param name="target">target that gets the effect</param> /// <param name="effectiveness">factor from 0..1 (0%-100%)</param> public override void ApplyEffectOnTarget(GameLiving target, double effectiveness) { if (target == null || target.CurrentRegion == null) { return; } if (target.Realm == 0 || Caster.Realm == 0) { target.LastAttackedByEnemyTickPvE = target.CurrentRegion.Time; Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; } else { target.LastAttackedByEnemyTickPvP = target.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; } base.ApplyEffectOnTarget(target, effectiveness); if (Spell.CastTime > 0) { target.StartInterruptTimer(target.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster); } if (target is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } }
/// <summary> /// Saves a merchant into the DB /// </summary> public override void SaveIntoDatabase() { Mob merchant = null; if (InternalID != null) { merchant = GameServer.Database.FindObjectByKey <Mob>(InternalID); } if (merchant == null) { merchant = new Mob(); } merchant.Name = Name; merchant.Guild = GuildName; merchant.X = X; merchant.Y = Y; merchant.Z = Z; merchant.Heading = Heading; merchant.Speed = MaxSpeedBase; merchant.Region = CurrentRegionID; merchant.Realm = (byte)Realm; merchant.RoamingRange = RoamingRange; merchant.Model = Model; merchant.Size = Size; merchant.Level = Level; merchant.Gender = (byte)Gender; merchant.Flags = (uint)Flags; merchant.PathID = PathID; merchant.PackageID = PackageID; merchant.OwnerID = OwnerID; IOldAggressiveBrain aggroBrain = Brain as IOldAggressiveBrain; if (aggroBrain != null) { merchant.AggroLevel = aggroBrain.AggroLevel; merchant.AggroRange = aggroBrain.AggroRange; } merchant.ClassType = this.GetType().ToString(); merchant.EquipmentTemplateID = EquipmentTemplateID; if (m_tradeItems == null) { merchant.ItemsListTemplateID = null; } else { merchant.ItemsListTemplateID = m_tradeItems.ItemsListID; } if (InternalID == null) { GameServer.Database.AddObject(merchant); InternalID = merchant.ObjectId; } else { GameServer.Database.SaveObject(merchant); } }
protected static void CheckNearFairyDragonflyHandler(DOLEvent e, object sender, EventArgs args) { GameNPC fairyDragonflyHandler = (GameNPC)sender; // if princess is dead no ned to checks ... if (!fairyDragonflyHandler.IsAlive || fairyDragonflyHandler.ObjectState != GameObject.eObjectState.Active) { return; } foreach (GamePlayer player in fairyDragonflyHandler.GetPlayersInRadius(1500)) { IreFairyIre quest = (IreFairyIre)player.IsDoingQuest(typeof(IreFairyIre)); if (quest != null && !quest.fairyDragonflyHandlerAttackStarted && quest.Step == 3) { quest.fairyDragonflyHandlerAttackStarted = true; SendSystemMessage(player, "Fairy Dragonfly Handler says, \"No! I have been betrayed by loathsome insects! How can this be?\""); IOldAggressiveBrain aggroBrain = fairyDragonflyHandler.Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(player, 70); } // if we find player doing quest stop looking for further ones ... break; } } }
public override int OnEffectExpires(GameSpellEffect effect, bool noMessages) { effect.Owner.IsStunned = false; effect.Owner.DisableTurning(false); if (effect.Owner == null) { return(0); } GamePlayer player = effect.Owner as GamePlayer; if (player != null) { player.Client.Out.SendUpdateMaxSpeed(); if (player.Group != null) { player.Group.UpdateMember(player, false, false); } } else { GameNPC npc = effect.Owner as GameNPC; if (npc != null) { IOldAggressiveBrain aggroBrain = npc.Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } } return(0); }
protected static void CheckNearAskefruerTrainer(DOLEvent e, object sender, EventArgs args) { GameNPC m_askefruerTrainer = (GameNPC)sender; // if princess is dead no ned to checks ... if (!m_askefruerTrainer.IsAlive || m_askefruerTrainer.ObjectState != GameObject.eObjectState.Active) { return; } foreach (GamePlayer player in m_askefruerTrainer.GetPlayersInRadius(1500)) { StolenEggs quest = (StolenEggs)player.IsDoingQuest(typeof(StolenEggs)); if (quest != null && !quest.askefruerGriffinHandlerAttackStarted && (quest.Step == 2 || quest.Step == 3)) { quest.askefruerGriffinHandlerAttackStarted = true; IOldAggressiveBrain aggroBrain = m_askefruerTrainer.Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(player, 70); } quest.Step = 3; // if we find player doing quest stop looking for further ones ... break; } } }
/// <summary> /// When an applied effect starts /// duration spells only /// </summary> /// <param name="effect"></param> public override void OnEffectStart(GameSpellEffect effect) { base.OnEffectStart(effect); if (effect.Owner.Realm == 0 || Caster.Realm == 0) { effect.Owner.LastAttackedByEnemyTickPvE = effect.Owner.CurrentRegion.Time; Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; } else { effect.Owner.LastAttackedByEnemyTickPvP = effect.Owner.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; } effect.Owner.DisarmedTime = effect.Owner.CurrentRegion.Time + CalculateEffectDuration(effect.Owner, Caster.Effectiveness); effect.Owner.StopAttack(); MessageToLiving(effect.Owner, Spell.Message1, eChatType.CT_Spell); Message.SystemToArea(effect.Owner, Util.MakeSentence(Spell.Message2, effect.Owner.GetName(0, false)), eChatType.CT_Spell, effect.Owner); effect.Owner.StartInterruptTimer(effect.Owner.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster); if (effect.Owner is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)effect.Owner).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } }
protected virtual void OnSpellResist(GameLiving target) { m_lastdamage -= m_lastdamage / 4; SendEffectAnimation(target, 0, false, 0); if (target is GameNPC) { IControlledBrain brain = ((GameNPC)target).Brain as IControlledBrain; if (brain != null) { GamePlayer owner = brain.GetPlayerOwner(); //Worthless checks if (owner != null /* && owner.ControlledNpc != null && target == owner.ControlledNpc.Body*/) { MessageToLiving(owner, "Your " + target.Name + " resists the effect!", eChatType.CT_SpellResisted); } } } else { MessageToLiving(target, "You resist the effect!", eChatType.CT_SpellResisted); } MessageToCaster(target.GetName(0, true) + " resists the effect!", eChatType.CT_SpellResisted); if (Spell.Damage != 0) { // notify target about missed attack for spells with damage AttackData ad = new AttackData(); ad.Attacker = Caster; ad.Target = target; ad.AttackType = AttackData.eAttackType.Spell; ad.AttackResult = GameLiving.eAttackResult.Missed; ad.SpellHandler = this; target.OnAttackedByEnemy(ad); target.StartInterruptTimer(target.SpellInterruptDuration, ad.AttackType, Caster); } else if (Spell.CastTime > 0) { target.StartInterruptTimer(target.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster); } if (target is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } if (target.Realm == 0 || Caster.Realm == 0) { target.LastAttackedByEnemyTickPvE = target.CurrentRegion.Time; Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; } else { target.LastAttackedByEnemyTickPvP = target.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; } }
/// <summary> /// execute non duration spell effect on target /// </summary> /// <param name="target"></param> /// <param name="effectiveness"></param> public override void OnDirectEffect(GameLiving target, double effectiveness) { base.OnDirectEffect(target, effectiveness); if (target == null || !target.IsAlive) { return; } if (Caster.EffectList.GetOfType <MasteryofConcentrationEffect>() != null) { return; } //have to do it here because OnAttackedByEnemy is not called to not get aggro if (target.Realm == 0 || Caster.Realm == 0) { target.LastAttackedByEnemyTickPvE = target.CurrentRegion.Time; } else { target.LastAttackedByEnemyTickPvP = target.CurrentRegion.Time; } SendEffectAnimation(target, 0, false, 1); if (target is GamePlayer) { ((GamePlayer)target).NextCombatStyle = null; ((GamePlayer)target).NextCombatBackupStyle = null; } target.StopCurrentSpellcast(); //stop even if MoC or QC if (target is GamePlayer) { MessageToLiving(target, LanguageMgr.GetTranslation((target as GamePlayer).Client, "Amnesia.MessageToTarget"), eChatType.CT_Spell); } GameSpellEffect effect; effect = SpellHandler.FindEffectOnTarget(target, "Mesmerize"); if (effect != null) { effect.Cancel(false); return; } if (target is GameNPC) { GameNPC npc = (GameNPC)target; IOldAggressiveBrain aggroBrain = npc.Brain as IOldAggressiveBrain; if (aggroBrain != null) { if (Util.Chance(Spell.AmnesiaChance)) { aggroBrain.ClearAggroList(); } } } }
/// <summary> /// Changes shade state of the player /// </summary> /// <param name="state">The new state</param> public override void Shade(bool makeShade) { bool wasShade = Player.IsShade; base.Shade(makeShade); if (wasShade == makeShade) { return; } if (makeShade) { // Necromancer has become a shade. Have any previous NPC // attackers aggro on pet now, as they can't attack the // necromancer any longer. if (Player.ControlledBrain != null && Player.ControlledBrain.Body != null) { GameNPC pet = Player.ControlledBrain.Body; List <GameObject> attackerList; lock (Player.Attackers) attackerList = new List <GameObject>(Player.Attackers); foreach (GameObject obj in attackerList) { if (obj is GameNPC) { GameNPC npc = (GameNPC)obj; if (npc.TargetObject == Player && npc.AttackState) { IOldAggressiveBrain brain = npc.Brain as IOldAggressiveBrain; if (brain != null) { npc.AddAttacker(pet); npc.StopAttack(); brain.AddToAggroList(pet, (int)(brain.GetAggroAmountForLiving(Player) + 1)); } } } } } } else { // Necromancer has lost shade form, release the pet if it // isn't dead already and update necromancer's current health. if (Player.ControlledBrain != null) { (Player.ControlledBrain as ControlledNpcBrain).Stop(); } Player.Health = Math.Min(Player.Health, Player.MaxHealth * Math.Max(10, m_savedPetHealthPercent) / 100); } }
/// <summary> /// How friendly this NPC is to a player. /// </summary> /// <param name="player">GamePlayer that is examining this object</param> /// <param name="firstLetterUppercase"></param> /// <returns>Aggro state as a string.</returns> public override string GetAggroLevelString(GamePlayer player, bool firstLetterUppercase) { IOldAggressiveBrain aggroBrain = Brain as IOldAggressiveBrain; string aggroLevelString; if (GameServer.ServerRules.IsSameRealm(this, player, true)) { if (firstLetterUppercase) { aggroLevelString = LanguageMgr.GetTranslation( player.Client.Account.Language, "GameNPC.GetAggroLevelString.Friendly2"); } else { aggroLevelString = LanguageMgr.GetTranslation( player.Client.Account.Language, "GameNPC.GetAggroLevelString.Friendly1"); } } else if (aggroBrain != null && aggroBrain.AggroLevel > 0) { if (firstLetterUppercase) { aggroLevelString = LanguageMgr.GetTranslation( player.Client.Account.Language, "GameNPC.GetAggroLevelString.Aggressive2"); } else { aggroLevelString = LanguageMgr.GetTranslation( player.Client.Account.Language, "GameNPC.GetAggroLevelString.Aggressive1"); } } else { if (firstLetterUppercase) { aggroLevelString = LanguageMgr.GetTranslation( player.Client.Account.Language, "GameNPC.GetAggroLevelString.Neutral2"); } else { aggroLevelString = LanguageMgr.GetTranslation( player.Client.Account.Language, "GameNPC.GetAggroLevelString.Neutral1"); } } return(aggroLevelString); }
/// <summary> /// execute non duration spell effect on target /// </summary> /// <param name="target"></param> /// <param name="effectiveness"></param> public override void OnDirectEffect(GameLiving target, double effectiveness) { base.OnDirectEffect(target, effectiveness); if (target == null) { return; } if (!target.IsAlive || target.ObjectState != GameLiving.eObjectState.Active) { return; } target.StartInterruptTimer(target.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster); if (target is GameNPC) { GameNPC npc = (GameNPC)target; IOldAggressiveBrain aggroBrain = npc.Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } //check for spell. foreach (GameSpellEffect effect in target.EffectList.GetAllOfType <GameSpellEffect>()) { foreach (Type buffType in buffs) { if (effect.SpellHandler.GetType().Equals(buffType)) { SendEffectAnimation(target, 0, false, 1); effect.Cancel(false); MessageToCaster("Your spell rips away some of your target's enhancing magic.", eChatType.CT_Spell); MessageToLiving(target, "Some of your enhancing magic has been ripped away by a spell!", eChatType.CT_Spell); return; } } } SendEffectAnimation(target, 0, false, 0); MessageToCaster("No enhancement of that type found on the target.", eChatType.CT_SpellResisted); /* * if (!noMessages) * { * MessageToLiving(effect.Owner, effect.Spell.Message3, eChatType.CT_SpellExpires); * Message.SystemToArea(effect.Owner, Util.MakeSentence(effect.Spell.Message4, effect.Owner.GetName(0, false)), eChatType.CT_SpellExpires, effect.Owner); * } */ }
public override void ApplyEffectOnTarget(GameLiving target, double effectiveness) { //TODO: correct effectiveness formula // invoke direct effect if not resisted for DD w/ debuff spells if (Caster is GamePlayer && Spell.Level > 0) { if (((GamePlayer)Caster).CharacterClass.ClassType == eClassType.ListCaster) { int specLevel = Caster.GetModifiedSpecLevel(m_spellLine.Spec); effectiveness = 0.75; effectiveness += (specLevel - 1.0) * 0.5 / Spell.Level; effectiveness = Math.Max(0.75, effectiveness); effectiveness = Math.Min(1.25, effectiveness); effectiveness *= (1.0 + m_caster.GetModified(eProperty.BuffEffectiveness) * 0.01); } else { effectiveness = 1.0; effectiveness *= (1.0 + m_caster.GetModified(eProperty.DebuffEffectivness) * 0.01); } } base.ApplyEffectOnTarget(target, effectiveness); if (target.Realm == 0 || Caster.Realm == 0) { target.LastAttackedByEnemyTickPvE = target.CurrentRegion.Time; Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; } else { target.LastAttackedByEnemyTickPvP = target.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; } if (target is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } if (Spell.CastTime > 0) { target.StartInterruptTimer(target.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster); } }
/// <summary> /// Apply the extra aggression /// </summary> /// <param name="ad"></param> /// <param name="showEffectAnimation"></param> /// <param name="attackResult"></param> public override void DamageTarget(AttackData ad, bool showEffectAnimation, int attackResult) { base.DamageTarget(ad, showEffectAnimation, attackResult); if (ad.Target is GameNPC && Spell.Value > 0) { IOldAggressiveBrain aggroBrain = ((GameNPC)ad.Target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { // this amount is a wild guess - Tolakram aggroBrain.AddToAggroList(Caster, Math.Max(1, (int)(Spell.Value * Caster.Level * 0.1))); //log.DebugFormat("Damage: {0}, Taunt Value: {1}, Taunt Amount {2}", ad.Damage, Spell.Value, Math.Max(1, (int)(Spell.Value * Caster.Level * 0.1))); } } m_lastAttackData = ad; }
public override void OnDirectEffect(GameLiving target, double effectiveness) { if (target is GameNPC) { AttackData ad = Caster.TempProperties.getProperty <object>(GameLiving.LAST_ATTACK_DATA, null) as AttackData; if (ad != null) { IOldAggressiveBrain aggroBrain = ((GameNPC)target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { int aggro = Convert.ToInt32(ad.Damage * Spell.Value); aggroBrain.AddToAggroList(Caster, aggro); //log.DebugFormat("Damage: {0}, Taunt Value: {1}, (de)Taunt Amount {2}", ad.Damage, Spell.Value, aggro.ToString()); } } } }
public override void ApplyEffectOnTarget(GameLiving target, double effectiveness) { base.ApplyEffectOnTarget(target, effectiveness); if (target.Realm == 0 || Caster.Realm == 0) { target.LastAttackedByEnemyTickPvE = target.CurrentRegion.Time; Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; } else { target.LastAttackedByEnemyTickPvP = target.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; } if (target is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)target).Brain as IOldAggressiveBrain; aggroBrain?.AddToAggroList(Caster, (int)Spell.Value); } }
public override void Perform(DOLEvent e, object sender, EventArgs args) { GamePlayer player = BehaviourUtils.GuessGamePlayerFromNotify(e, sender, args); int aggroAmount = P.HasValue ? P.Value : player.Level << 1; GameNPC attacker = Q; if (attacker.Brain is IOldAggressiveBrain) { IOldAggressiveBrain brain = (IOldAggressiveBrain)attacker.Brain; brain.AddToAggroList(player, aggroAmount); } else { if (log.IsWarnEnabled) { log.Warn("Non agressive mob " + attacker.Name + " was order to attack player. This goes against the first directive and will not happen"); } } }
/// <summary> /// When an applied effect starts /// duration spells only /// </summary> /// <param name="effect"></param> public override void OnEffectStart(GameSpellEffect effect) { base.OnEffectStart(effect); if (effect.Owner.Realm == 0 || Caster.Realm == 0) { effect.Owner.LastAttackedByEnemyTickPvE = effect.Owner.CurrentRegion.Time; Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; } else { effect.Owner.LastAttackedByEnemyTickPvP = effect.Owner.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; } GameSpellEffect mezz = SpellHandler.FindEffectOnTarget(effect.Owner, "Mesmerize"); if (mezz != null) { mezz.Cancel(false); } effect.Owner.Disease(true); effect.Owner.BuffBonusMultCategory1.Set((int)eProperty.MaxSpeed, this, 1.0 - 0.15); effect.Owner.BuffBonusMultCategory1.Set((int)eProperty.Strength, this, 1.0 - 0.075); SendUpdates(effect); MessageToLiving(effect.Owner, Spell.Message1, eChatType.CT_Spell); Message.SystemToArea(effect.Owner, Util.MakeSentence(Spell.Message2, effect.Owner.GetName(0, true)), eChatType.CT_System, effect.Owner); effect.Owner.StartInterruptTimer(effect.Owner.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster); if (effect.Owner is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)effect.Owner).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } }
/// <summary> /// Apply effect on target or do spell action if non duration spell /// </summary> /// <param name="target">target that gets the effect</param> /// <param name="effectiveness">factor from 0..1 (0%-100%)</param> public override void ApplyEffectOnTarget(GameLiving target, double effectiveness) { if (target.Realm == 0 || Caster.Realm == 0) { target.LastAttackedByEnemyTickPvE = target.CurrentRegion.Time; Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; } else { target.LastAttackedByEnemyTickPvP = target.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; } if (target.HasAbility(Abilities.CCImmunity)) { MessageToCaster(target.Name + " is immune to this effect!", eChatType.CT_SpellResisted); return; } if (target.TempProperties.getProperty("Charging", false)) { MessageToCaster(target.Name + " is moving to fast for this spell to have any effect!", eChatType.CT_SpellResisted); return; } base.ApplyEffectOnTarget(target, effectiveness); if (Spell.CastTime > 0) { target.StartInterruptTimer(target.SpellInterruptDuration, AttackData.eAttackType.Spell, Caster); } if (target is GameNPC) { GameNPC npc = (GameNPC)target; IOldAggressiveBrain aggroBrain = npc.Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } }
public override void DamageTarget(AttackData ad, bool showEffectAnimation) { if (ad.Damage > 0 && ad.Target is GameNPC) { if (!(Caster is GamePlayer)) { return; } IOldAggressiveBrain aggroBrain = ((GameNPC)ad.Target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { TurretPet turret = null; if (Caster.TargetObject == null || !Caster.IsControlledNPC(Caster.TargetObject as TurretPet)) { if (Caster.ControlledBrain != null && Caster.ControlledBrain.Body != null) { turret = Caster.ControlledBrain.Body as TurretPet; } } else if (Caster.IsControlledNPC(Caster.TargetObject as TurretPet)) { turret = Caster.TargetObject as TurretPet; } if (turret != null) { //pet will take aggro AttackData turretAd = ad; turretAd.Attacker = turret; ad.Target.OnAttackedByEnemy(turretAd); aggroBrain.AddToAggroList(turret, (ad.Damage + ad.CriticalDamage) * 3); } aggroBrain.AddToAggroList(Caster, ad.Damage); } } base.DamageTarget(ad, showEffectAnimation); }
/// <summary> /// When an applied effect expires. /// Duration spells only. /// </summary> /// <param name="effect">The expired effect</param> /// <param name="noMessages">true, when no messages should be sent to player and surrounding</param> /// <returns>immunity duration in milliseconds</returns> public override int OnEffectExpires(GameSpellEffect effect, bool noMessages) { if (effect.Owner == null) { return(0); } base.OnEffectExpires(effect, noMessages); GamePlayer player = effect.Owner as GamePlayer; if (player != null) { player.Client.Out.SendUpdateMaxSpeed(); if (player.Group != null) { player.Group.UpdateMember(player, false, false); } } else { GameNPC npc = effect.Owner as GameNPC; if (npc != null) { IOldAggressiveBrain aggroBrain = npc.Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } } effect.Owner.Notify(GameLivingEvent.CrowdControlExpired, effect.Owner); return((effect.Name == "Pet Stun") ? 0 : 60000); }
public void OnCommand(GameClient client, string[] args) { uint hour = WorldMgr.GetCurrentGameTime() / 1000 / 60 / 60; uint minute = WorldMgr.GetCurrentGameTime() / 1000 / 60 % 60; uint seconde = WorldMgr.GetCurrentGameTime() / 1000 % 60; string name = "(NoName)"; var info = new List <string>(); info.Add(" Current Region : " + client.Player.CurrentRegionID); info.Add(" "); Type regionType = client.Player.CurrentRegion.GetType(); info.Add(" Region ClassType: " + regionType.FullName); info.Add(" "); if (client.Player.TargetObject != null) { if (!string.IsNullOrEmpty(client.Player.TargetObject.Name)) { name = client.Player.TargetObject.Name; } #region Mob /********************* MOB ************************/ if (client.Player.TargetObject is GameNPC) { var target = client.Player.TargetObject as GameNPC; if (target.NPCTemplate != null) { info.Add(" + NPCTemplate: " + "[" + target.NPCTemplate.TemplateId + "] " + target.NPCTemplate.Name); } info.Add(" + Class: " + target.GetType().ToString()); info.Add(" + Brain: " + (target.Brain == null ? "(null)" : target.Brain.GetType().ToString())); if (target.LoadedFromScript) { info.Add(" + Loaded: from Script"); } else { info.Add(" + Loaded: from Database"); } info.Add(" "); if (client.Player.TargetObject is GameMerchant) { var targetM = client.Player.TargetObject as GameMerchant; info.Add(" + Is Merchant "); if (targetM.TradeItems != null) { info.Add(" + Sell List: \n " + targetM.TradeItems.ItemsListID); } else { info.Add(" + Sell List: Not Present !\n"); } info.Add(" "); } if (client.Player.TargetObject is GamePet) { var targetP = client.Player.TargetObject as GamePet; info.Add(" + Is Pet "); info.Add(" + Pet Owner: " + targetP.Owner); info.Add(" "); } if (client.Player.TargetObject is GameMovingObject) { var targetM = client.Player.TargetObject as GameMovingObject; info.Add(" + Is GameMovingObject "); info.Add(" + ( Boats - Siege weapons - Custom Object"); info.Add(" + Emblem: " + targetM.Emblem); info.Add(" "); } info.Add(" + Name: " + name); if (target.GuildName != null && target.GuildName.Length > 0) { info.Add(" + Guild: " + target.GuildName); } info.Add(" + Level: " + target.Level); info.Add(" + Realm: " + GlobalConstants.RealmToName(target.Realm)); info.Add(" + Model: " + target.Model); info.Add(" + Size " + target.Size); info.Add(string.Format(" + Flags: {0} (0x{1})", ((GameNPC.eFlags)target.Flags).ToString("G"), target.Flags.ToString("X"))); info.Add(" "); info.Add(" + Speed(current/max): " + target.CurrentSpeed + "/" + target.MaxSpeedBase); info.Add(" + Health: " + target.Health + "/" + target.MaxHealth); info.Add(" + Endu: " + target.Endurance + "/" + target.MaxEndurance); info.Add(" + Mana: " + target.Mana + "/" + target.MaxMana); info.Add(" + Conc: " + target.Concentration + "/" + target.MaxConcentration); IOldAggressiveBrain aggroBrain = target.Brain as IOldAggressiveBrain; if (aggroBrain != null) { info.Add(" + Aggro level: " + aggroBrain.AggroLevel); info.Add(" + Aggro range: " + aggroBrain.AggroRange); if (target.MaxDistance < 0) { info.Add(" + MaxDistance: " + -target.MaxDistance * aggroBrain.AggroRange / 100); } else { info.Add(" + MaxDistance: " + target.MaxDistance); } } else { info.Add(" + Not aggressive brain"); } if (target.NPCTemplate != null) { info.Add(" + NPCTemplate: " + "[" + target.NPCTemplate.TemplateId + "] " + target.NPCTemplate.Name); } info.Add(" + Roaming Range: " + target.RoamingRange); TimeSpan respawn = TimeSpan.FromMilliseconds(target.RespawnInterval); if (target.RespawnInterval <= 0) { info.Add(" + Respawn: NPC will not respawn"); } else { string days = ""; string hours = ""; if (respawn.Days > 0) { days = respawn.Days + " days "; } if (respawn.Hours > 0) { hours = respawn.Hours + " hours "; } info.Add(" + Respawn: " + days + hours + respawn.Minutes + " minutes " + respawn.Seconds + " seconds"); info.Add(" + SpawnPoint: " + target.SpawnPoint.X + ", " + target.SpawnPoint.Y + ", " + target.SpawnPoint.Z); } if (target.QuestListToGive.Count > 0) { info.Add(" + Quests to give: " + target.QuestListToGive.Count); } if (target.PathID != null && target.PathID.Length > 0) { info.Add(" + Path: " + target.PathID); } if (target.OwnerID != null && target.OwnerID.Length > 0) { info.Add(" + OwnerID: " + target.OwnerID); } info.Add(" "); info.Add($" + {target.Strength} STR / {target.Constitution} CON / {target.Dexterity} DEX / {target.Quickness} QUI"); info.Add($" + {target.Intelligence} INT / {target.Empathy} EMP / {target.Piety} PIE / {target.Charisma} CHR"); info.Add($" + {target.WeaponDps} DPS / {target.WeaponSpd} SPD / {target.ArmorFactor} AF / {target.ArmorAbsorb} ABS"); info.Add($" + {target.BlockChance}% Block / {target.ParryChance}% Parry / {target.EvadeChance}% Evade"); info.Add(" + Damage type: " + target.MeleeDamageType); if (target.LeftHandSwingChance > 0) { info.Add(" + Left Swing %: " + target.LeftHandSwingChance); } if (target.Abilities != null && target.Abilities.Count > 0) { info.Add(" + Abilities: " + target.Abilities.Count); } if (target.Spells != null && target.Spells.Count > 0) { info.Add(" + Spells: " + target.Spells.Count); } if (target.Styles != null && target.Styles.Count > 0) { info.Add(" + Styles: " + target.Styles.Count); } info.Add(" "); if (target.Race > 0) { info.Add(" + Race: " + target.Race); } if (target.BodyType > 0) { info.Add(" + Body Type: " + target.BodyType); } if (target.GetDamageResist(eProperty.Resist_Crush) > 0) { info.Add(" + Resist Crush: " + target.GetDamageResist(eProperty.Resist_Crush)); } if (target.GetDamageResist(eProperty.Resist_Slash) > 0) { info.Add(" + Resist Slash: " + target.GetDamageResist(eProperty.Resist_Slash)); } if (target.GetDamageResist(eProperty.Resist_Thrust) > 0) { info.Add(" + Resist Thrust: " + target.GetDamageResist(eProperty.Resist_Thrust)); } if (target.GetDamageResist(eProperty.Resist_Heat) > 0) { info.Add(" + Resist Heat: " + target.GetDamageResist(eProperty.Resist_Heat)); } if (target.GetDamageResist(eProperty.Resist_Cold) > 0) { info.Add(" + Resist Cold: " + target.GetDamageResist(eProperty.Resist_Cold)); } if (target.GetDamageResist(eProperty.Resist_Matter) > 0) { info.Add(" + Resist Matter: " + target.GetDamageResist(eProperty.Resist_Matter)); } if (target.GetDamageResist(eProperty.Resist_Natural) > 0) { info.Add(" + Resist Natural: " + target.GetDamageResist(eProperty.Resist_Natural)); } if (target.GetDamageResist(eProperty.Resist_Body) > 0) { info.Add(" + Resist Body: " + target.GetDamageResist(eProperty.Resist_Body)); } if (target.GetDamageResist(eProperty.Resist_Spirit) > 0) { info.Add(" + Resist Spirit: " + target.GetDamageResist(eProperty.Resist_Spirit)); } if (target.GetDamageResist(eProperty.Resist_Energy) > 0) { info.Add(" + Resist Energy: " + target.GetDamageResist(eProperty.Resist_Energy)); } info.Add(" + Active weapon slot: " + target.ActiveWeaponSlot); info.Add(" + Visible weapon slot: " + target.VisibleActiveWeaponSlots); if (target.EquipmentTemplateID != null && target.EquipmentTemplateID.Length > 0) { info.Add(" + Equipment Template ID: " + target.EquipmentTemplateID); } if (target.Inventory != null) { info.Add(" + Inventory: " + target.Inventory.AllItems.Count + " items"); } info.Add(" "); info.Add(" + Mob_ID: " + target.InternalID); info.Add(" + Position: " + target.Position.ToString("F0") + ", " + target.Heading); info.Add(" + OID: " + target.ObjectID); info.Add(" + Package ID: " + target.PackageID); /* if (target.Brain != null && target.Brain.IsActive) * { * info.Add(target.Brain.GetType().FullName); * info.Add(target.Brain.ToString()); * info.Add(""); * } */ info.Add(""); info.Add(" ------ State ------"); if (target.IsReturningHome || target.IsReturningToSpawnPoint) { info.Add("IsReturningHome: " + target.IsReturningHome); info.Add("IsReturningToSpawnPoint: " + target.IsReturningToSpawnPoint); info.Add(""); } info.Add("InCombat: " + target.InCombat); info.Add("AttackState: " + target.AttackState); info.Add("LastCombatPVE: " + target.LastAttackedByEnemyTickPvE); info.Add("LastCombatPVP: " + target.LastAttackedByEnemyTickPvP); if (target.InCombat || target.AttackState) { info.Add("RegionTick: " + target.CurrentRegion.Time); } info.Add(""); if (target.TargetObject != null) { info.Add("TargetObject: " + target.TargetObject.Name); info.Add("InView: " + target.TargetInView); } if (target.Brain != null && target.Brain is StandardMobBrain) { Dictionary <GameLiving, long> aggroList = (target.Brain as StandardMobBrain).AggroTable; if (aggroList.Count > 0) { info.Add(""); info.Add("Aggro List:"); foreach (GameLiving living in aggroList.Keys) { info.Add(living.Name + ": " + aggroList[living]); } } } if (target.Attackers != null && target.Attackers.Count > 0) { info.Add(""); info.Add("Attacker List:"); foreach (GameLiving attacker in target.Attackers) { info.Add(attacker.Name); } } if (target.EffectList.Count > 0) { info.Add(""); info.Add("Effect List:"); foreach (IGameEffect effect in target.EffectList) { info.Add(effect.Name + " remaining " + effect.RemainingTime); } } info.Add(""); info.Add(" + Loot:"); var template = DOLDB <LootTemplate> .SelectObjects(DB.Column(nameof(LootTemplate.TemplateName)).IsEqualTo(target.Name)); foreach (LootTemplate loot in template) { ItemTemplate drop = GameServer.Database.FindObjectByKey <ItemTemplate>(loot.ItemTemplateID); string message = ""; if (drop == null) { message += loot.ItemTemplateID + " (Template Not Found)"; } else { message += drop.Name + " (" + drop.Id_nb + ")"; } message += " Chance: " + loot.Chance.ToString(); info.Add("- " + message); } } #endregion Mob #region Player /********************* PLAYER ************************/ if (client.Player.TargetObject is GamePlayer) { var target = client.Player.TargetObject as GamePlayer; info.Add("PLAYER INFORMATION (Client # " + target.Client.SessionID + ")"); info.Add(" - Name : " + target.Name); info.Add(" - Lastname : " + target.LastName); info.Add(" - Realm : " + GlobalConstants.RealmToName(target.Realm)); info.Add(" - Level : " + target.Level); info.Add(" - Class : " + target.CharacterClass.Name); info.Add(" - Guild : " + target.GuildName); info.Add(" "); info.Add(" - Account Name : " + target.AccountName); info.Add(" - IP : " + target.Client.Account.LastLoginIP); info.Add(" - Priv. Level : " + target.Client.Account.PrivLevel); info.Add(" - Client Version: " + target.Client.Account.LastClientVersion); info.Add(" "); info.Add(" - Craftingskill : " + target.CraftingPrimarySkill + ""); info.Add(" - Model ID : " + target.Model); info.Add(" - AFK Message: " + target.TempProperties.getProperty <string>(GamePlayer.AFK_MESSAGE) + ""); info.Add(" "); info.Add(" - Money : " + Money.GetString(target.GetCurrentMoney()) + "\n"); info.Add(" - Speed : " + target.MaxSpeedBase); info.Add(" - XPs : " + target.Experience); info.Add(" - RPs : " + target.RealmPoints); info.Add(" - BPs : " + target.BountyPoints); String sCurrent = ""; String sTitle = ""; int cnt = 0; info.Add(" "); info.Add("SPECCING INFORMATIONS "); info.Add(" - Remaining spec. points : " + target.SkillSpecialtyPoints); sTitle = " - Player specialisations / level: \n"; sCurrent = ""; foreach (Specialization spec in target.GetSpecList()) { sCurrent += " - " + spec.Name + " = " + spec.Level + " \n"; } info.Add(sTitle + sCurrent); sCurrent = ""; sTitle = ""; info.Add(" "); info.Add("CHARACTER STATS "); info.Add(" - Maximum Health : " + target.MaxHealth); info.Add(" - Current AF : " + target.GetModified(eProperty.ArmorFactor)); info.Add(" - Current ABS : " + target.GetModified(eProperty.ArmorAbsorption)); for (eProperty stat = eProperty.Stat_First; stat <= eProperty.Stat_Last; stat++, cnt++) { sTitle += GlobalConstants.PropertyToName(stat); sCurrent += target.GetModified(stat); info.Add(" - " + sTitle + " : " + sCurrent); sCurrent = ""; sTitle = ""; } sCurrent = ""; sTitle = ""; cnt = 0; for (eProperty res = eProperty.Resist_First; res <= eProperty.Resist_Last; res++, cnt++) { sTitle += GlobalConstants.PropertyToName(res); sCurrent += target.GetModified(res); info.Add(" - " + sTitle + " : " + sCurrent); sCurrent = ""; sTitle = ""; } info.Add(" "); info.Add(" "); info.Add(" - Respecs dol : " + target.RespecAmountDOL); info.Add(" - Respecs single : " + target.RespecAmountSingleSkill); info.Add(" - Respecs full : " + target.RespecAmountAllSkill); info.Add(" "); info.Add(" "); info.Add(" --------------------------------------"); info.Add(" ----- Inventory Equiped -----"); info.Add(" --------------------------------------"); ////////////// Inventaire ///////////// info.Add(" ----- Money:"); info.Add(Money.GetShortString(target.GetCurrentMoney())); info.Add(" "); info.Add(" ----- Wearing:"); foreach (InventoryItem item in target.Inventory.EquippedItems) { info.Add(" [" + GlobalConstants.SlotToName(item.Item_Type) + "] " + item.Name); } info.Add(" "); } #endregion Player #region StaticItem /********************* OBJECT ************************/ if (client.Player.TargetObject is GameStaticItem) { var target = client.Player.TargetObject as GameStaticItem; info.Add(" ------- OBJECT ------\n"); info.Add(" Name: " + name); info.Add(" Model: " + target.Model); info.Add(" Emblem: " + target.Emblem); info.Add(" Realm: " + target.Realm); if (target.Owners.LongLength > 0) { info.Add(" "); info.Add(" Owner Name: " + target.Owners[0].Name); } info.Add(" "); info.Add(" OID: " + target.ObjectID); info.Add(" Type: " + target.GetType()); WorldInventoryItem invItem = target as WorldInventoryItem; if (invItem != null) { info.Add(" Count: " + invItem.Item.Count); } info.Add(" "); info.Add(" Location: " + target.Position.ToString("F0")); } #endregion StaticItem #region Door /********************* DOOR ************************/ if (client.Player.TargetObject is GameDoor) { var target = client.Player.TargetObject as GameDoor; string Realmname = ""; string statut = ""; name = target.Name; if (target.Realm == eRealm.None) { Realmname = "None"; } if (target.Realm == eRealm.Albion) { Realmname = "Albion"; } if (target.Realm == eRealm.Midgard) { Realmname = "Midgard"; } if (target.Realm == eRealm.Hibernia) { Realmname = "Hibernia"; } if (target.Realm == eRealm.Door) { Realmname = "All"; } if (target.Locked == 1) { statut = " Locked"; } if (target.Locked == 0) { statut = " Unlocked"; } info.Add(" ------- DOOR ------\n"); info.Add(" "); info.Add(" + Name : " + target.Name); info.Add(" + ID : " + target.DoorID); info.Add(" + Realm : " + (int)target.Realm + " : " + Realmname); info.Add(" + Level : " + target.Level); info.Add(" + Guild : " + target.GuildName); info.Add(" + Health : " + target.Health + " / " + target.MaxHealth); info.Add(" + Statut : " + statut); info.Add(" + Type : " + DoorRequestHandler.m_handlerDoorID / 100000000); info.Add(" "); info.Add(" + Position : " + target.Position.ToString("F0")); info.Add(" + Heading : " + target.Heading); } #endregion Door #region Keep /********************* KEEP ************************/ if (client.Player.TargetObject is GameKeepComponent) { var target = client.Player.TargetObject as GameKeepComponent; name = target.Name; string realm = " other realm"; if ((byte)target.Realm == 0) { realm = " Monster"; } if ((byte)target.Realm == 1) { realm = " Albion"; } if ((byte)target.Realm == 2) { realm = " Midgard"; } if ((byte)target.Realm == 3) { realm = " Hibernia"; } info.Add(" ------- KEEP ------\n"); info.Add(" + Name : " + target.Name); info.Add(" + KeepID : " + target.Keep.KeepID); info.Add(" + Level : " + target.Level); info.Add(" + BaseLevel : " + target.Keep.BaseLevel); info.Add(" + Realm : " + realm); info.Add(" "); info.Add(" + Model : " + target.Model); info.Add(" + Skin : " + target.Skin); info.Add(" + Height : " + target.Height); info.Add(" + ID : " + target.ID); info.Add(" "); info.Add(" + Health : " + target.Health); info.Add(" + IsRaized : " + target.IsRaized); info.Add(" + Status : " + target.Status); info.Add(" "); info.Add(" + Climbing : " + target.Climbing); info.Add(" "); info.Add(" + ComponentX : " + target.ComponentX); info.Add(" + ComponentY : " + target.ComponentY); info.Add(" + ComponentHeading : " + target.ComponentHeading); info.Add(" "); info.Add(" + HookPoints : " + target.HookPoints.Count); info.Add(" + Positions : " + target.Positions.Count); info.Add(" "); info.Add(" + RealmPointsValue : " + target.RealmPointsValue); info.Add(" + ExperienceValue : " + target.ExperienceValue); info.Add(" + AttackRange : " + target.AttackRange); info.Add(" "); if (GameServer.KeepManager.GetFrontierKeeps().Contains(target.Keep)) { info.Add(" + Keep Manager : " + GameServer.KeepManager.GetType().FullName); info.Add(" + Frontiers"); } else if (GameServer.KeepManager.GetBattleground(target.CurrentRegionID) != null) { info.Add(" + Keep Manager : " + GameServer.KeepManager.GetType().FullName); Battleground bg = GameServer.KeepManager.GetBattleground(client.Player.CurrentRegionID); info.Add(" + Battleground (" + bg.MinLevel + " to " + bg.MaxLevel + ", max RL: " + bg.MaxRealmLevel + ")"); } else { info.Add(" + Keep Manager : Not Managed"); } } #endregion Keep client.Out.SendCustomTextWindow("[ " + name + " ]", info); return; } if (client.Player.TargetObject == null) { /*********************** HOUSE *************************/ if (client.Player.InHouse) { #region House House house = client.Player.CurrentHouse as House; name = house.Name; int level = house.Model - ((house.Model - 1) / 4) * 4; TimeSpan due = (house.LastPaid.AddDays(ServerProperties.Properties.RENT_DUE_DAYS).AddHours(1) - DateTime.Now); info.Add(" ------- HOUSE ------\n"); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Owner", name)); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Lotnum", house.HouseNumber)); info.Add("Unique ID: " + house.UniqueID); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Level", level)); info.Add(" "); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Porch")); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.PorchEnabled", (house.Porch ? " Present" : " Not Present"))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.PorchRoofColor", Color(house.PorchRoofColor))); info.Add(" "); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.ExteriorMaterials")); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.RoofMaterial", MaterialWall(house.RoofMaterial))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.WallMaterial", MaterialWall(house.WallMaterial))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.DoorMaterial", MaterialDoor(house.DoorMaterial))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.TrussMaterial", MaterialTruss(house.TrussMaterial))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.PorchMaterial", MaterialTruss(house.PorchMaterial))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.WindowMaterial", MaterialTruss(house.WindowMaterial))); info.Add(" "); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.ExteriorUpgrades")); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.OutdoorGuildBanner", ((house.OutdoorGuildBanner) ? " Present" : " Not Present"))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.OutdoorGuildShield", ((house.OutdoorGuildShield) ? " Present" : " Not Present"))); info.Add(" "); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.InteriorUpgrades")); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.IndoorGuildBanner", ((house.IndoorGuildBanner) ? " Present" : " Not Present"))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.IndoorGuildShield", ((house.IndoorGuildShield) ? " Present" : " Not Present"))); info.Add(" "); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.InteriorCarpets")); if (house.Rug1Color != 0) { info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Rug1Color", Color(house.Rug1Color))); } if (house.Rug2Color != 0) { info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Rug2Color", Color(house.Rug2Color))); } if (house.Rug3Color != 0) { info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Rug3Color", Color(house.Rug3Color))); } if (house.Rug4Color != 0) { info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Rug4Color", Color(house.Rug4Color))); } info.Add(" "); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.Lockbox", Money.GetString(house.KeptMoney))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.RentalPrice", Money.GetString(HouseMgr.GetRentByModel(house.Model)))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.MaxLockbox", Money.GetString(HouseMgr.GetRentByModel(house.Model) * ServerProperties.Properties.RENT_LOCKBOX_PAYMENTS))); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.RentDueIn", due.Days, due.Hours)); #endregion House client.Out.SendCustomTextWindow(LanguageMgr.GetTranslation(client.Account.Language, "House.SendHouseInfo.HouseOwner", name), info); } else // No target and not in a house { string realm = " other realm"; if (client.Player.CurrentZone.Realm == eRealm.Albion) { realm = " Albion"; } if (client.Player.CurrentZone.Realm == eRealm.Midgard) { realm = " Midgard"; } if (client.Player.CurrentZone.Realm == eRealm.Hibernia) { realm = " Hibernia"; } info.Add(" Game Time: \t" + hour.ToString() + ":" + minute.ToString()); info.Add(" "); info.Add(" Server Rules: " + GameServer.ServerRules.GetType().FullName); if (GameServer.KeepManager.FrontierRegionsList.Contains(client.Player.CurrentRegionID)) { info.Add(" Keep Manager: " + GameServer.KeepManager.GetType().FullName); info.Add(" Frontiers"); } else if (GameServer.KeepManager.GetBattleground(client.Player.CurrentRegionID) != null) { info.Add(" Keep Manager: " + GameServer.KeepManager.GetType().FullName); Battleground bg = GameServer.KeepManager.GetBattleground(client.Player.CurrentRegionID); info.Add(" Battleground (" + bg.MinLevel + " to " + bg.MaxLevel + ", max RL: " + bg.MaxRealmLevel + ")"); } else { info.Add(" Keep Manager : None for this region"); } info.Add(" "); info.Add(" Server players: " + WorldMgr.GetAllPlayingClientsCount()); info.Add(" "); info.Add(" Region Players:"); info.Add(" All players: " + WorldMgr.GetClientsOfRegionCount(client.Player.CurrentRegion.ID)); info.Add(" "); info.Add(" Alb players: " + WorldMgr.GetClientsOfRegionCount(client.Player.CurrentRegion.ID, eRealm.Albion)); info.Add(" Hib players: " + WorldMgr.GetClientsOfRegionCount(client.Player.CurrentRegion.ID, eRealm.Hibernia)); info.Add(" Mid players: " + WorldMgr.GetClientsOfRegionCount(client.Player.CurrentRegion.ID, eRealm.Midgard)); info.Add(" "); info.Add(" Total objects in region: " + client.Player.CurrentRegion.TotalNumberOfObjects); info.Add(" "); info.Add(" NPC in zone:"); info.Add(" Alb : " + client.Player.CurrentZone.GetNPCsOfZone(eRealm.Albion).Count); info.Add(" Hib : " + client.Player.CurrentZone.GetNPCsOfZone(eRealm.Hibernia).Count); info.Add(" Mid: " + client.Player.CurrentZone.GetNPCsOfZone(eRealm.Midgard).Count); info.Add(" None : " + client.Player.CurrentZone.GetNPCsOfZone(eRealm.None).Count); info.Add(" "); info.Add(" Total objects in zone: " + client.Player.CurrentZone.TotalNumberOfObjects); info.Add(" "); info.Add(" Zone Description: " + client.Player.CurrentZone.Description); info.Add(" Zone Realm: " + realm); info.Add(" Zone ID: " + client.Player.CurrentZone.ID); info.Add(" Zone IsDungeon: " + client.Player.CurrentZone.IsDungeon); info.Add(" Zone SkinID: " + client.Player.CurrentZone.ZoneSkinID); info.Add(" Zone X: " + client.Player.CurrentZone.XOffset); info.Add(" Zone Y: " + client.Player.CurrentZone.YOffset); info.Add(" Zone Width: " + client.Player.CurrentZone.Width); info.Add(" Zone Height: " + client.Player.CurrentZone.Height); info.Add(" Zone DivingEnabled: " + client.Player.CurrentZone.IsDivingEnabled); info.Add(" Zone Waterlevel: " + client.Player.CurrentZone.Waterlevel); info.Add(" "); info.Add(" Region Name: " + client.Player.CurrentRegion.Name); info.Add(" Region Description: " + client.Player.CurrentRegion.Description); info.Add(" Region Skin: " + client.Player.CurrentRegion.Skin); info.Add(" Region ID: " + client.Player.CurrentRegion.ID); info.Add(" Region Expansion: " + client.Player.CurrentRegion.Expansion); info.Add(" Region IsRvR: " + client.Player.CurrentRegion.IsRvR); info.Add(" Region IsFrontier: " + client.Player.CurrentRegion.IsFrontier); info.Add(" Region IsDungeon: " + client.Player.CurrentRegion.IsDungeon); info.Add(" Zone in Region: " + client.Player.CurrentRegion.Zones.Count); info.Add(" Region WaterLevel: " + client.Player.CurrentRegion.WaterLevel); info.Add(" Region HousingEnabled: " + client.Player.CurrentRegion.HousingEnabled); info.Add(" Region IsDisabled: " + client.Player.CurrentRegion.IsDisabled); info.Add(" "); info.Add(" Region ServerIP: " + client.Player.CurrentRegion.ServerIP); info.Add(" Region ServerPort: " + client.Player.CurrentRegion.ServerPort); client.Out.SendCustomTextWindow("[ " + client.Player.CurrentRegion.Description + " ]", info); } } }
protected override void OnTick() { GameLiving target = m_arrowTarget; GameLiving caster = (GameLiving)m_actionSource; if (target == null || !target.IsAlive || target.ObjectState != GameObject.eObjectState.Active || target.CurrentRegionID != caster.CurrentRegionID) { return; } int missrate = 100 - m_handler.CalculateToHitChance(target); // add defence bonus from last executed style if any AttackData targetAD = (AttackData)target.TempProperties.getProperty <object>(GameLiving.LAST_ATTACK_DATA, null); if (targetAD != null && targetAD.AttackResult == GameLiving.eAttackResult.HitStyle && targetAD.Style != null) { missrate += targetAD.Style.BonusToDefense; } // half of the damage is magical // subtract any spelldamage bonus and re-calculate after half damage is calculated AttackData ad = m_handler.CalculateDamageToTarget(target, 0.5 - (caster.GetModified(eProperty.SpellDamage) * 0.01)); // check for bladeturn miss if (ad.AttackResult == GameLiving.eAttackResult.Missed) { return; } if (Util.Chance(missrate)) { ad.AttackResult = GameLiving.eAttackResult.Missed; m_handler.MessageToCaster("You miss!", eChatType.CT_YouHit); m_handler.MessageToLiving(target, caster.GetName(0, false) + " missed!", eChatType.CT_Missed); target.OnAttackedByEnemy(ad); target.StartInterruptTimer(target.SpellInterruptDuration, ad.AttackType, caster); if (target is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(caster, 1); } } return; } ad.Damage = (int)((double)ad.Damage * (1.0 + caster.GetModified(eProperty.SpellDamage) * 0.01)); bool arrowBlock = false; if (target is GamePlayer && !target.IsStunned && !target.IsMezzed && !target.IsSitting && m_handler.Spell.LifeDrainReturn != (int)Archery.eShotType.Critical) { GamePlayer player = (GamePlayer)target; InventoryItem lefthand = player.Inventory.GetItem(eInventorySlot.LeftHandWeapon); if (lefthand != null && (player.AttackWeapon == null || player.AttackWeapon.Item_Type == Slot.RIGHTHAND || player.AttackWeapon.Item_Type == Slot.LEFTHAND)) { if (target.IsObjectInFront(caster, 180) && lefthand.Object_Type == (int)eObjectType.Shield) { // TODO: shield size vs number of attackers not calculated double shield = 0.5 * player.GetModifiedSpecLevel(Specs.Shields); double blockchance = ((player.Dexterity * 2) - 100) / 40.0 + shield + (0 * 3) + 5; blockchance += 30; blockchance -= target.GetConLevel(caster) * 5; if (blockchance >= 100) { blockchance = 99; } if (blockchance <= 0) { blockchance = 1; } if (target.IsEngaging) { EngageEffect engage = target.EffectList.GetOfType <EngageEffect>(); if (engage != null && target.AttackState && engage.EngageTarget == caster) { // Engage raised block change to 85% if attacker is engageTarget and player is in attackstate // You cannot engage a mob that was attacked within the last X seconds... if (engage.EngageTarget.LastAttackedByEnemyTick > engage.EngageTarget.CurrentRegion.Time - EngageAbilityHandler.ENGAGE_ATTACK_DELAY_TICK) { if (engage.Owner is GamePlayer) { (engage.Owner as GamePlayer).Out.SendMessage(engage.EngageTarget.GetName(0, true) + " has been attacked recently and you are unable to engage.", eChatType.CT_System, eChatLoc.CL_SystemWindow); } } // Check if player has enough endurance left to engage else if (engage.Owner.Endurance < EngageAbilityHandler.ENGAGE_DURATION_LOST) { engage.Cancel(false); // if player ran out of endurance cancel engage effect } else { engage.Owner.Endurance -= EngageAbilityHandler.ENGAGE_DURATION_LOST; if (engage.Owner is GamePlayer) { (engage.Owner as GamePlayer).Out.SendMessage("You concentrate on blocking the blow!", eChatType.CT_Skill, eChatLoc.CL_SystemWindow); } if (blockchance < 85) { blockchance = 85; } } } } if (blockchance >= Util.Random(1, 100)) { arrowBlock = true; m_handler.MessageToLiving(player, "You block " + caster.GetName(0, false) + "'s arrow!", eChatType.CT_System); if (m_handler.Spell.Target.ToLower() != "area") { m_handler.MessageToCaster(player.GetName(0, true) + " blocks your arrow!", eChatType.CT_System); m_handler.DamageTarget(ad, false, 0x02); } } } } } if (arrowBlock == false) { // now calculate the magical part of arrow damage (similar to bolt calculation). Part 1 Physical, Part 2 Magical double damage = m_handler.Spell.Damage / 2; // another half is physical damage if (target is GamePlayer) { ad.ArmorHitLocation = ((GamePlayer)target).CalculateArmorHitLocation(ad); } InventoryItem armor = null; if (target.Inventory != null) { armor = target.Inventory.GetItem((eInventorySlot)ad.ArmorHitLocation); } double ws = (caster.Level * 8 * (1.0 + (caster.GetModified(eProperty.Dexterity) - 50) / 200.0)); damage *= ((ws + 90.68) / (target.GetArmorAF(ad.ArmorHitLocation) + 20 * 4.67)); damage *= 1.0 - Math.Min(0.85, ad.Target.GetArmorAbsorb(ad.ArmorHitLocation)); ad.Modifier = (int)(damage * (ad.Target.GetResist(ad.DamageType) + SkillBase.GetArmorResist(armor, ad.DamageType)) / -100.0); damage += ad.Modifier; double effectiveness = caster.Effectiveness; effectiveness += (caster.GetModified(eProperty.SpellDamage) * 0.01); damage = damage * effectiveness; damage *= (1.0 + RelicMgr.GetRelicBonusModifier(caster.Realm, eRelicType.Magic)); if (damage < 0) { damage = 0; } ad.Damage += (int)damage; if (caster.AttackWeapon != null) { // Quality ad.Damage -= (int)(ad.Damage * (100 - caster.AttackWeapon.Quality) * .01); // Condition ad.Damage = (int)((double)ad.Damage * Math.Min(1.0, (double)caster.AttackWeapon.Condition / (double)caster.AttackWeapon.MaxCondition)); // Patch Note: http://support.darkageofcamelot.com/kb/article.php?id=931 // - The Damage Per Second (DPS) of your bow will have an effect on your damage for archery shots. If the effective DPS // of your equipped bow is less than that of your max DPS for the level of archery shot you are using, the damage of your // shot will be reduced. Max DPS for a particular level can be found by using this equation: (.3 * level) + 1.2 int spellRequiredDPS = 12 + 3 * m_handler.Spell.Level; if (caster.AttackWeapon.DPS_AF < spellRequiredDPS) { double percentReduction = (double)caster.AttackWeapon.DPS_AF / (double)spellRequiredDPS; ad.Damage = (int)(ad.Damage * percentReduction); } } if (ad.Damage < 0) { ad.Damage = 0; } ad.UncappedDamage = ad.Damage; ad.Damage = (int)Math.Min(ad.Damage, m_handler.DamageCap(effectiveness)); if (ad.CriticalDamage > 0) { if (m_handler.Spell.Target.ToLower() == "area") { ad.CriticalDamage = 0; } else { int critMax = (target is GamePlayer) ? ad.Damage / 2 : ad.Damage; ad.CriticalDamage = Util.Random(critMax / 10, critMax); } } target.ModifyAttack(ad); m_handler.SendDamageMessages(ad); m_handler.DamageTarget(ad, false, 0x14); target.StartInterruptTimer(target.SpellInterruptDuration, ad.AttackType, caster); } if (m_handler.Spell.SubSpellID != 0) { Spell subspell = SkillBase.GetSpellByID(m_handler.Spell.SubSpellID); if (subspell != null) { subspell.Level = m_handler.Spell.Level; ISpellHandler spellhandler = ScriptMgr.CreateSpellHandler(m_handler.Caster, subspell, SkillBase.GetSpellLine(GlobalSpellsLines.Combat_Styles_Effect)); if (spellhandler != null) { spellhandler.StartSpell(target); } } } if (arrowBlock == false && m_handler.Caster.AttackWeapon != null && GlobalConstants.IsBowWeapon((eObjectType)m_handler.Caster.AttackWeapon.Object_Type)) { if (ad.AttackResult == GameLiving.eAttackResult.HitUnstyled || ad.AttackResult == GameLiving.eAttackResult.HitStyle) { caster.CheckWeaponMagicalEffect(ad, m_handler.Caster.AttackWeapon); } } }
public void SpawnEncounter() { //Lets start spawning the encounter mobs! //First we spawn the 30 Wall of Fire mobs around the perimeter of the island. for (int i = 0; i < 30; i++) { SpawnAfire(FirePosition[i, 0], FirePosition[i, 1], FirePosition[i, 2]); } //Next we spawn the two sets of stair guards for (int i = 0; i < 4; i++) { SpawnAGuard(GuardPosition[i, 0], GuardPosition[i, 1], GuardPosition[i, 2], 3720); } for (int i = 4; i < 8; i++) { SpawnAGuard(GuardPosition[i, 0], GuardPosition[i, 1], GuardPosition[i, 2], 1735); } //Next we spawn Sunkaio GameSunkaio sunkaio = new GameSunkaio(); sunkaio.Model = 1349; sunkaio.Size = 100; sunkaio.Level = 68; //level 65 on live sunkaio.Name = "Sunkaio"; sunkaio.CurrentRegionID = (ushort)Ianetor.playerregion; sunkaio.Heading = 1690; sunkaio.Realm = 0; sunkaio.CurrentSpeed = 0; sunkaio.MaxSpeedBase = 191; sunkaio.GuildName = ""; sunkaio.X = 431865; sunkaio.Y = 544121; sunkaio.Z = 8311; sunkaio.RoamingRange = 0; sunkaio.RespawnInterval = 0; sunkaio.BodyType = 0; SunBrain brain = new SunBrain(); brain.AggroLevel = 100; brain.AggroRange = 350; sunkaio.SetOwnBrain(brain); sunkaio.AddToWorld(); BossList.Add(sunkaio); Sun = sunkaio; GameEventMgr.AddHandler(sunkaio, GameNPCEvent.Dying, new DOLEventHandler(Ianetor.SunHasDied)); //Next we spawn Zopureo GameZopureo zopureo = new GameZopureo(); zopureo.Model = 1349; zopureo.Size = 100; zopureo.Level = 70; zopureo.Name = "Zopureo"; zopureo.CurrentRegionID = (ushort)Ianetor.playerregion; zopureo.Heading = 1690; zopureo.Realm = 0; zopureo.CurrentSpeed = 0; zopureo.MaxSpeedBase = 0; zopureo.GuildName = ""; zopureo.X = 432767; zopureo.Y = 543483; zopureo.Z = 8291; zopureo.RoamingRange = 0; zopureo.RespawnInterval = 0; zopureo.BodyType = 0; ZopureoBrain zbrain = new ZopureoBrain(); zbrain.AggroLevel = 100; zbrain.AggroRange = 0; zopureo.SetOwnBrain(zbrain); zopureo.AddToWorld(); BossList.Add(zopureo); Zop = zopureo; GameEventMgr.AddHandler(zopureo, GameNPCEvent.Dying, new DOLEventHandler(Ianetor.ZopHasDied)); //Next we spawn Aithos GameAithos aithos = new GameAithos(); aithos.Model = 1349; aithos.Size = 100; aithos.Level = 68; //level 65 on live aithos.Name = "Aithos"; aithos.CurrentRegionID = (ushort)Ianetor.playerregion; aithos.Heading = 1690; aithos.Realm = 0; aithos.CurrentSpeed = 0; aithos.MaxSpeedBase = 191; aithos.GuildName = ""; aithos.X = 432377; aithos.Y = 543728; aithos.Z = 8334; aithos.RoamingRange = 0; aithos.RespawnInterval = 0; aithos.BodyType = 0; AithosBrain abrain = new AithosBrain(); abrain.AggroLevel = 100; abrain.AggroRange = 350; aithos.SetOwnBrain(abrain); aithos.AddToWorld(); BossList.Add(aithos); Aith = aithos; GameEventMgr.AddHandler(aithos, GameNPCEvent.Dying, new DOLEventHandler(Ianetor.AithosHasDied)); //Make sure there are not too many players on the island when the encounter starts, if there is too many players //sick the stairgards on them. List <GamePlayer> islandplayers = new List <GamePlayer>(); foreach (GamePlayer foundplayer in (Aith.GetPlayersInRadius((ushort)2300))) { islandplayers.Add(foundplayer); } if (islandplayers.Count > 8) { EncounterMgr.BroadcastMsg(Aith, "You can not have more then one full group of players on the island, you must all die for your mistake!", 2300, true); EncounterMgr.BroadcastMsg(Aith, "Guards!!!!!!!!!!!", 2300, true); foreach (GameNPC stairgard in StairGuardList) { IOldAggressiveBrain aggroBrain = stairgard.Brain as IOldAggressiveBrain; foreach (GamePlayer foundplayer in islandplayers) { if (aggroBrain != null && (GameServer.ServerRules.IsAllowedToAttack(stairgard, foundplayer, true))) { aggroBrain.AddToAggroList(foundplayer, Util.Random(50, 100)); } } } } return; }
public override void DamageTarget(AttackData ad, bool showEffectAnimation) { InventoryItem weapon = null; weapon = ad.Weapon; if (showEffectAnimation && ad.Target != null) { byte resultByte = 0; int attackersWeapon = (weapon == null) ? 0 : weapon.Model; int defendersWeapon = 0; switch (ad.AttackResult) { case GameLiving.eAttackResult.Missed: resultByte = 0; break; case GameLiving.eAttackResult.Evaded: resultByte = 3; break; case GameLiving.eAttackResult.Fumbled: resultByte = 4; break; case GameLiving.eAttackResult.HitUnstyled: resultByte = 10; break; case GameLiving.eAttackResult.HitStyle: resultByte = 11; break; case GameLiving.eAttackResult.Parried: resultByte = 1; if (ad.Target != null && ad.Target.AttackWeapon != null) { defendersWeapon = ad.Target.AttackWeapon.Model; } break; case GameLiving.eAttackResult.Blocked: resultByte = 2; if (ad.Target != null && ad.Target.Inventory != null) { InventoryItem lefthand = ad.Target.Inventory.GetItem(eInventorySlot.LeftHandWeapon); if (lefthand != null && lefthand.Object_Type == (int)eObjectType.Shield) { defendersWeapon = lefthand.Model; } } break; } foreach (GamePlayer player in ad.Target.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { if (player == null) { continue; } int animationId; switch (ad.AnimationId) { case -1: animationId = player.Out.OneDualWeaponHit; break; case -2: animationId = player.Out.BothDualWeaponHit; break; default: animationId = ad.AnimationId; break; } //We don't need to send the animiation for the throwning, thats been done earlier. //this is for the defender, which should show the appropriate animation player.Out.SendCombatAnimation(null, ad.Target, (ushort)attackersWeapon, (ushort)defendersWeapon, animationId, 0, resultByte, ad.Target.HealthPercent); } } // send animation before dealing damage else dead livings show no animation ad.Target.OnAttackedByEnemy(ad); ad.Attacker.DealDamage(ad); if (ad.Damage == 0 && ad.Target is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)ad.Target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(Caster, 1); } } }
/// <summary> /// Called on every timer tick /// </summary> protected override void OnTick() { GameLiving target = m_boltTarget; GameLiving caster = (GameLiving)m_actionSource; if (target == null) { return; } if (target.CurrentRegionID != caster.CurrentRegionID) { return; } if (target.ObjectState != GameObject.eObjectState.Active) { return; } if (!target.IsAlive) { return; } // Related to PvP hitchance // http://www.camelotherald.com/news/news_article.php?storyid=2444 // No information on bolt hitchance against npc's // Bolts are treated as physical attacks for the purpose of ABS only // Based on this I am normalizing the miss rate for npc's to be that of a standard spell int missrate = 0; if (caster is GamePlayer && target is GamePlayer) { if (target.InCombat) { foreach (GameLiving attacker in target.Attackers) { if (attacker != caster && target.GetDistanceTo(attacker) <= 200) { // each attacker within 200 units adds a 20% chance to miss missrate += 20; } } } } if (target is GameNPC || caster is GameNPC) { missrate += (int)(ServerProperties.Properties.PVE_SPELL_CONHITPERCENT * caster.GetConLevel(target)); } // add defence bonus from last executed style if any AttackData targetAD = (AttackData)target.TempProperties.getProperty <object>(GameLiving.LAST_ATTACK_DATA, null); if (targetAD != null && targetAD.AttackResult == GameLiving.eAttackResult.HitStyle && targetAD.Style != null) { missrate += targetAD.Style.BonusToDefense; } AttackData ad = m_handler.CalculateDamageToTarget(target, 0.5 - (caster.GetModified(eProperty.SpellDamage) * 0.01)); if (Util.Chance(missrate)) { ad.AttackResult = GameLiving.eAttackResult.Missed; m_handler.MessageToCaster("You miss!", eChatType.CT_YouHit); m_handler.MessageToLiving(target, caster.GetName(0, false) + " missed!", eChatType.CT_Missed); target.OnAttackedByEnemy(ad); target.StartInterruptTimer(target.SpellInterruptDuration, ad.AttackType, caster); if (target is GameNPC) { IOldAggressiveBrain aggroBrain = ((GameNPC)target).Brain as IOldAggressiveBrain; if (aggroBrain != null) { aggroBrain.AddToAggroList(caster, 1); } } return; } ad.Damage = (int)((double)ad.Damage * (1.0 + caster.GetModified(eProperty.SpellDamage) * 0.01)); // Block bool blocked = false; if (target is GamePlayer) { // mobs left out yet GamePlayer player = (GamePlayer)target; InventoryItem lefthand = player.Inventory.GetItem(eInventorySlot.LeftHandWeapon); if (lefthand != null && (player.AttackWeapon == null || player.AttackWeapon.Item_Type == Slot.RIGHTHAND || player.AttackWeapon.Item_Type == Slot.LEFTHAND)) { if (target.IsObjectInFront(caster, 180) && lefthand.Object_Type == (int)eObjectType.Shield) { double shield = 0.5 * player.GetModifiedSpecLevel(Specs.Shields); double blockchance = ((player.Dexterity * 2) - 100) / 40.0 + shield + 5; // Removed 30% increased chance to block, can find no clear evidence this is correct - tolakram blockchance -= target.GetConLevel(caster) * 5; if (blockchance >= 100) { blockchance = 99; } if (blockchance <= 0) { blockchance = 1; } if (target.IsEngaging) { EngageEffect engage = target.EffectList.GetOfType <EngageEffect>(); if (engage != null && target.AttackState && engage.EngageTarget == caster) { // Engage raised block change to 85% if attacker is engageTarget and player is in attackstate // You cannot engage a mob that was attacked within the last X seconds... if (engage.EngageTarget.LastAttackedByEnemyTick > engage.EngageTarget.CurrentRegion.Time - EngageAbilityHandler.ENGAGE_ATTACK_DELAY_TICK) { if (engage.Owner is GamePlayer) { (engage.Owner as GamePlayer).Out.SendMessage(engage.EngageTarget.GetName(0, true) + " has been attacked recently and you are unable to engage.", eChatType.CT_System, eChatLoc.CL_SystemWindow); } } // Check if player has enough endurance left to engage else if (engage.Owner.Endurance < EngageAbilityHandler.ENGAGE_DURATION_LOST) { engage.Cancel(false); // if player ran out of endurance cancel engage effect } else { engage.Owner.Endurance -= EngageAbilityHandler.ENGAGE_DURATION_LOST; if (engage.Owner is GamePlayer) { (engage.Owner as GamePlayer).Out.SendMessage("You concentrate on blocking the blow!", eChatType.CT_Skill, eChatLoc.CL_SystemWindow); } if (blockchance < 85) { blockchance = 85; } } } } if (blockchance >= Util.Random(1, 100)) { m_handler.MessageToLiving(player, "You partially block " + caster.GetName(0, false) + "'s spell!", eChatType.CT_Missed); m_handler.MessageToCaster(player.GetName(0, true) + " blocks!", eChatType.CT_YouHit); blocked = true; } } } } double effectiveness = 1.0 + (caster.GetModified(eProperty.SpellDamage) * 0.01); // simplified melee damage calculation if (blocked == false) { // TODO: armor resists to damage type double damage = m_handler.Spell.Damage / 2; // another half is physical damage if (target is GamePlayer) { ad.ArmorHitLocation = ((GamePlayer)target).CalculateArmorHitLocation(ad); } InventoryItem armor = null; if (target.Inventory != null) { armor = target.Inventory.GetItem((eInventorySlot)ad.ArmorHitLocation); } double ws = (caster.Level * 8 * (1.0 + (caster.GetModified(eProperty.Dexterity) - 50) / 200.0)); damage *= ((ws + 90.68) / (target.GetArmorAF(ad.ArmorHitLocation) + 20 * 4.67)); damage *= 1.0 - Math.Min(0.85, ad.Target.GetArmorAbsorb(ad.ArmorHitLocation)); ad.Modifier = (int)(damage * (ad.Target.GetResist(ad.DamageType) + SkillBase.GetArmorResist(armor, ad.DamageType)) / -100.0); damage += ad.Modifier; damage = damage * effectiveness; damage *= (1.0 + RelicMgr.GetRelicBonusModifier(caster.Realm, eRelicType.Magic)); if (damage < 0) { damage = 0; } ad.Damage += (int)damage; } if (m_handler is SiegeArrow == false) { ad.UncappedDamage = ad.Damage; ad.Damage = (int)Math.Min(ad.Damage, m_handler.DamageCap(effectiveness)); } ad.Damage = (int)(ad.Damage * caster.Effectiveness); if (blocked == false && ad.CriticalDamage > 0) { int critMax = (target is GamePlayer) ? ad.Damage / 2 : ad.Damage; ad.CriticalDamage = Util.Random(critMax / 10, critMax); } m_handler.SendDamageMessages(ad); m_handler.DamageTarget(ad, false, (blocked ? 0x02 : 0x14)); target.StartInterruptTimer(target.SpellInterruptDuration, ad.AttackType, caster); }