Merge branch 'master' into 310

This commit is contained in:
tomrus88 2009-06-05 14:54:05 +04:00
commit 4236f7c75c
21 changed files with 173 additions and 98 deletions

View file

@ -631,7 +631,6 @@ void sendMTFValues ( EState* s )
} }
} }
gs = ge+1; gs = ge+1;
selCtr++; selCtr++;
} }

View file

@ -175,6 +175,8 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
float ort = fields[3].GetFloat(); float ort = fields[3].GetFloat();
uint32 mapid = fields[4].GetUInt32(); uint32 mapid = fields[4].GetUInt32();
Object::_Create(guid, 0, HIGHGUID_CORPSE);
if(!LoadValues( fields[5].GetString() )) if(!LoadValues( fields[5].GetString() ))
{ {
sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid); sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid);

View file

@ -1777,6 +1777,25 @@ void Creature::CallAssistance()
} }
} }
void Creature::CallForHelp(float fRadius)
{
if (fRadius <= 0.0f || !getVictim() || isPet() || isCharmed())
return;
CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::CallOfHelpCreatureInRangeDo u_do(this, getVictim(), fRadius);
MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo> worker(this, u_do);
TypeContainerVisitor<MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo>, GridTypeMapContainer > grid_creature_searcher(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap());
}
bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const
{ {
// we don't need help from zombies :) // we don't need help from zombies :)

View file

@ -608,6 +608,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
float GetAttackDistance(Unit const* pl) const; float GetAttackDistance(Unit const* pl) const;
void DoFleeToGetAssistance(); void DoFleeToGetAssistance();
void CallForHelp(float fRadius);
void CallAssistance(); void CallAssistance();
void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; } void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; }
void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; } void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; }

View file

