Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
This commit is contained in:
commit
3c5bf554ff
13 files changed
+64
-41
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 (GetSpellInfo()->NeedsExplicitUnitTarget())
|
||||
{
|
||||
Unit* target = m_targets.GetUnitTarget();
|
||||
if (!target)
|
||||
return SPELL_FAILED_DONT_REPORT;
|
||||
|
||||
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));
|
||||
|
||||
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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in new issue
Block a user