Merge commit 'origin/master' into 310

Conflicts:
	src/game/SpellAuras.cpp
	src/game/SpellEffects.cpp
This commit is contained in:
tomrus88 2009-05-24 10:11:26 +04:00
commit afd82229d7
34 changed files with 357 additions and 344 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` (
`required_7802_02_characters_character_achievement_progress` bit(1) default NULL
`required_7887_01_characters_character_pet` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
--
@ -483,7 +483,6 @@ CREATE TABLE `character_pet` (
`resettalents_cost` int(11) unsigned NOT NULL default '0',
`resettalents_time` bigint(20) unsigned NOT NULL default '0',
`abdata` longtext,
`teachspelldata` longtext,
PRIMARY KEY (`id`),
KEY `owner` (`owner`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System';

View file

@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`required_7855_01_mangos_pools` bit(1) default NULL
`required_7886_01_mangos_petcreateinfo_spell` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -3660,29 +3660,6 @@ INSERT INTO `pet_name_generation` (`word`,`entry`,`half`) VALUES
/*!40000 ALTER TABLE `pet_name_generation` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `petcreateinfo_spell`
--
DROP TABLE IF EXISTS `petcreateinfo_spell`;
CREATE TABLE `petcreateinfo_spell` (
`entry` mediumint(8) unsigned NOT NULL default '0',
`Spell1` mediumint(8) unsigned NOT NULL default '0',
`Spell2` mediumint(8) unsigned NOT NULL default '0',
`Spell3` mediumint(8) unsigned NOT NULL default '0',
`Spell4` mediumint(8) unsigned NOT NULL default '0',
PRIMARY KEY (`entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet Create Spells';
--
-- Dumping data for table `petcreateinfo_spell`
--
LOCK TABLES `petcreateinfo_spell` WRITE;
/*!40000 ALTER TABLE `petcreateinfo_spell` DISABLE KEYS */;
/*!40000 ALTER TABLE `petcreateinfo_spell` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `pickpocketing_loot_template`
--

View file

@ -0,0 +1,7 @@
ALTER TABLE db_version CHANGE COLUMN required_7855_01_mangos_pools required_7879_01_mangos_spell_proc_event bit;
DELETE FROM spell_proc_event WHERE entry IN (31571, 31572);
INSERT INTO spell_proc_event VALUES
(31571, 0x00, 3, 0x00000000, 0x00000022, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
(31572, 0x00, 3, 0x00000000, 0x00000022, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0);

View file

@ -0,0 +1,3 @@
ALTER TABLE db_version CHANGE COLUMN required_7879_01_mangos_spell_proc_event required_7884_01_mangos_playercreateinfo_spell bit;
DELETE FROM playercreateinfo_spell WHERE Spell = '28734';

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_7884_01_mangos_playercreateinfo_spell required_7884_02_mangos_playercreateinfo_action bit;
DELETE FROM playercreateinfo_action WHERE action = '28734';
UPDATE playercreateinfo_action SET button = '3' WHERE race = '10' AND class IN ('8', '9', '5', '2', '3') AND button = '4';
UPDATE playercreateinfo_action SET button = '4' WHERE race = '10' AND class = '4' AND button = '5';

View file

@ -0,0 +1,3 @@
ALTER TABLE character_db_version CHANGE COLUMN required_7802_02_characters_character_achievement_progress required_7884_03_characters_character_spell bit;
DELETE FROM character_spell WHERE spell = '28734';

View file

@ -0,0 +1,3 @@
ALTER TABLE character_db_version CHANGE COLUMN required_7884_03_characters_character_spell required_7884_04_characters_character_aura bit;
DELETE FROM character_aura WHERE spell = '28734';

View file

@ -0,0 +1,3 @@
ALTER TABLE character_db_version CHANGE COLUMN required_7884_04_characters_character_aura required_7884_05_characters_character_action bit;
DELETE FROM character_action WHERE action = '28734' AND type = '0';

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_7884_02_mangos_playercreateinfo_action required_7886_01_mangos_petcreateinfo_spell bit;
DROP TABLE IF EXISTS `petcreateinfo_spell`;

View file

@ -0,0 +1,4 @@
ALTER TABLE character_db_version CHANGE COLUMN required_7884_05_characters_character_action required_7887_01_characters_character_pet bit;
ALTER TABLE `character_pet`
DROP TeachSpelldata;

View file

@ -191,6 +191,14 @@ pkgdata_DATA = \
7850_01_mangos_command.sql \
7855_01_mangos_pools.sql \
7867_01_realmd_account.sql \
7879_01_mangos_spell_proc_event.sql \
7884_01_mangos_playercreateinfo_spell.sql \
7884_02_mangos_playercreateinfo_action.sql \
7884_03_characters_character_spell.sql \
7884_04_characters_character_aura.sql \
7884_05_characters_character_action.sql \
7886_01_mangos_petcreateinfo_spell.sql \
7887_01_characters_character_pet.sql \
README
## Additional files to include when running 'make dist'
@ -362,4 +370,12 @@ EXTRA_DIST = \
7850_01_mangos_command.sql \
7855_01_mangos_pools.sql \
7867_01_realmd_account.sql \
7879_01_mangos_spell_proc_event.sql \
7884_01_mangos_playercreateinfo_spell.sql \
7884_02_mangos_playercreateinfo_action.sql \
7884_03_characters_character_spell.sql \
7884_04_characters_character_aura.sql \
7884_05_characters_character_action.sql \
7886_01_mangos_petcreateinfo_spell.sql \
7887_01_characters_character_pet.sql \
README

View file

@ -128,6 +128,12 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
}
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
if(player_dead.own_team_flag > 1)
{
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong boolean value1 (%u).",
criteria->ID, criteria->requiredType,dataType,player_dead.own_team_flag);
return false;
}
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
@ -193,7 +199,10 @@ bool AchievementCriteriaData::Meets(Player const* source, Unit const* target) co
return false;
return target->GetHealth()*100 <= health.percent*target->GetMaxHealth();
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
return target && target->GetTypeId() == TYPEID_PLAYER && !target->isAlive() && ((Player*)target)->GetDeathTimer() != 0;
if (!target || target->GetTypeId() != TYPEID_PLAYER || target->isAlive() || ((Player*)target)->GetDeathTimer() == 0)
return false;
// flag set == must be same team, not set == different team
return (((Player*)target)->GetTeam() == source->GetTeam()) == (player_dead.own_team_flag != 0);
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
return source->HasAura(aura.spell_id,aura.effect_idx);
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
@ -961,7 +970,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
SetCriteriaProgress(achievementCriteria, GetPlayer()->GetByteValue(PLAYER_BYTES_2, 2)+1);
SetCriteriaProgress(achievementCriteria, GetPlayer()->GetBankBagSlotCount());
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
{

View file

@ -46,7 +46,7 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH= 3, // health_percent 0
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // 0 0 not corpse (not released body)
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // own_team 0 not corpse (not released body), own_team==false if enemy team expected
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx
@ -78,6 +78,11 @@ struct AchievementCriteriaData
{
uint32 percent;
} health;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD
struct
{
uint32 own_team_flag;
} player_dead;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA
struct

View file

@ -1577,6 +1577,20 @@ bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index)
if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1)))
return true;
// Taunt immunity special flag check
if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NOT_TAUNTABLE)
{
// Taunt aura apply check
if (spellInfo->Effect[index] == SPELL_EFFECT_APPLY_AURA)
{
if (spellInfo->EffectApplyAuraName[index] == SPELL_AURA_MOD_TAUNT)
return true;
}
// Spell effect taunt check
else if (spellInfo->Effect[index] == SPELL_EFFECT_ATTACK_ME)
return true;
}
return Unit::IsImmunedToSpellEffect(spellInfo, index);
}

View file

@ -142,6 +142,7 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_NO_CRUSH = 0x00000020, // creature can't do crush attacks
CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP
CREATURE_FLAG_EXTRA_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures)
CREATURE_FLAG_EXTRA_NOT_TAUNTABLE = 0x00000100, // creature is immune to taunt auras and effect attack me
};
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform

View file

@ -705,11 +705,13 @@ struct CreatureFamilyEntry
// 27 m_iconFile
};
#define MAX_CREATURE_SPELL_DATA_SLOT 4
struct CreatureSpellDataEntry
{
uint32 ID; // 0 m_ID
//uint32 spellId[4]; // 1-4 m_spells[4]
//uint32 availability[4]; // 4-7 m_availability[4]
uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]; // 1-4 m_spells[4]
//uint32 availability[MAX_CREATURE_SPELL_DATA_SLOT]; // 4-7 m_availability[4]
};
struct CreatureTypeEntry

View file

@ -37,7 +37,7 @@ const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxx
const char CinematicSequencesEntryfmt[]="nxxxxxxxxx";
const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";
const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
const char CreatureSpellDatafmt[]="nxxxxxxxx";
const char CreatureSpellDatafmt[]="niiiixxxx";
const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx";
const char CurrencyTypesfmt[]="xnxi";
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";

View file

@ -843,7 +843,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
return;
}
uint32 slot = _player->GetByteValue(PLAYER_BYTES_2, 2);
uint32 slot = _player->GetBankBagSlotCount();
// next slot
++slot;
@ -861,7 +861,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
return;
_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot);
_player->SetByteValue(PLAYER_BYTES_2, 2, slot);
_player->SetBankBagSlotCount(slot);
_player->ModifyMoney(-int32(price));
}

View file

@ -3563,90 +3563,6 @@ void ObjectMgr::LoadQuestLocales()
sLog.outString( ">> Loaded %lu Quest locale strings", (unsigned long)mQuestLocaleMap.size() );
}
void ObjectMgr::LoadPetCreateSpells()
{
QueryResult *result = WorldDatabase.Query("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell");
if(!result)
{
barGoLink bar( 1 );
bar.step();
sLog.outString();
sLog.outString( ">> Loaded 0 pet create spells" );
sLog.outErrorDb("`petcreateinfo_spell` table is empty!");
return;
}
uint32 count = 0;
barGoLink bar( result->GetRowCount() );
mPetCreateSpell.clear();
do
{
Field *fields = result->Fetch();
bar.step();
uint32 creature_id = fields[0].GetUInt32();
if(!creature_id)
{
sLog.outErrorDb("Creature id %u listed in `petcreateinfo_spell` not exist.",creature_id);
continue;
}
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(creature_id);
if(!cInfo)
{
sLog.outErrorDb("Creature id %u listed in `petcreateinfo_spell` not exist.",creature_id);
continue;
}
PetCreateSpellEntry PetCreateSpell;
bool have_spell = false;
bool have_spell_db = false;
for(int i = 0; i < 4; i++)
{
PetCreateSpell.spellid[i] = fields[i + 1].GetUInt32();
if(!PetCreateSpell.spellid[i])
continue;
have_spell_db = true;
SpellEntry const* i_spell = sSpellStore.LookupEntry(PetCreateSpell.spellid[i]);
if(!i_spell)
{
sLog.outErrorDb("Spell %u listed in `petcreateinfo_spell` does not exist",PetCreateSpell.spellid[i]);
PetCreateSpell.spellid[i] = 0;
continue;
}
have_spell = true;
}
if(!have_spell_db)
{
sLog.outErrorDb("Creature %u listed in `petcreateinfo_spell` have only 0 spell data, why it listed?",creature_id);
continue;
}
if(!have_spell)
continue;
mPetCreateSpell[creature_id] = PetCreateSpell;
++count;
}
while (result->NextRow());
delete result;
sLog.outString();
sLog.outString( ">> Loaded %u pet create spells", count );
}
void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
{
if(sWorld.IsScriptScheduled()) // function don't must be called in time scripts use.

View file

@ -196,11 +196,6 @@ struct PointOfInterest
std::string icon_name;
};
struct PetCreateSpellEntry
{
uint32 spellid[4];
};
#define WEATHER_SEASONS 4
struct WeatherSeasonChances
{
@ -320,8 +315,6 @@ class ObjectMgr
typedef UNORDERED_MAP<uint32, WeatherZoneChances> WeatherZoneMap;
typedef UNORDERED_MAP<uint32, PetCreateSpellEntry> PetCreateSpellMap;
typedef std::vector<std::string> ScriptNameMap;
Player* GetPlayer(const char* name) const { return ObjectAccessor::Instance().FindPlayerByName(name);}
@ -464,14 +457,6 @@ class ObjectMgr
return NULL;
}
PetCreateSpellEntry const* GetPetCreateSpellEntry(uint32 id) const
{
PetCreateSpellMap::const_iterator itr = mPetCreateSpell.find(id);
if(itr != mPetCreateSpell.end())
return &itr->second;
return NULL;
}
void LoadGuilds();
void LoadArenaTeams();
void LoadGroups();
@ -502,7 +487,6 @@ class ObjectMgr
bool LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value);
bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase,"mangos_string",MIN_MANGOS_STRING_ID,MAX_MANGOS_STRING_ID); }
void LoadDbScriptStrings();
void LoadPetCreateSpells();
void LoadCreatureLocales();
void LoadCreatureTemplates();
void LoadCreatures();
@ -816,8 +800,6 @@ class ObjectMgr
WeatherZoneMap mWeatherZoneMap;
PetCreateSpellMap mPetCreateSpell;
//character reserved names
typedef std::set<std::wstring> ReservedNamesMap;
ReservedNamesMap m_ReservedNames;

View file

@ -87,25 +87,25 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
QueryResult *result;
if (petnumber)
// known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
// known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
"FROM character_pet WHERE owner = '%u' AND id = '%u'",
ownerid, petnumber);
else if (current)
// current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
// current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
"FROM character_pet WHERE owner = '%u' AND slot = '%u'",
ownerid, PET_SAVE_AS_CURRENT );
else if (petentry)
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
"FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ",
ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
else
// any current or other non-stabled pet (for hunter "call pet")
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
"FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ",
ownerid,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
@ -122,7 +122,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
return false;
}
uint32 summon_spell_id = fields[19].GetUInt32();
uint32 summon_spell_id = fields[18].GetUInt32();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
@ -164,7 +164,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
return false;
}
setPetType(PetType(fields[20].GetUInt8()));
setPetType(PetType(fields[19].GetUInt8()));
SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
@ -257,27 +257,13 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
++iter;
m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
}
//init teach spells
tokens = StrSplit(fields[15].GetString(), " ");
for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)
{
uint32 tmp = atol((*iter).c_str());
++iter;
if(tmp)
AddTeachSpell(tmp, atol((*iter).c_str()));
else
break;
}
}
// since last save (in seconds)
uint32 timediff = (time(NULL) - fields[16].GetUInt32());
uint32 timediff = (time(NULL) - fields[15].GetUInt32());
m_resetTalentsCost = fields[17].GetUInt32();
m_resetTalentsTime = fields[18].GetUInt64();
m_resetTalentsCost = fields[16].GetUInt32();
m_resetTalentsTime = fields[17].GetUInt64();
delete result;
@ -418,7 +404,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
// save pet
std::ostringstream ss;
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
<< "VALUES ("
<< m_charmInfo->GetPetNumber() << ", "
<< GetEntry() << ", "
@ -437,17 +423,6 @@ void Pet::SavePetToDB(PetSaveMode mode)
for(uint32 i = 0; i < 10; ++i)
ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
ss << "', '";
//save spells the pet can teach to it's Master
{
int i = 0;
for(TeachSpellMap::const_iterator itr = m_teachspells.begin(); i < 4 && itr != m_teachspells.end(); ++i, ++itr)
ss << itr->first << " " << itr->second << " ";
for(; i < 4; ++i)
ss << uint32(0) << " " << uint32(0) << " ";
}
ss << "', "
<< time(NULL) << ", "
<< uint32(m_resetTalentsCost) << ", "
@ -1437,25 +1412,40 @@ bool Pet::learnSpell(uint32 spell_id)
void Pet::InitLevelupSpellsForLevel()
{
uint32 family = GetCreatureInfo()->family;
if(!family)
return;
PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(family);
if(!levelupSpells)
return;
uint32 level = getLevel();
// PetLevelupSpellSet ordered by levels, process in reversed order
for(PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
if(PetLevelupSpellSet const *levelupSpells = GetCreatureInfo()->family ? spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family) : NULL)
{
// will called first if level down
if(itr->first > level)
unlearnSpell(itr->second,true); // will learn prev rank if any
// will called if level up
else
learnSpell(itr->second); // will unlearn prev rank if any
// PetLevelupSpellSet ordered by levels, process in reversed order
for(PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
{
// will called first if level down
if(itr->first > level)
unlearnSpell(itr->second,true); // will learn prev rank if any
// will called if level up
else
learnSpell(itr->second); // will unlearn prev rank if any
}
}
int32 petSpellsId = GetCreatureInfo()->PetSpellDataId ? -(int32)GetCreatureInfo()->PetSpellDataId : GetEntry();
// default spells (can be not learned if pet level (as owner level decrease result for example) less first possible in normal game)
if(PetDefaultSpellsEntry const *defSpells = spellmgr.GetPetDefaultSpellsEntry(petSpellsId))
{
for(int i = 0; i < MAX_CREATURE_SPELL_DATA_SLOT; ++i)
{
SpellEntry const* spellEntry = sSpellStore.LookupEntry(defSpells->spellid[i]);
if(!spellEntry)
continue;
// will called first if level down
if(spellEntry->spellLevel > level)
unlearnSpell(spellEntry->Id,false);
// will called if level up
else
learnSpell(spellEntry->Id);
}
}
}
@ -1516,14 +1506,16 @@ bool Pet::removeSpell(uint32 spell_id, bool learn_prev)
learnSpell(prev_id);
}
else
{
m_charmInfo->AddSpellToAB(spell_id, 0);
learn_prev = false;
}
// need update action bar for last removed rank
if (Unit* owner = GetOwner())
if (owner->GetTypeId() == TYPEID_PLAYER)
((Player*)owner)->PetSpellInitialize();
}
// if remove last rank or non-ranked then update action bar at server and client if need
if(!learn_prev && m_charmInfo->AddSpellToAB(spell_id, 0))
{
// need update action bar for last removed rank
if (Unit* owner = GetOwner())
if (owner->GetTypeId() == TYPEID_PLAYER)
((Player*)owner)->PetSpellInitialize();
}
return true;
@ -1534,65 +1526,11 @@ void Pet::InitPetCreateSpells()
m_charmInfo->InitPetActionBar();
m_spells.clear();
uint32 petspellid;
PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry());
if(CreateSpells)
{
for(uint8 i = 0; i < 4; ++i)
{
if(!CreateSpells->spellid[i])
break;
SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(CreateSpells->spellid[i]);
if(!learn_spellproto)
continue;
if(learn_spellproto->Effect[0] == SPELL_EFFECT_LEARN_SPELL || learn_spellproto->Effect[0] == SPELL_EFFECT_LEARN_PET_SPELL)
{
petspellid = learn_spellproto->EffectTriggerSpell[0];
Unit* owner = GetOwner();
if(owner->GetTypeId() == TYPEID_PLAYER && !((Player*)owner)->HasSpell(learn_spellproto->Id))
{
if(IsPassiveSpell(petspellid)) //learn passive skills when tamed, not sure if thats right
((Player*)owner)->learnSpell(learn_spellproto->Id,false);
else
AddTeachSpell(learn_spellproto->EffectTriggerSpell[0], learn_spellproto->Id);
}
}
else
petspellid = learn_spellproto->Id;
addSpell(petspellid);
}
}
LearnPetPassives();
CastPetAuras(false);
}
void Pet::CheckLearning(uint32 spellid)
{
//charmed case -> prevent crash
if(GetTypeId() == TYPEID_PLAYER || getPetType() != HUNTER_PET)
return;
Unit* owner = GetOwner();
if(m_teachspells.empty() || !owner || owner->GetTypeId() != TYPEID_PLAYER)
return;
TeachSpellMap::iterator itr = m_teachspells.find(spellid);
if(itr == m_teachspells.end())
return;
if(urand(0, 100) < 10)
{
((Player*)owner)->learnSpell(itr->second,false);
m_teachspells.erase(itr);
}
}
bool Pet::resetTalents(bool no_cost)
{
Unit *owner = GetOwner();

View file

@ -107,7 +107,6 @@ enum PetNameInvalidReason
};
typedef UNORDERED_MAP<uint32, PetSpell> PetSpellMap;
typedef std::map<uint32,uint32> TeachSpellMap;
typedef std::vector<uint32> AutoSpellList;
#define HAPPINESS_LEVEL_SIZE 333000
@ -183,7 +182,6 @@ class Pet : public Creature
void ToggleAutocast(uint32 spellid, bool apply);
bool HasSpell(uint32 spell) const;
void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; }
void LearnPetPassives();
void CastPetAuras(bool current);
@ -204,11 +202,9 @@ class Pet : public Creature
bool removeSpell(uint32 spell_id, bool learn_prev);
PetSpellMap m_spells;
TeachSpellMap m_teachspells;
AutoSpellList m_autospells;
void InitPetCreateSpells();
void CheckLearning(uint32 spellid);
bool resetTalents(bool no_cost = false);
uint32 resetTalentsCost() const;

View file

@ -273,8 +273,6 @@ void PetAI::UpdateAI(const uint32 diff)
}
m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
if (m_creature->isPet())
((Pet*)m_creature)->CheckLearning(spell->m_spellInfo->Id);
spell->prepare(&targets);
}

View file

@ -215,8 +215,6 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if(result == SPELL_CAST_OK)
{
((Creature*)pet)->AddCreatureSpellCooldown(spellid);
if (((Creature*)pet)->isPet())
((Pet*)pet)->CheckLearning(spellid);
unit_target = spell->m_targets.getUnitTarget();
@ -628,11 +626,9 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
pet->AddCreatureSpellCooldown(spellid);
if(pet->isPet())
{
Pet* p = (Pet*)pet;
p->CheckLearning(spellid);
//10% chance to play special pet attack talk, else growl
//actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
if(((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);

View file

@ -8345,14 +8345,6 @@ uint32 Player::GetAttackBySlot( uint8 slot )
}
}
bool Player::HasBankBagSlot( uint8 slot ) const
{
uint32 maxslot = GetByteValue(PLAYER_BYTES_2, 2) + BANK_SLOT_BAG_START;
if( slot < maxslot )
return true;
return false;
}
bool Player::IsInventoryPos( uint8 bag, uint8 slot )
{
if( bag == INVENTORY_SLOT_BAG_0 && slot == NULL_SLOT )
@ -9733,44 +9725,44 @@ uint8 Player::CanUnequipItem( uint16 pos, bool swap ) const
uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading ) const
{
if( !pItem )
if (!pItem)
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
uint32 count = pItem->GetCount();
sLog.outDebug( "STORAGE: CanBankItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), pItem->GetCount());
ItemPrototype const *pProto = pItem->GetProto();
if( !pProto )
if (!pProto)
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
if( pItem->IsBindedNotWith(GetGUID()) )
if (pItem->IsBindedNotWith(GetGUID()))
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
// check count of items (skip for auto move for same player from bank)
uint8 res = CanTakeMoreSimilarItems(pItem);
if(res != EQUIP_ERR_OK)
if (res != EQUIP_ERR_OK)
return res;
// in specific slot
if( bag != NULL_BAG && slot != NULL_SLOT )
if (bag != NULL_BAG && slot != NULL_SLOT)
{
if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
if (slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END)
{
if (!pItem->IsBag())
return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT;
if( !HasBankBagSlot( slot ) )
if (slot - BANK_SLOT_BAG_START >= GetBankBagSlotCount())
return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
if (uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK)
return cantuse;
}
res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem);
if(res!=EQUIP_ERR_OK)
if (res!=EQUIP_ERR_OK)
return res;
if(count==0)
if (count==0)
return EQUIP_ERR_OK;
}

View file

@ -1025,7 +1025,8 @@ class MANGOS_DLL_SPEC Player : public Unit
static bool IsBankPos( uint8 bag, uint8 slot );
bool IsValidPos( uint16 pos ) { return IsBankPos(pos >> 8,pos & 255); }
bool IsValidPos( uint8 bag, uint8 slot );
bool HasBankBagSlot( uint8 slot ) const;
uint8 GetBankBagSlotCount() const { return GetByteValue(PLAYER_BYTES_2, 2); }
void SetBankBagSlotCount(uint8 count) { SetByteValue(PLAYER_BYTES_2, 2, count); }
bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const;
bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL);
bool CanNoReagentCast(SpellEntry const* spellInfo) const;

View file

@ -3761,26 +3761,6 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++)
if (m_target->m_currentSpells[i] && m_target->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
m_target->InterruptSpell(i, false); // Stop spells on prepare or casting state
switch (GetId())
{
// Arcane Torrent (Energy)
case 25046:
{
Unit * caster = GetCaster();
if (!caster)
return;
// Search Mana Tap auras on caster
Aura * dummy = caster->GetDummyAura(28734);
if (dummy)
{
int32 bp = dummy->GetStackAmount() * 10;
caster->CastCustomSpell(caster, 25048, &bp, NULL, NULL, true);
caster->RemoveAurasDueToSpell(28734);
}
}
}
}
else
{

View file

@ -2700,17 +2700,30 @@ void Spell::EffectCreateItem(uint32 i)
void Spell::EffectCreateItem2(uint32 i)
{
// special case: generate using spell_loot_template
if(!m_spellInfo->EffectItemType[i])
if(m_caster->GetTypeId()!=TYPEID_PLAYER)
return;
Player* player = (Player*)m_caster;
uint32 item_id = m_spellInfo->EffectItemType[i];
if(item_id)
DoCreateItem(i, item_id);
// special case: fake item replaced by generate using spell_loot_template
if(IsLootCraftingSpell(m_spellInfo))
{
if(m_caster->GetTypeId()!=TYPEID_PLAYER)
return;
if(item_id)
{
if(!player->HasItemCount(item_id, 1))
return;
// remove reagent
uint32 count = 1;
player->DestroyItemCount (item_id, count, true);
}
// create some random items
((Player*)m_caster)->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell);
return;
player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell);
}
DoCreateItem(i,m_spellInfo->EffectItemType[i]);
}
void Spell::EffectPersistentAA(uint32 i)
@ -4933,32 +4946,12 @@ void Spell::EffectScriptEffect(uint32 effIndex)
case 61288: // Minor Inscription Research
case 61756: // Northrend Inscription Research (FAST QA VERSION)
{
if(!IsExplicitDiscoverySpell(m_spellInfo))
{
sLog.outError("Wrong explicit discovery spell %u structure, or outdated...",m_spellInfo->Id);
return;
}
if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
Player* player = (Player*)m_caster;
// need replace effect 0 item by loot
uint32 reagent_id = m_spellInfo->EffectItemType[0];
if(!player->HasItemCount(reagent_id, 1))
return;
// remove reagent
uint32 count = 1;
player->DestroyItemCount(reagent_id, count, true);
// create some random items
player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell);
// learn random explicit discovery recipe (if any)
if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player))
player->learnSpell(discoveredSpell, false);
if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, (Player*)m_caster))
((Player*)m_caster)->learnSpell(discoveredSpell, false);
return;
}
}

View file

@ -2223,6 +2223,131 @@ void SpellMgr::LoadPetLevelupSpellMap()
sLog.outString( ">> Loaded %u pet levelup and default spells for %u families", count, family_count );
}
bool LoadPetDefaultSpells_helper(CreatureInfo const* cInfo, PetDefaultSpellsEntry& petDefSpells)
{
// skip empty list;
bool have_spell = false;
for(int j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
{
if(petDefSpells.spellid[j])
{
have_spell = true;
break;
}
}
if(!have_spell)
return false;
// remove duplicates with levelupSpells if any
if(PetLevelupSpellSet const *levelupSpells = cInfo->family ? spellmgr.GetPetLevelupSpellList(cInfo->family) : NULL)
{
for(int j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
{
if(!petDefSpells.spellid[j])
continue;
for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr)
{
if (itr->second == petDefSpells.spellid[j])
{
petDefSpells.spellid[j] = 0;
break;
}
}
}
}
// skip empty list;
have_spell = false;
for(int j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
{
if(petDefSpells.spellid[j])
{
have_spell = true;
break;
}
}
return have_spell;
}
void SpellMgr::LoadPetDefaultSpells()
{
assert(MAX_CREATURE_SPELL_DATA_SLOT==CREATURE_MAX_SPELLS);
mPetDefaultSpellsMap.clear();
uint32 countCreature = 0;
uint32 countData = 0;
for(uint32 i = 0; i < sCreatureStorage.MaxEntry; ++i )
{
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i);
if(!cInfo)
continue;
if(!cInfo->PetSpellDataId)
continue;
// for creature with PetSpellDataId get default pet spells from dbc
CreatureSpellDataEntry const* spellDataEntry = sCreatureSpellDataStore.LookupEntry(cInfo->PetSpellDataId);
if(!spellDataEntry)
continue;
int32 petSpellsId = -(int32)cInfo->PetSpellDataId;
PetDefaultSpellsEntry petDefSpells;
for(int j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
petDefSpells.spellid[j] = spellDataEntry->spellId[j];
if(LoadPetDefaultSpells_helper(cInfo, petDefSpells))
{
mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
++countData;
}
}
// different summon spells
for(uint32 i = 0; i < sSpellStore.GetNumRows(); ++i )
{
SpellEntry const* spellEntry = sSpellStore.LookupEntry(i);
if(!spellEntry)
continue;
for(int k = 0; k < 3; ++k)
{
if(spellEntry->Effect[k]==SPELL_EFFECT_SUMMON || spellEntry->Effect[k]==SPELL_EFFECT_SUMMON_PET)
{
uint32 creature_id = spellEntry->EffectMiscValue[k];
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(creature_id);
if(!cInfo)
continue;
// already loaded
if(cInfo->PetSpellDataId)
continue;
// for creature without PetSpellDataId get default pet spells from creature_template
int32 petSpellsId = cInfo->Entry;
if(mPetDefaultSpellsMap.find(cInfo->Entry) != mPetDefaultSpellsMap.end())
continue;
PetDefaultSpellsEntry petDefSpells;
for(int j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j)
petDefSpells.spellid[j] = cInfo->spells[j];
if(LoadPetDefaultSpells_helper(cInfo, petDefSpells))
{
mPetDefaultSpellsMap[petSpellsId] = petDefSpells;
++countCreature;
}
}
}
}
sLog.outString();
sLog.outString( ">> Loaded addition spells for %u pet spell data entries and %u summonable creature templates", countData, countCreature );
}
/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc
bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
{

View file

@ -140,8 +140,10 @@ inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo)
inline bool IsLootCraftingSpell(SpellEntry const *spellInfo)
{
return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 &&
(spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT || !spellInfo->EffectItemType[0]);
return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 && (
spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT || // see IsExplicitDiscoverySpell
!spellInfo->EffectItemType[0] || // result item not provided
spellInfo->TotemCategory[0] == 121); // different random cards from Inscription (121==Virtuoso Inking Set category)
}
int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
@ -562,6 +564,15 @@ typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
typedef std::multimap<uint32, uint32> PetLevelupSpellSet;
typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
struct PetDefaultSpellsEntry
{
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT];
};
// < 0 for petspelldata id, > 0 for creature_id
typedef std::map<int32, PetDefaultSpellsEntry> PetDefaultSpellsMap;
inline bool IsPrimaryProfessionSkill(uint32 skill)
{
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill);
@ -812,6 +823,15 @@ class SpellMgr
return NULL;
}
// < 0 for petspelldata id, > 0 for creature_id
PetDefaultSpellsEntry const* GetPetDefaultSpellsEntry(int32 id) const
{
PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id);
if(itr != mPetDefaultSpellsMap.end())
return &itr->second;
return NULL;
}
SpellCastResult GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = NULL);
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
@ -860,6 +880,7 @@ class SpellMgr
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
void LoadPetLevelupSpellMap();
void LoadPetDefaultSpells();
void LoadSpellAreas();
private:
@ -876,6 +897,7 @@ class SpellMgr
SkillLineAbilityMap mSkillLineAbilityMap;
SpellPetAuraMap mSpellPetAuraMap;
PetLevelupSpellMap mPetLevelupSpellMap;
PetDefaultSpellsMap mPetDefaultSpellsMap; // only spells not listed in related mPetLevelupSpellMap entry
SpellAreaMap mSpellAreaMap;
SpellAreaForQuestMap mSpellAreaForQuestMap;
SpellAreaForQuestMap mSpellAreaForActiveQuestMap;

View file

@ -4846,6 +4846,25 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 29077;
break;
}
//Arcane Potency
if (dummySpell->SpellIconID == 2120)
{
if(!procSpell)
return false;
target = this;
switch (dummySpell->Id)
{
case 31571: triggered_spell_id = 57529; break;
case 31572: triggered_spell_id = 57531; break;
default:
sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u",dummySpell->Id);
return false;
}
break;
}
// Hot Streak
if (dummySpell->SpellIconID == 2999)
{
@ -5092,9 +5111,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if(triggeredByAura->GetCasterGUID() != pVictim->GetGUID())
return false;
// energize amount
basepoints0 = triggerAmount*damage/100;
pVictim->CastCustomSpell(pVictim,34919,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
// Energize 0.25% of max. mana
pVictim->CastSpell(pVictim,57669,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
// Divine Aegis
@ -10462,6 +10480,7 @@ bool InitTriggerAuraData()
isTriggerAura[SPELL_AURA_PRAYER_OF_MENDING] = true;
isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true;
isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true;
isTriggerAura[SPELL_AURA_MOD_SPELL_CRIT_CHANCE] = true;
isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true;
isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK]=true;

View file

@ -1160,12 +1160,15 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Points Of Interest Data..." );
objmgr.LoadPointsOfInterest();
sLog.outString( "Loading Pet Create Spells..." );
objmgr.LoadPetCreateSpells();
sLog.outString( "Loading Creature Data..." );
objmgr.LoadCreatures();
sLog.outString( "Loading pet levelup spells..." );
spellmgr.LoadPetLevelupSpellMap();
sLog.outString( "Loading pet default spell additional to levelup spells..." );
spellmgr.LoadPetDefaultSpells();
sLog.outString( "Loading Creature Addon Data..." );
sLog.outString();
objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
@ -1232,9 +1235,6 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading spell pet auras..." );
spellmgr.LoadSpellPetAuras();
sLog.outString( "Loading pet levelup spells..." );
spellmgr.LoadPetLevelupSpellMap();
sLog.outString( "Loading Player Create Info & Level Stats..." );
sLog.outString();
objmgr.LoadPlayerInfo();

View file

@ -537,7 +537,7 @@ int WorldSocket::handle_input_payload (void)
int WorldSocket::handle_input_missing_data (void)
{
char buf [1024];
char buf [4096];
ACE_Data_Block db ( sizeof (buf),
ACE_Message_Block::MB_DATA,

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7877"
#define REVISION_NR "7887"
#endif // __REVISION_NR_H__