Core/Spells: Allow dead players as valid objects for RaiseDeadObjectCheck (enables Raise Dead on players that have not yet released spirit)
TODO: Allow all corpses
This commit is contained in:
@@ -530,20 +530,38 @@ namespace Trinity
|
|||||||
class RaiseDeadObjectCheck
|
class RaiseDeadObjectCheck
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RaiseDeadObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
|
RaiseDeadObjectCheck(Unit* source, float range) : _source(source), i_range(range) {}
|
||||||
bool operator()(Creature* u)
|
bool operator()(Creature* u)
|
||||||
{
|
{
|
||||||
if (i_funit->GetTypeId() != TYPEID_PLAYER || !((Player*)i_funit)->isHonorOrXPTarget(u) ||
|
if (_source->GetTypeId() != TYPEID_PLAYER || !((Player*)_source)->isHonorOrXPTarget(u) ||
|
||||||
u->getDeathState() != CORPSE || u->isInFlight() ||
|
u->getDeathState() != CORPSE ||
|
||||||
(u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0 ||
|
(u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0 ||
|
||||||
(u->GetDisplayId() != u->GetNativeDisplayId()))
|
(u->GetDisplayId() != u->GetNativeDisplayId()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return i_funit->IsWithinDistInMap(u, i_range);
|
return _source->IsWithinDistInMap(u, i_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(Player* u)
|
||||||
|
{
|
||||||
|
if (_source == u || _source->GetTypeId() != TYPEID_PLAYER || !((Player*)_source)->isHonorOrXPTarget(u) ||
|
||||||
|
u->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) || u->isInFlight() || !u->isDead() ||
|
||||||
|
(u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _source->IsWithinDistInMap(u, i_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(Corpse* u)
|
||||||
|
{
|
||||||
|
if (_source->GetTypeId() != TYPEID_PLAYER || u->GetType() == CORPSE_BONES)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _source->IsWithinDistInMap(u, i_range);
|
||||||
}
|
}
|
||||||
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
|
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
|
||||||
private:
|
private:
|
||||||
Unit* const i_funit;
|
Unit* const _source;
|
||||||
float i_range;
|
float i_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -598,24 +598,10 @@ WorldObject* Spell::FindCorpseUsing()
|
|||||||
// non-standard target selection
|
// non-standard target selection
|
||||||
float max_range = m_spellInfo->GetMaxRange(false);
|
float max_range = m_spellInfo->GetMaxRange(false);
|
||||||
|
|
||||||
CellCoord p(Trinity::ComputeCellCoord(m_caster->GetPositionX(), m_caster->GetPositionY()));
|
|
||||||
Cell cell(p);
|
|
||||||
cell.SetNoCreate();
|
|
||||||
|
|
||||||
WorldObject* result = NULL;
|
WorldObject* result = NULL;
|
||||||
|
|
||||||
T u_check(m_caster, max_range);
|
T u_check(m_caster, max_range);
|
||||||
Trinity::WorldObjectSearcher<T> searcher(m_caster, result, u_check);
|
Trinity::WorldObjectSearcher<T> searcher(m_caster, result, u_check);
|
||||||
|
m_caster->GetMap()->VisitFirstFound(m_caster->GetPositionX(), m_caster->GetPositionY(), max_range, searcher);
|
||||||
TypeContainerVisitor<Trinity::WorldObjectSearcher<T>, GridTypeMapContainer > grid_searcher(searcher);
|
|
||||||
cell.Visit(p, grid_searcher, *m_caster->GetMap(), *m_caster, max_range);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
TypeContainerVisitor<Trinity::WorldObjectSearcher<T>, WorldTypeMapContainer > world_searcher(searcher);
|
|
||||||
cell.Visit(p, world_searcher, *m_caster->GetMap(), *m_caster, max_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2554,11 +2540,15 @@ uint32 Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur)
|
|||||||
{
|
{
|
||||||
case 46584: // Raise Dead
|
case 46584: // Raise Dead
|
||||||
{
|
{
|
||||||
if (WorldObject* result = FindCorpseUsing<Trinity::RaiseDeadObjectCheck> ())
|
if (WorldObject* result = FindCorpseUsing<Trinity::RaiseDeadObjectCheck>())
|
||||||
{
|
{
|
||||||
switch (result->GetTypeId())
|
switch (result->GetTypeId())
|
||||||
{
|
{
|
||||||
case TYPEID_UNIT:
|
case TYPEID_UNIT:
|
||||||
|
case TYPEID_PLAYER:
|
||||||
|
unitList.push_back(result->ToUnit());
|
||||||
|
// no break;
|
||||||
|
case TYPEID_CORPSE: // wont work until corpses are allowed in target lists, but at least will send dest in packet
|
||||||
m_targets.SetDst(*result);
|
m_targets.SetDst(*result);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -2582,7 +2572,7 @@ uint32 Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur)
|
|||||||
{
|
{
|
||||||
CleanupTargetList();
|
CleanupTargetList();
|
||||||
|
|
||||||
WorldObject* result = FindCorpseUsing <Trinity::ExplodeCorpseObjectCheck> ();
|
WorldObject* result = FindCorpseUsing<Trinity::ExplodeCorpseObjectCheck>();
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@@ -2824,13 +2814,13 @@ uint32 Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur)
|
|||||||
unitList.remove(m_targets.GetUnitTarget());
|
unitList.remove(m_targets.GetUnitTarget());
|
||||||
Trinity::RandomResizeList(unitList, maxTargets);
|
Trinity::RandomResizeList(unitList, maxTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallScriptAfterUnitTargetSelectHandlers(unitList, SpellEffIndex(i));
|
|
||||||
|
|
||||||
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
|
|
||||||
AddUnitTarget(*itr, effectMask, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CallScriptAfterUnitTargetSelectHandlers(unitList, SpellEffIndex(i));
|
||||||
|
|
||||||
|
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
|
||||||
|
AddUnitTarget(*itr, effectMask, false);
|
||||||
|
|
||||||
if (!gobjectList.empty())
|
if (!gobjectList.empty())
|
||||||
{
|
{
|
||||||
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
|
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
|
||||||
@@ -3725,6 +3715,27 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas
|
|||||||
case SPELL_FAILED_CUSTOM_ERROR:
|
case SPELL_FAILED_CUSTOM_ERROR:
|
||||||
data << uint32(customError);
|
data << uint32(customError);
|
||||||
break;
|
break;
|
||||||
|
case SPELL_FAILED_REAGENTS:
|
||||||
|
{
|
||||||
|
uint32 missingItem = 0;
|
||||||
|
for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
|
||||||
|
{
|
||||||
|
if (spellInfo->Reagent[i] <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 itemid = spellInfo->Reagent[i];
|
||||||
|
uint32 itemcount = spellInfo->ReagentCount[i];
|
||||||
|
|
||||||
|
if (!caster->HasItemCount(itemid, itemcount))
|
||||||
|
{
|
||||||
|
missingItem = itemid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data << uint32(missingItem); // first missing item
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5926,7 +5937,7 @@ SpellCastResult Spell::CheckItems()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!p_caster->HasItemCount(itemid, itemcount))
|
if (!p_caster->HasItemCount(itemid, itemcount))
|
||||||
return SPELL_FAILED_ITEM_NOT_READY; //0x54
|
return SPELL_FAILED_REAGENTS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user