private static void WriteUnitDynFlags(ObjectBase obj, Character receiver, UpdatePacket packet) { Unit unit = (Unit)obj; UnitDynamicFlags dynamicFlags = unit.DynamicFlags; Asda2Loot loot = obj.Loot; if (loot != null && receiver.LooterEntry.MayLoot(loot) && !unit.IsAlive) { dynamicFlags |= UnitDynamicFlags.Lootable; } else { Unit firstAttacker = unit.FirstAttacker; if (firstAttacker != null) { if ((firstAttacker == receiver || firstAttacker.IsAlliedWith(receiver)) && unit.IsAlive) { dynamicFlags |= UnitDynamicFlags.TaggedByMe; } else { dynamicFlags |= UnitDynamicFlags.TaggedByOther; } } } packet.Write((uint)dynamicFlags); }
/// <summary> /// Whether the given lootable contains quest items for the given Character when looting with the given type /// </summary> public static bool ContainsQuestItemsFor(this IAsda2Lootable lootable, Character chr, Asda2LootEntryType type) { Asda2Loot loot = lootable.Loot; if (loot != null) { return(((IEnumerable <Asda2LootItem>)loot.Items).Any <Asda2LootItem>((Func <Asda2LootItem, bool>)(item => { if (item.Template.HasQuestRequirements) { return item.Template.CheckQuestConstraints(chr); } return false; }))); } List <Asda2LootItemEntry> entries = lootable.GetEntries(type); if (entries != null) { return(entries.Any <Asda2LootItemEntry>((Func <Asda2LootItemEntry, bool>)(entry => { if (entry.ItemTemplate.HasQuestRequirements) { return entry.ItemTemplate.CheckQuestConstraints(chr); } return false; }))); } return(false); }
/// <summary> /// Returns whether this Looter is entitled to loot anything from the given loot /// </summary> public bool MayLoot(Asda2Loot loot) { return(this.m_owner != null && (loot.Looters.Count == 0 || loot.Looters.Contains(this) || this.m_owner.GodMode || loot.Group != null && this.m_owner.Group == loot.Group && (loot.FreelyAvailableCount > 0 || this.m_owner.GroupMember == loot.Group.MasterLooter))); }
/// <summary>Requires loot to already be generated</summary> /// <param name="lootable"></param> public void TryLoot(IAsda2Lootable lootable) { this.Release(); Asda2Loot loot = lootable.Loot; if (loot == null || !this.MayLoot(loot)) { return; } this.m_owner.CancelAllActions(); this.Loot = loot; }
/// <summary> /// Gold is given automatically in group-looting. Client can only request gold when looting alone. /// </summary> public static void HandleLootMoney(IRealmClient client, RealmPacketIn packet) { Character activeCharacter = client.ActiveCharacter; Asda2LooterEntry looterEntry = activeCharacter.LooterEntry; activeCharacter.SpellCast.Cancel(SpellFailedReason.Interrupted); Asda2Loot loot = looterEntry.Loot; if (loot == null) { return; } loot.GiveMoney(); }
/// <summary> /// Releases the current loot and (maybe) makes it available to everyone else. /// </summary> public void Release() { if (this.m_loot == null) { return; } Character owner = this.m_owner; this.m_loot.RemoveLooter(this); if (this.m_loot.Looters.Count == 0) { this.m_loot.IsReleased = true; } this.Loot = (Asda2Loot)null; }
/// <summary> /// Returns whether this Looter is entitled to loot anything from the given loot /// </summary> public bool MayLoot(Asda2Loot loot) { if (m_owner == null) { return(false); } if (((loot.Looters.Count == 0 || loot.Looters.Contains(this))) || // we are one of the initial looters OR: m_owner.GodMode || (loot.Group != null && m_owner.Group == loot.Group && ( // we are part of the group AND: (loot.FreelyAvailableCount > 0) || // there are freely available items or m_owner.GroupMember == loot.Group.MasterLooter))) // this is the MasterLooter { return(true); } return(false); }
/// <summary> /// Releases the current loot and (maybe) makes it available to everyone else. /// </summary> public void Release() { if (m_loot != null) { if (m_owner != null) { //LootHandler.SendLootReleaseResponse(m_owner, m_loot); } m_loot.RemoveLooter(this); if (m_loot.Looters.Count == 0) { // last looter released m_loot.IsReleased = true; } Loot = null; } }
/// <summary> /// Generates normal loot (usually for dead mob-corpses). /// Returns null, if the loot is empty. /// </summary> /// <param name="lootable">The Object or Unit that is being looted</param> public static Asda2Loot GetOrCreateLoot(IAsda2Lootable lootable, Character triggerChar, Asda2LootEntryType type) { Asda2Loot loot = lootable.Loot; if (loot != null) { if (loot.IsMoneyLooted && loot.RemainingCount == 0) { return((Asda2Loot)null); } loot.Looters.Clear(); } else { lootable.Loot = loot = (Asda2Loot)Asda2LootMgr.CreateLoot <Asda2NPCLoot>(lootable, triggerChar, type, MapId.Silaris); } return(loot); }
/// <summary>Generates loot for Items and GOs.</summary> /// <param name="lootable">The Object or Unit that is being looted</param> /// <returns>The object's loot or null if there is nothing to get or the given Character can't access the loot.</returns> public static Asda2ObjectLoot CreateAndSendObjectLoot(IAsda2Lootable lootable, Character initialLooter, Asda2LootEntryType type) { Asda2Loot loot1 = initialLooter.LooterEntry.Loot; if (loot1 != null) { loot1.ForceDispose(); } IList <Asda2LooterEntry> looters = Asda2LootMgr.FindLooters(lootable, initialLooter); Asda2ObjectLoot loot2 = Asda2LootMgr.CreateLoot <Asda2ObjectLoot>(lootable, initialLooter, type, MapId.Silaris); if (loot2 != null) { initialLooter.LooterEntry.Loot = (Asda2Loot)loot2; loot2.Initialize(initialLooter, looters, MapId.Silaris); } return(loot2); }
/// <summary> /// Requires loot to already be generated /// </summary> /// <param name="lootable"></param> public void TryLoot(IAsda2Lootable lootable) { Release(); // make sure that the Character is not still looting something else var loot = lootable.Loot; if (loot == null) { //LootHandler.SendLootFail(m_owner, lootable); // TODO: Kneel and unkneel? } else if (MayLoot(loot)) { // we are either already a looter or become a new one m_owner.CancelAllActions(); Loot = loot; //LootHandler.SendLootResponse(m_owner, loot); } else { //LootHandler.SendLootFail(m_owner, lootable); } }
protected override void OnDeath() { if (m_brain != null) { m_brain.IsRunning = false; } if (m_Map != null || this != null) { var rcvrs = this.GetNearbyClients(false); var looter = CalcLooter(); Asda2Loot loot = null; if (looter != null && m_Map.DefenceTownEvent == null) { loot = Asda2LootMgr.GetOrCreateLoot(this, looter, Asda2LootEntryType.Npc); if (loot != null && Template != null) { loot.MonstrId = (short?)Template.Id; } } Loot = null; var map = m_Map; m_Map.CallDelayed(LastDamageDelay, () => { Asda2CombatHandler.SendMostrDeadToAreaResponse(rcvrs, (short) UniqIdOnMap, (short) Asda2Position. X, (short) Asda2Position. Y); map.OnNPCDied(this); var chr = LastKiller as Character; if (chr != null) { Asda2TitleChecker.OnNpcDeath(this, chr); if (chr.IsInGroup) { chr.Group.ForeachCharacter(x => KillMonsterEventManager.TryGiveReward(x, Template.Id)); } else { KillMonsterEventManager.TryGiveReward(chr, Template.Id); } } if (loot != null && loot.Lootable is NPC) { var npc = ((NPC)loot.Lootable); if (npc != null && npc.Map != null) { npc.Map.SpawnLoot(loot); } } if (m_entry != null && Entry != null && Template != null) { if (Entry.Rank >= CreatureRank.Boss) { if (LastKiller != null) { ChatMgr.SendGlobalMessageResponse(LastKiller.Name, ChatMgr.Asda2GlobalMessageType .HasDefeated, 0, 0, (short)Template.Id); } if (chr != null) { chr.GuildPoints += m_entry.MinLevel * CharacterFormulas.BossKillingGuildPointsPerLevel; } } else { if (chr != null && chr.Level < m_entry.MinLevel + 3) { chr.GuildPoints += CharacterFormulas.MobKillingGuildPoints; } } // notify events m_entry.NotifyDied(this); } EnterFinalState(); }); } //UnitFlags |= UnitFlags.SelectableNotAttackable; // send off the tamer if (m_currentTamer != null) { PetHandler.SendTameFailure(m_currentTamer, TameFailReason.TargetDead); CurrentTamer.SpellCast.Cancel(SpellFailedReason.Ok); } // reset spawn timer if (m_spawnPoint != null) { m_spawnPoint.SignalSpawnlingDied(this); } }