@ -27,43 +27,8 @@
#include "GameEventMgr.h" #include "GameEventMgr.h"
#include "GridNotifiers.h" #include "GridNotifiers.h"
#include "GridNotifiersImpl.h" #include "GridNotifiersImpl.h"
#include "WorldPacket.h"
#include "InstanceData.h" #include "InstanceData.h"
namespace MaNGOS
{
class CallOfHelpCreatureInRangeDo // do attack at call of help to friendly crearture
{
public:
CallOfHelpCreatureInRangeDo(Unit* funit, Unit* enemy, float range)
: i_funit(funit), i_enemy(enemy), i_range(range)
{}
void operator()(Creature* u)
{
if (u == i_funit)
return;
if (!u->CanAssistTo(i_funit, i_enemy, false))
return;
// too far
if( !i_funit->IsWithinDistInMap(u, i_range) )
return;
// only if see assisted creature
if( !i_funit->IsWithinLOSInMap(u) )
return;
if(u->AI())
u->AI()->AttackStart(i_enemy);
}
private:
Unit* const i_funit;
Unit* const i_enemy;
float i_range;
};
}
bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeatMin, uint32 repeatMax ) bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeatMin, uint32 repeatMax )
{ {
if (repeatMin == repeatMax) if (repeatMin == repeatMax)
@ -780,21 +745,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
break; break;
case ACTION_T_CALL_FOR_HELP: case ACTION_T_CALL_FOR_HELP:
{ {
if (!m_creature->getVictim()) m_creature->CallForHelp(action.call_for_help.radius);
return;
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::CallOfHelpCreatureInRangeDo u_do(m_creature, m_creature->getVictim(), action.call_for_help.radius);
MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo> worker(m_creature, u_do);
TypeContainerVisitor<MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo>, GridTypeMapContainer > grid_creature_searcher(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
break; break;
} }
case ACTION_T_SET_SHEATH: case ACTION_T_SET_SHEATH:

View file

@ -1433,7 +1433,9 @@ struct SpellRangeEntry
{ {
uint32 ID; uint32 ID;
float minRange; float minRange;
float minRangeFriendly;
float maxRange; float maxRange;
float maxRangeFriendly;
}; };
struct SpellRuneCostEntry struct SpellRuneCostEntry

View file

@ -87,7 +87,7 @@ const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixxx"; const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixxx";
const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
const char SpellRadiusfmt[]="nfxf"; const char SpellRadiusfmt[]="nfxf";
const char SpellRangefmt[]="nfxfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char SpellRangefmt[]="nffffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellRuneCostfmt[]="niiii"; const char SpellRuneCostfmt[]="niiii";
const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx"; const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx";
const char StableSlotPricesfmt[] = "ni"; const char StableSlotPricesfmt[] = "ni";

View file

@ -30,6 +30,7 @@
#include "GameObject.h" #include "GameObject.h"
#include "Player.h" #include "Player.h"
#include "Unit.h" #include "Unit.h"
#include "CreatureAI.h"
class Player; class Player;
//class Map; //class Map;
@ -766,6 +767,25 @@ namespace MaNGOS
float i_range; float i_range;
}; };
class AnyUnfriendlyVisibleUnitInObjectRangeCheck
{
public:
AnyUnfriendlyVisibleUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
: i_obj(obj), i_funit(funit), i_range(range) {}
bool operator()(Unit* u)
{
return u->isAlive()
&& i_obj->IsWithinDistInMap(u, i_range)
&& !i_funit->IsFriendlyTo(u)
&& u->isVisibleForOrDetect(i_funit, false);
}
private:
WorldObject const* i_obj;
Unit const* i_funit;
float i_range;
};
class AnyFriendlyUnitInObjectRangeCheck class AnyFriendlyUnitInObjectRangeCheck
{ {
public: public:
@ -827,8 +847,8 @@ namespace MaNGOS
class AnyAoETargetUnitInObjectRangeCheck class AnyAoETargetUnitInObjectRangeCheck
{ {
public: public:
AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool hitHidden = true)
: i_obj(obj), i_funit(funit), i_range(range) : i_obj(obj), i_funit(funit), i_range(range), i_hitHidden(hitHidden)
{ {
Unit const* check = i_funit; Unit const* check = i_funit;
Unit const* owner = i_funit->GetOwner(); Unit const* owner = i_funit->GetOwner();
@ -843,6 +863,8 @@ namespace MaNGOS
return false; return false;
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem()) if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
return false; return false;
if (!i_hitHidden && !u->isVisibleForOrDetect(i_funit, false))
return false;
if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range)) if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range))
return true; return true;
@ -850,12 +872,45 @@ namespace MaNGOS
return false; return false;
} }
private: private:
bool i_hitHidden;
bool i_targetForPlayer; bool i_targetForPlayer;
WorldObject const* i_obj; WorldObject const* i_obj;
Unit const* i_funit; Unit const* i_funit;
float i_range; float i_range;
}; };
// do attack at call of help to friendly crearture
class CallOfHelpCreatureInRangeDo
{
public:
CallOfHelpCreatureInRangeDo(Unit* funit, Unit* enemy, float range)
: i_funit(funit), i_enemy(enemy), i_range(range)
{}
void operator()(Creature* u)
{
if (u == i_funit)
return;
if (!u->CanAssistTo(i_funit, i_enemy, false))
return;
// too far
if (!i_funit->IsWithinDistInMap(u, i_range))
return;
// only if see assisted creature
if (!i_funit->IsWithinLOSInMap(u))
return;
if (u->AI())
u->AI()->AttackStart(i_enemy);
}
private:
Unit* const i_funit;
Unit* const i_enemy;
float i_range;
};
struct AnyDeadUnitCheck struct AnyDeadUnitCheck
{ {
bool operator()(Unit* u) { return !u->isAlive(); } bool operator()(Unit* u) { return !u->isAlive(); }

View file

@ -1008,7 +1008,13 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data)
return; return;
} }
else else
sLog.outErrorDb("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (unknown item)", itemid); {
// listed in dbc or not expected to exist unknown item
if(sItemStore.LookupEntry(itemid))
sLog.outErrorDb("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (item listed in Item.dbc but not exist in DB)", itemid);
else
sLog.outError("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (unknown item, not listed in Item.dbc)", itemid);
}
} }
void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data)

View file

@ -6459,8 +6459,7 @@ bool ChatHandler::HandleSendMessageCommand(const char* args)
{ {
///- Find the player ///- Find the player
Player *rPlayer; Player *rPlayer;
std::string rName; if(!extractPlayerTarget((char*)args,&rPlayer))
if(!extractPlayerTarget((char*)args,&rPlayer,NULL,&rName))
return false; return false;
char* msg_str = strtok(NULL, ""); char* msg_str = strtok(NULL, "");
@ -6481,7 +6480,7 @@ bool ChatHandler::HandleSendMessageCommand(const char* args)
rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
//Confirmation message //Confirmation message
std::string nameLink = playerLink(rName); std::string nameLink = GetNameLink(rPlayer);
PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str); PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str);
return true; return true;
} }

View file

@ -814,9 +814,6 @@ void ObjectMgr::LoadEquipmentTemplates()
} }
sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount ); sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount );
sLog.outString(); sLog.outString();
// Creature items can be not listed in item_template
//sItemStore.Clear(); -- so used in spell casting
} }
CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid) CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)

