diff options
| author | Vincent-Michael <Vincent_Michael@gmx.de> | 2014-06-27 19:39:23 +0200 |
|---|---|---|
| committer | Vincent-Michael <Vincent_Michael@gmx.de> | 2014-06-27 19:39:23 +0200 |
| commit | f3de6f028403b6b6eb59b8cb59cb15419ea47932 (patch) | |
| tree | 0b391c0e5c2c344bfb661e42cbd8a680735c9f8e /src/server/game | |
| parent | a2b860b7814ca216565a432e07579dd77f004a86 (diff) | |
| parent | 52023b1e6b1fefaf4be95fa201fc1dd2ecca55a7 (diff) | |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 45 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 29 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 12 | ||||
| -rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Handlers/LootHandler.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/Handlers/MailHandler.cpp | 7 | ||||
| -rw-r--r-- | src/server/game/Loot/LootMgr.h | 3 | ||||
| -rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 22 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 18 |
11 files changed, 76 insertions, 78 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index fbbea8b38c4..d1148f6cfb2 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -142,8 +142,8 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) } Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), -lootForPickPocketed(false), _pickpocketLootRestore(0), lootForBody(false), lootForSkinned(false), _skinner(0), m_groupLootTimer(0), lootingGroupLowGUID(0), -m_PlayerDamageReq(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0), +_pickpocketLootRestore(0), m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0), +m_lootRecipient(0), m_lootRecipientGroup(0), _skinner(0), m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), @@ -551,9 +551,9 @@ void Creature::Update(uint32 diff) time_t now = time(NULL); // Check if we should refill the pickpocketing loot - if (lootForPickPocketed && _pickpocketLootRestore && _pickpocketLootRestore <= now) + if (loot.loot_type == LOOT_PICKPOCKETING && _pickpocketLootRestore && _pickpocketLootRestore <= now) { - lootForPickPocketed = false; + loot.clear(); _pickpocketLootRestore = 0; } @@ -1485,11 +1485,6 @@ void Creature::setDeathState(DeathState s) setActive(false); - if (!IsPet() && GetCreatureTemplate()->SkinLootId) - if (LootTemplates_Skinning.HaveLootFor(GetCreatureTemplate()->SkinLootId)) - if (hasLootRecipient()) - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - if (HasSearchedAssistance()) { SetNoSearchAssistance(false); @@ -1548,9 +1543,7 @@ void Creature::Respawn(bool force) GetName().c_str(), GetGUIDLow(), GetGUID(), GetEntry()); m_respawnTime = 0; _pickpocketLootRestore = 0; - lootForPickPocketed = false; - lootForBody = false; - lootForSkinned = false; + loot.clear(); if (m_originalEntry != GetEntry()) UpdateEntry(m_originalEntry); @@ -2284,23 +2277,23 @@ void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, floa void Creature::AllLootRemovedFromCorpse() { - if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE)) - { - time_t now = time(NULL); - if (m_corpseRemoveTime <= now) - return; + if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient()) + if (LootTemplates_Skinning.HaveLootFor(GetCreatureTemplate()->SkinLootId)) + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - float decayRate = sWorld->getRate(RATE_CORPSE_DECAY_LOOTED); - CreatureTemplate const* cinfo = GetCreatureTemplate(); + time_t now = time(NULL); + if (m_corpseRemoveTime <= now) + return; - // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update - if (cinfo && cinfo->SkinLootId) - m_corpseRemoveTime = time(NULL); - else - m_corpseRemoveTime = now + m_corpseDelay * decayRate; + float decayRate = sWorld->getRate(RATE_CORPSE_DECAY_LOOTED); - m_respawnTime = m_corpseRemoveTime + m_respawnTime; - } + // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update + if (loot.loot_type == LOOT_SKINNING) + m_corpseRemoveTime = time(NULL); + else + m_corpseRemoveTime = now + m_corpseDelay * decayRate; + + m_respawnTime = m_corpseRemoveTime + m_respawnTime; } uint8 Creature::getLevelForTarget(WorldObject const* target) const diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 85850170603..86fafb330a7 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -548,9 +548,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject virtual void DeleteFromDB(); // overriden in Pet Loot loot; - bool lootForPickPocketed; - bool lootForBody; - bool lootForSkinned; void StartPickPocketRefillTimer(); void ResetPickPocketRefillTimer() { _pickpocketLootRestore = 0; } void SetSkinner(uint64 guid) { _skinner = guid; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e1a1b367b7b..cf6e94328b7 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9182,9 +9182,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type) if (loot_type == LOOT_PICKPOCKETING) { - if (!creature->lootForPickPocketed) + if (loot->loot_type != LOOT_PICKPOCKETING) { - creature->lootForPickPocketed = true; creature->StartPickPocketRefillTimer(); loot->clear(); @@ -9205,12 +9204,9 @@ void Player::SendLoot(uint64 guid, LootType loot_type) if (!recipient) return; - if (!creature->lootForBody) + if (loot->loot_type == LOOT_NONE) { - creature->lootForBody = true; - // for creature, loot is filled when creature is killed. - if (Group* group = recipient->GetGroup()) { switch (group->GetLootMethod()) @@ -9231,15 +9227,17 @@ void Player::SendLoot(uint64 guid, LootType loot_type) } } - // possible only if creature->lootForBody && loot->empty() at spell cast check - if (loot_type == LOOT_SKINNING) + // if loot is already skinning loot then don't do anything else + if (loot->loot_type == LOOT_SKINNING) { - if (!creature->lootForSkinned) - { - creature->lootForSkinned = true; - loot->clear(); - loot->FillLoot(creature->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, this, true); - } + loot_type = LOOT_SKINNING; + permission = creature->GetSkinner() == GetGUID() ? OWNER_PERMISSION : NONE_PERMISSION; + } + else if (loot_type == LOOT_SKINNING) + { + loot->clear(); + loot->FillLoot(creature->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, this, true); + creature->SetSkinner(GetGUID()); permission = OWNER_PERMISSION; } // set group rights only for loot_type != LOOT_SKINNING @@ -17978,6 +17976,9 @@ bool Player::isAllowedToLoot(const Creature* creature) if (loot->isLooted()) // nothing to loot or everything looted. return false; + if (loot->loot_type == LOOT_SKINNING) + return creature->GetSkinner() == GetGUID(); + Group* thisGroup = GetGroup(); if (!thisGroup) return this == creature->GetLootRecipient(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e4eca6b970b..6c66e900be7 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13669,11 +13669,8 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (creature) { Loot* loot = &creature->loot; - if (creature->lootForPickPocketed) - { + if (creature->loot.loot_type == LOOT_PICKPOCKETING) creature->ResetPickPocketRefillTimer(); - creature->lootForPickPocketed = false; - } loot->clear(); if (uint32 lootid = creature->GetCreatureTemplate()->lootid) @@ -13794,9 +13791,12 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (!creature->IsPet()) { creature->DeleteThreatList(); - CreatureTemplate const* cInfo = creature->GetCreatureTemplate(); - if (cInfo && (cInfo->lootid || cInfo->maxgold > 0)) + + // must be after setDeathState which resets dynamic flags + if (!creature->loot.empty()) creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + else + creature->AllLootRemovedFromCorpse(); } // Call KilledUnit for creatures, this needs to be called after the lootable flag is set diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 70547136bf8..70e01238663 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -775,9 +775,9 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData) std::string IP_str = GetRemoteAddress(); TC_LOG_INFO("entities.player.character", "Account: %d, IP: %s deleted character: %s, GUID: %u, Level: %u", accountId, IP_str.c_str(), name.c_str(), GUID_LOPART(guid), level); - + // To prevent hook failure, place hook before removing reference from DB - sScriptMgr->OnPlayerDelete(guid, initAccountId); // To prevent race conditioning, but as it also makes sense, we hand the accountId over for successful delete. + sScriptMgr->OnPlayerDelete(guid, initAccountId); // To prevent race conditioning, but as it also makes sense, we hand the accountId over for successful delete. // Shouldn't interfere with character deletion though if (sLog->ShouldLog("entities.player.dump", LOG_LEVEL_INFO)) // optimize GetPlayerDump call diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index a4fde51b498..7c3d9e99eee 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -82,7 +82,7 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData) { Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid); - bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed); + bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) { @@ -149,7 +149,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) case HIGHGUID_VEHICLE: { Creature* creature = player->GetMap()->GetCreature(guid); - bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed); + bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; @@ -357,7 +357,7 @@ void WorldSession::DoLootRelease(uint64 lguid) { Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid); - bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed); + bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) return; @@ -365,9 +365,6 @@ void WorldSession::DoLootRelease(uint64 lguid) if (loot->isLooted()) { creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - - if (loot->loot_type == LOOT_SKINNING) - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact if (!creature->IsAlive()) diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 536d6a7dc95..3c4e5feb771 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -181,6 +181,13 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) uint64 reqmoney = cost + money; + // Check for overflow + if (reqmoney < money) + { + player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); + return; + } + if (!player->HasEnoughMoney(reqmoney) && !player->IsGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 9be745e622d..cb3b9082c20 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -76,6 +76,8 @@ enum PermissionTypes enum LootType { + LOOT_NONE = 0, + LOOT_CORPSE = 1, LOOT_PICKPOCKETING = 2, LOOT_FISHING = 3, @@ -341,6 +343,7 @@ struct Loot gold = 0; unlootedCount = 0; roundRobinPlayer = 0; + loot_type = LOOT_NONE; i_LootValidatorRefManager.clearReferences(); } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 475e8ee3fa8..22b2d58585c 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -2987,7 +2987,7 @@ enum CreatureTypeFlags CREATURE_TYPEFLAGS_EXOTIC = 0x00010000, // Can be tamed by hunter as exotic pet CREATURE_TYPEFLAGS_UNK17 = 0x00020000, // ? Related to vehicles/pvp? CREATURE_TYPEFLAGS_UNK18 = 0x00040000, // ? Related to vehicle/siege weapons? - CREATURE_TYPEFLAGS_UNK19 = 0x00080000, + CREATURE_TYPEFLAGS_PROJECTILE_COLLISION = 0x00080000, // Projectiles can collide with this creature - interacts with TARGET_DEST_TRAJ CREATURE_TYPEFLAGS_UNK20 = 0x00100000, CREATURE_TYPEFLAGS_UNK21 = 0x00200000, CREATURE_TYPEFLAGS_UNK22 = 0x00400000, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 2a01a8046ed..56ae9061033 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1507,10 +1507,24 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) std::list<WorldObject*>::const_iterator itr = targets.begin(); for (; itr != targets.end(); ++itr) { + if (!m_caster->HasInLine(*itr, 5.0f)) + continue; + + if (m_spellInfo->CheckTarget(m_caster, *itr, true) != SPELL_CAST_OK) + continue; + if (Unit* unitTarget = (*itr)->ToUnit()) - if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster)) + { + if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || unitTarget->GetVehicle()) continue; + if (Creature* creatureTarget = unitTarget->ToCreature()) + { + if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PROJECTILE_COLLISION)) + continue; + } + } + const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3) /// @todo all calculation should be based on src instead of m_caster const float objDist2d = m_targets.GetSrcPos()->GetExactDist2d(*itr) * std::cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)); @@ -5120,13 +5134,11 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_TARGET_UNSKINNABLE; Creature* creature = m_targets.GetUnitTarget()->ToCreature(); - if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && creature->loot.loot_type != LOOT_SKINNING && !creature->loot.isLooted()) + if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && !creature->loot.isLooted()) return SPELL_FAILED_TARGET_NOT_LOOTED; uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill(); - bool alreadySkinned = creature->loot.loot_type == LOOT_SKINNING && creature->GetSkinner() == m_caster->GetGUID(); - int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill); int32 TargetLevel = m_targets.GetUnitTarget()->getLevel(); int32 ReqValue = (skillValue < 100 ? (TargetLevel-10) * 10 : TargetLevel * 5); @@ -5136,7 +5148,7 @@ SpellCastResult Spell::CheckCast(bool strict) // chance for fail at orange skinning attempt if ((m_selfContainer && (*m_selfContainer) == this) && skillValue < sWorld->GetConfigMaxSkillValue() && - (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37) && !alreadySkinned) + (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37)) return SPELL_FAILED_TRY_AGAIN; break; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 8d8abc9eb36..ebd0a269223 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4435,28 +4435,16 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/) uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill(); - bool awardPoints = true; - - // Check if a skinning loot table was already generated for this creature - if (creature->loot.loot_type == LOOT_SKINNING) - { - if (creature->GetSkinner() != m_caster->GetGUID()) - return; - - awardPoints = false; // Do not grant skill points for this loot, they were already granted the first time. - } - else - creature->SetSkinner(m_caster->GetGUID()); - m_caster->ToPlayer()->SendLoot(creature->GetGUID(), LOOT_SKINNING); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel-10)*10 : targetLevel*5; int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill); // Double chances for elites - if (awardPoints) - m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1); + m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1); } void Spell::EffectCharge(SpellEffIndex /*effIndex*/) |
