diff options
author | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-02-13 21:48:09 +0100 |
---|---|---|
committer | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-02-13 21:48:09 +0100 |
commit | 3c5bf554ffa58e46eb88aebd46af21335d581432 (patch) | |
tree | ce6d5856921406bf4be4effdbf8873a9c1419bb5 /src | |
parent | d292b05ac1fb04be23161072a7386d7f44905fe1 (diff) | |
parent | ca280dbe051f2d9c43bbda128a6aa6bc19d8149f (diff) |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Loot/LootMgr.cpp | 30 | ||||
-rw-r--r-- | src/server/game/Loot/LootMgr.h | 3 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 7 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.h | 2 | ||||
-rwxr-xr-x | src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Movement/PathGenerator.h | 4 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MoveSplineInit.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 3 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_mmaps.cpp | 2 |
13 files changed, 64 insertions, 41 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 0157cdf9130..fd87054b2d8 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -289,6 +289,10 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data --diff; } + // Initialize loot duplicate count depending on raid difficulty + if (GetMap()->IsRaid() && GetMap()->GetSpawnMode() & RAID_DIFFICULTY_MASK_25MAN) + loot.maxDuplicates = 3; + SetEntry(Entry); // normal entry always m_creatureInfo = cinfo; // map mode related always diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index a837f2313e8..7f9e317c2d2 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -259,6 +259,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa LastUsedScriptID = GetGOInfo()->ScriptId; AIM_Initialize(); + // Initialize loot duplicate count depending on raid difficulty + if (map->IsRaid() && map->GetSpawnMode() & RAID_DIFFICULTY_MASK_25MAN) + loot.maxDuplicates = 3; + return true; } diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 94aea40f511..232dbc1e186 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -52,16 +52,27 @@ LootStore LootTemplates_Reference("reference_loot_template", "reference LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true); LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false); -struct NotMatchingLootMode : public std::unary_function<LootStoreItem*, bool> +// Selects invalid loot items to be removed from group possible entries (before rolling) +struct LootGroupInvalidSelector : public std::unary_function<LootStoreItem*, bool> { - explicit NotMatchingLootMode(uint16 lootMode) : _lootMode(lootMode) { } + explicit LootGroupInvalidSelector(Loot const& loot, uint16 lootMode) : _loot(loot), _lootMode(lootMode) { } bool operator()(LootStoreItem* item) const { - return !(item->lootmode & _lootMode); + if (!(item->lootmode & _lootMode)) + return true; + + uint8 foundDuplicates = 0; + for (std::vector<LootItem>::const_iterator itr = _loot.items.begin(); itr != _loot.items.end(); ++itr) + if (itr->itemid == item->itemid) + if (++foundDuplicates == _loot.maxDuplicates) + return true; + + return false; } private: + Loot const& _loot; uint16 _lootMode; }; @@ -89,7 +100,7 @@ class LootTemplate::LootGroup // A set of loot def LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance - LootStoreItem const* Roll(uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances + LootStoreItem const* Roll(Loot& loot, uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances // This class must never be copied - storing pointers LootGroup(LootGroup const&); @@ -1080,10 +1091,10 @@ void LootTemplate::LootGroup::AddEntry(LootStoreItem* item) } // Rolls an item from the group, returns NULL if all miss their chances -LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode) const +LootStoreItem const* LootTemplate::LootGroup::Roll(Loot& loot, uint16 lootMode) const { LootStoreItemList possibleLoot = ExplicitlyChanced; - possibleLoot.remove_if(NotMatchingLootMode(lootMode)); + possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode)); if (!possibleLoot.empty()) // First explicitly chanced entries are checked { @@ -1102,7 +1113,7 @@ LootStoreItem const* LootTemplate::LootGroup::Roll(uint16 lootMode) const } possibleLoot = EqualChanced; - possibleLoot.remove_if(NotMatchingLootMode(lootMode)); + possibleLoot.remove_if(LootGroupInvalidSelector(loot, lootMode)); if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part return Trinity::Containers::SelectRandomContainerElement(possibleLoot); @@ -1149,7 +1160,7 @@ void LootTemplate::LootGroup::CopyConditions(ConditionList /*conditions*/) // Rolls an item from the group (if any takes its chance) and adds the item to the loot void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode) const { - if (LootStoreItem const* item = Roll(lootMode)) + if (LootStoreItem const* item = Roll(loot, lootMode)) loot.AddItem(*item); } @@ -1289,7 +1300,7 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId for (LootStoreItemList::const_iterator i = Entries.begin(); i != Entries.end(); ++i) { LootStoreItem* item = *i; - if (item->lootmode &~ lootMode) // Do not add if mode mismatch + if (!(item->lootmode & lootMode)) // Do not add if mode mismatch continue; if (!item->Roll(rate)) @@ -1298,7 +1309,6 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId if (item->mincountOrRef < 0) // References processing { LootTemplate const* Referenced = LootTemplates_Reference.GetLootFor(-item->mincountOrRef); - if (!Referenced) continue; // Error message already printed at loading stage diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 7474fc87a71..d338f6f503b 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -297,12 +297,13 @@ struct Loot uint8 unlootedCount; uint64 roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released. LootType loot_type; // required for achievement system + uint8 maxDuplicates; // Max amount of items with the same entry that can drop (default is 1; on 25 man raid mode 3) // GUIDLow of container that holds this loot (item_instance.entry) // Only set for inventory items that can be right-click looted uint32 containerID; - Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE), containerID(0) {} + Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE), maxDuplicates(1), containerID(0) {} ~Loot() { clear(); } // For deleting items at loot removal since there is no backward interface to the Item() diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 3a061910faa..514a59894b0 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3438,7 +3438,12 @@ enum SummonType enum EventId { EVENT_CHARGE = 1003, - EVENT_JUMP = 1004 + EVENT_JUMP = 1004, + + /// Special charge event which is used for charge spells that have explicit targets + /// and had a path already generated - using it in PointMovementGenerator will not + /// create a new spline and launch it + EVENT_CHARGE_PREPATH = 1005 }; enum ResponseCodes diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index c9ca7772186..8e045b98dbb 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -424,15 +424,16 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, } } -void MotionMaster::MoveCharge(PathGenerator path, float speed, uint32 id) +void MotionMaster::MoveCharge(PathGenerator const& path) { Vector3 dest = path.GetActualEndPosition(); - MoveCharge(dest.x, dest.y, dest.z, speed, id); + MoveCharge(dest.x, dest.y, dest.z, SPEED_CHARGE, EVENT_CHARGE_PREPATH); + // Charge movement is not started when using EVENT_CHARGE_PREPATH Movement::MoveSplineInit init(_owner); init.MovebyPath(path.GetPath()); - init.SetVelocity(speed); + init.SetVelocity(SPEED_CHARGE); init.Launch(); } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 4b6075aac10..f2f3959dba5 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -162,7 +162,7 @@ class MotionMaster //: private std::stack<MovementGenerator *> void MoveTakeoff(uint32 id, Position const& pos); void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false); - void MoveCharge(PathGenerator path, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE); + void MoveCharge(PathGenerator const& path); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = EVENT_JUMP) diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 1f5503948c8..ea7a8c4c710 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -34,7 +34,7 @@ void PointMovementGenerator<T>::DoInitialize(T* unit) unit->AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); - if (id == EVENT_CHARGE) + if (id == EVENT_CHARGE_PREPATH) return; Movement::MoveSplineInit init(unit); @@ -58,7 +58,7 @@ bool PointMovementGenerator<T>::DoUpdate(T* unit, uint32 /*diff*/) unit->AddUnitState(UNIT_STATE_ROAMING_MOVE); - if (id != EVENT_CHARGE && i_recalculateSpeed && !unit->movespline->Finalized()) + if (id != EVENT_CHARGE_PREPATH && i_recalculateSpeed && !unit->movespline->Finalized()) { i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index a20f900b584..d41d3160db5 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -55,7 +55,7 @@ enum PathType class PathGenerator { public: - PathGenerator(Unit const* owner); + explicit PathGenerator(Unit const* owner); ~PathGenerator(); // Calculate the path from owner to given destination @@ -71,7 +71,7 @@ class PathGenerator Vector3 const& GetEndPosition() const { return _endPosition; } Vector3 const& GetActualEndPosition() const { return _actualEndPosition; } - PointsArray& GetPath() { return _pathPoints; } + PointsArray const& GetPath() const { return _pathPoints; } PathType GetPathType() const { return _type; } private: diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 249f25a6353..d42df898a7e 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -185,7 +185,7 @@ namespace Movement { PathGenerator path(unit); bool result = path.CalculatePath(dest.x, dest.y, dest.z, forceDestination); - if (result && path.GetPathType() & ~PATHFIND_NOPATH) + if (result && !(path.GetPathType() & PATHFIND_NOPATH)) { MovebyPath(path.GetPath()); return; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index ba570ad73a4..4c465df7c35 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5189,26 +5189,23 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->HasUnitState(UNIT_STATE_ROOT)) return SPELL_FAILED_ROOTED; - Unit* target = m_targets.GetUnitTarget(); - - if (!target) - return SPELL_FAILED_DONT_REPORT; - - if (m_caster->GetTypeId() == TYPEID_PLAYER) - if (!target->isAlive()) - return SPELL_FAILED_BAD_TARGETS; - - Position pos; - target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); - target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster)); + if (GetSpellInfo()->NeedsExplicitUnitTarget()) + { + Unit* target = m_targets.GetUnitTarget(); + if (!target) + return SPELL_FAILED_DONT_REPORT; - m_preGeneratedPath.SetPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f); - bool result = m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize()); - if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) - return SPELL_FAILED_OUT_OF_RANGE; - else if (!result) - return SPELL_FAILED_NOPATH; + Position pos; + target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); + target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster)); + m_preGeneratedPath.SetPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f); + bool result = m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize()); + if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) + return SPELL_FAILED_OUT_OF_RANGE; + else if (!result || m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH) + return SPELL_FAILED_NOPATH; + } break; } case SPELL_EFFECT_SKINNING: diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index bb730b94002..61e28a886ab 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4631,7 +4631,8 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) { - if (m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH) + // Spell is not using explicit target - no generated path + if (m_preGeneratedPath.GetPathType() == PATHFIND_BLANK) { Position pos; unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 97861133983..79cd0deb75e 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -95,7 +95,7 @@ public: path.SetUseStraightPath(useStraightPath); bool result = path.CalculatePath(x, y, z); - PointsArray pointPath = path.GetPath(); + PointsArray const& pointPath = path.GetPath(); handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str()); handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath"); handler->PSendSysMessage("Result: %s - Length: "SIZEFMTD" - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType()); |