View file

@ -1584,7 +1584,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
std::list<Unit *> tempUnitMap; std::list<Unit *> tempUnitMap;
{ {
MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(pUnitTarget, originalCaster, max_range); MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(pUnitTarget, originalCaster, max_range, false);
MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck> searcher(m_caster, tempUnitMap, u_check); MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck> searcher(m_caster, tempUnitMap, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
@ -4739,14 +4739,14 @@ SpellCastResult Spell::CheckRange(bool strict)
range_mod = 6.25; range_mod = 6.25;
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
float max_range = GetSpellMaxRange(srange) + range_mod; Unit *target = m_targets.getUnitTarget();
float min_range = GetSpellMinRange(srange); bool friendly = target ? target->IsFriendlyTo(m_caster) : false;
float max_range = GetSpellMaxRange(srange, friendly) + range_mod;
float min_range = GetSpellMinRange(srange, friendly);
if(Player* modOwner = m_caster->GetSpellModOwner()) if(Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this); modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
Unit *target = m_targets.getUnitTarget();
if(target && target != m_caster) if(target && target != m_caster)
{ {
// distance from target in checks // distance from target in checks

View file

@ -6453,8 +6453,42 @@ void Aura::PeriodicDummyTick()
} }
case SPELLFAMILY_ROGUE: case SPELLFAMILY_ROGUE:
{ {
// switch (spell->Id) switch (spell->Id)
// { {
case 51690:
{
std::list<Unit*> targets;
{
// eff_radius ==0
float radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spell->rangeIndex));
CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(),caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::AnyUnfriendlyVisibleUnitInObjectRangeCheck u_check(caster, caster, radius);
MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyVisibleUnitInObjectRangeCheck> checker(caster,targets, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyVisibleUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyVisibleUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_object_checker, *caster->GetMap());
cell_lock->Visit(cell_lock, world_object_checker, *caster->GetMap());
}
if(targets.empty())
return;
std::list<Unit*>::const_iterator itr = targets.begin();
std::advance(itr, rand()%targets.size());
Unit* target = *itr;
caster->CastSpell(target, 57840, true);
caster->CastSpell(target, 57841, true);
return;
}
// Master of Subtlety // Master of Subtlety
// case 31666: break; // case 31666: break;
// Killing Spree // Killing Spree
@ -6463,7 +6497,7 @@ void Aura::PeriodicDummyTick()
// case 58428: break; // case 58428: break;
// default: // default:
// break; // break;
// } }
break; break;
} }
case SPELLFAMILY_HUNTER: case SPELLFAMILY_HUNTER:

View file

@ -104,8 +104,18 @@ SpellSpecific GetSpellSpecific(uint32 spellId);
// Different spell properties // Different spell properties
inline float GetSpellRadius(SpellRadiusEntry const *radius) { return (radius ? radius->Radius : 0); } inline float GetSpellRadius(SpellRadiusEntry const *radius) { return (radius ? radius->Radius : 0); }
uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL); uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL);
inline float GetSpellMinRange(SpellRangeEntry const *range) { return (range ? range->minRange : 0); } inline float GetSpellMinRange(SpellRangeEntry const *range, bool friendly = false)
inline float GetSpellMaxRange(SpellRangeEntry const *range) { return (range ? range->maxRange : 0); } {
if(!range)
return 0;
return (friendly ? range->minRangeFriendly : range->minRange);
}
inline float GetSpellMaxRange(SpellRangeEntry const *range, bool friendly = false)
{
if(!range)
return 0;
return (friendly ? range->maxRangeFriendly : range->maxRange);
}
inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; } inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
int32 GetSpellDuration(SpellEntry const *spellInfo); int32 GetSpellDuration(SpellEntry const *spellInfo);
int32 GetSpellMaxDuration(SpellEntry const *spellInfo); int32 GetSpellMaxDuration(SpellEntry const *spellInfo);

View file

@ -5093,8 +5093,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
target = GetPet(); target = GetPet();
if (!target) if (!target)
return false; return false;
basepoints0 = damage * 15 / 100;
triggered_spell_id = 54181; triggered_spell_id = 54181;
basepoints0 = damage * triggerAmount / 100;
break; break;
} }
switch(dummySpell->Id) switch(dummySpell->Id)

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7948" #define REVISION_NR "7960"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -371,7 +371,7 @@ namespace VMAP
if(!rf) if(!rf)
{ {
printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str()); printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str());
printf("... or form: %s",filename ); printf("... or form: %s",filename.c_str() );
return false; return false;
} }