*Merge to Trinity 673.

--HG--
branch : trunk
This commit is contained in:
megamage
2008-12-26 16:27:41 -06:00
25 changed files with 591 additions and 231 deletions
+5
View File
@@ -0,0 +1,5 @@
DELETE FROM `spell_script_target` WHERE entry IN (33655, 33633, 44374);
INSERT INTO `spell_script_target` VALUES
(33655,0,183350),
(33633,0,183351),
(44374,1,24722);
+6
View File
@@ -0,0 +1,6 @@
delete from creature where id=17318;
update creature_template set scriptname='npc_geezle' where entry=17318;
delete from event_scripts where id=10675;
insert into event_scripts () VALUES (10675, 0, 10, 17318, 120000, 0, -5134.3, -11250.3, 5.29568, 6.23554),
(10675, 72, 7, 9531, 0, 0, 0, 0, 0, 0);
update quest_template set specialflags=2, reqcreatureorgoid1=0, reqcreatureorgocount1=0 where entry=9531;
+1
View File
@@ -0,0 +1 @@
update creature_template set scriptname='npc_professor_dabiri' where entry=20907;
@@ -735,6 +735,56 @@ void ScriptedAI::DoTeleportAll(float x, float y, float z, float o)
i_pl->TeleportTo(m_creature->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
}
Unit* ScriptedAI::FindCreature(uint32 entry, uint32 range)
{
CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(pair);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
std::list<Creature*> NPCList;
Trinity::AllCreaturesOfEntryInRange check(m_creature, entry, range);
Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(NPCList, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher);
CellLock<GridReadGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap()));
if (!NPCList.empty())
{
for(std::list<Creature*>::iterator itr = NPCList.begin(); itr != NPCList.end(); ++itr)
{
return Creature::GetUnit((*m_creature), (*itr)->GetGUID());
}
}else error_log("SD2 ERROR: Entry: %u not found!", entry); return NULL;
}
GameObject* ScriptedAI::FindGameObject(uint32 entry)
{
CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(pair);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
std::list<GameObject*> GOList;
Trinity::AllGameObjectsWithEntryInGrid go_check(entry);
Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(GOList, go_check);
TypeContainerVisitor
<Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid>, GridTypeMapContainer> go_visit(go_search);
CellLock<GridReadGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, go_visit, *(m_creature->GetMap()));
if (!GOList.empty())
{
for(std::list<GameObject*>::iterator itr = GOList.begin(); itr != GOList.end(); ++itr)
{
return (*itr);
}
}
else error_log("SD2 ERROR: GameObject Entry: %u not found!", entry); return NULL;
}
Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
{
@@ -148,6 +148,12 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
void DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o);
void DoTeleportAll(float x, float y, float z, float o);
//Get a single creature of given entry
Unit* FindCreature(uint32 entry, uint32 range);
//Get a single gameobject of given entry
GameObject* FindGameObject(uint32 entry);
//Returns friendly unit with the most amount of hp missing from max hp
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff = 1);
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Azuremyst_Isle
SD%Complete: 75
SDComment: Quest support: 9283, 9537, 9582, 9554(special flight path, proper model for mount missing). Injured Draenei cosmetic only
SDComment: Quest support: 9283, 9537, 9582, 9554, 9531(special flight path, proper model for mount missing). Injured Draenei cosmetic only
SDCategory: Azuremyst Isle
EndScriptData */
@@ -27,6 +27,7 @@ npc_engineer_spark_overgrind
npc_injured_draenei
npc_magwin
npc_susurrus
npc_geezle
EndContentData */
#include "precompiled.h"
@@ -462,6 +463,150 @@ bool GossipSelect_npc_susurrus(Player *player, Creature *_Creature, uint32 sende
return true;
}
/*######
## npc_geezle
######*/
#define GEEZLE_SAY_1 "What's the big idea, Spark?"
#define SPARK_SAY_2 "What's the big idea? You nearly blew my cover, idiot! I told you to put the compass and navigation maps somewhere safe - not out in the open for any fool to discover."
#define SPARK_SAY_3 "The Master has gone to great lengths to secure information about the whereabouts of the Exodar. You could have blown the entire operation, including the cover of our spy on the inside."
#define GEEZLE_SAY_4 "Relax, Spark! I have it all under control. We'll strip mine the Exodar right out from under 'em - making both you and I very, very rich in the process."
#define SPARK_SAY_5 "Relax? Do you know what Kael'thas does to those that fail him, Geezle? Eternal suffering and pain... Do NOT screw this up, fool."
#define SPARK_SAY_6 "Our Bloodmyst scouts have located our contact. The fool, Velen, will soon leave himself open and defenseless -- long enough for us to strike! Now get out of my sight before I vaporize you..."
#define GEEZLE_SAY_7 "Yes, sir. It won't happen again..."
#define EMOTE_SPARK "picks up the naga flag."
#define MOB_SPARK 17243
#define GO_NAGA_FLAG 181694
static float SparkPos[4] = {-5030.95, -11291.99, 7.97};
struct TRINITY_DLL_DECL npc_geezleAI : public ScriptedAI
{
npc_geezleAI(Creature *c) : ScriptedAI(c) {Reset();}
std::list<GameObject*> FlagList;
uint64 SparkGUID;
uint32 Step;
uint32 SayTimer;
bool EventStarted;
void Reset()
{
SparkGUID = 0;
Step = 0;
StartEvent();
}
void Aggro(Unit* who){}
void StartEvent()
{
Step = 1;
EventStarted = true;
Creature* Spark = m_creature->SummonCreature(MOB_SPARK, SparkPos[0], SparkPos[1], SparkPos[2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000);
SparkGUID = Spark->GetGUID();
Spark->setActive(true);
Spark->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
m_creature->GetMotionMaster()->MovePoint(0, -5092.26, -11252, 0.71);
Spark->GetMotionMaster()->MovePoint(0, -5080.70, -11253.61, 0.56);
SayTimer = 23000;
}
uint32 NextStep(uint32 Step)
{
Unit* Spark = Unit::GetUnit((*m_creature), SparkGUID);
switch(Step)
{
case 0: return 99999;
case 1:
//DespawnNagaFlag(true);
((Creature*)Spark)->TextEmote(EMOTE_SPARK, NULL, false);
return 1000;
case 2:
DoSay(GEEZLE_SAY_1, LANG_UNIVERSAL, Spark);
Spark->SetInFront(m_creature);
m_creature->SetInFront(Spark);
return 5000;
case 3:
((Creature*)Spark)->Say(SPARK_SAY_2, LANG_UNIVERSAL, NULL);
return 7000;
case 4:
((Creature*)Spark)->Say(SPARK_SAY_3, LANG_UNIVERSAL, NULL);
return 8000;
case 5:
DoSay(GEEZLE_SAY_4, LANG_UNIVERSAL, Spark);
return 8000;
case 6:
((Creature*)Spark)->Say(SPARK_SAY_5, LANG_UNIVERSAL, NULL);
return 9000;
case 7:
((Creature*)Spark)->Say(SPARK_SAY_6, LANG_UNIVERSAL, NULL);
return 8000;
case 8:
DoSay(GEEZLE_SAY_7, LANG_UNIVERSAL, Spark);
return 2000;
case 9:
m_creature->GetMotionMaster()->MoveTargetedHome();
Spark->GetMotionMaster()->MovePoint(0, -5030.95, -11291.99, 7.97);
return 20000;
case 10:
Spark->DealDamage(Spark,Spark->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
//DespawnNagaFlag(false);
m_creature->SetVisibility(VISIBILITY_OFF);
default: return 99999999;
}
}
void DespawnNagaFlag(bool despawn)
{
CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(pair);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
Trinity::AllGameObjectsWithEntryInGrid go_check(GO_NAGA_FLAG);
Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(FlagList, go_check);
TypeContainerVisitor
<Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid>, GridTypeMapContainer> go_visit(go_search);
CellLock<GridReadGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, go_visit, *(m_creature->GetMap()));
Player* player = NULL;
if (!FlagList.empty())
{
for(std::list<GameObject*>::iterator itr = FlagList.begin(); itr != FlagList.end(); ++itr)
{
//TODO: Found how to despawn and respawn
if(despawn)
(*itr)->RemoveFromWorld();
else
(*itr)->Respawn();
}
} else error_log("SD2 ERROR: FlagList is empty!");
}
void UpdateAI(const uint32 diff)
{
if(SayTimer < diff)
{
if(EventStarted)
{
SayTimer = NextStep(Step++);
}
}else SayTimer -= diff;
}
};
CreatureAI* GetAI_npc_geezleAI(Creature *_Creature)
{
return new npc_geezleAI(_Creature);
}
/*######
##
######*/
@@ -498,4 +643,10 @@ void AddSC_azuremyst_isle()
newscript->pGossipHello = &GossipHello_npc_susurrus;
newscript->pGossipSelect = &GossipSelect_npc_susurrus;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_geezle";
newscript->GetAI = &GetAI_npc_geezleAI;
newscript->RegisterSelf();
}
@@ -30,7 +30,7 @@ EndScriptData */
//Spells
#define SPELL_MOLTEN_PUNCH 40126
#define SPELL_HURTFUL_STRIKE 41926
#define SPELL_HATEFUL_STRIKE 41926
#define SPELL_MOLTEN_FLAME 40980
#define SPELL_VOLCANIC_ERUPTION 40117
#define SPELL_VOLCANIC_SUMMON 40276
@@ -63,7 +63,7 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
uint32 SwitchTargetTimer;
uint32 PhaseSwitchTimer;
uint32 SummonVolcanoTimer;
uint32 HurtfulStrikeTimer;
uint32 HatefulStrikeTimer;
uint32 BerserkTimer;
bool Phase1;
@@ -82,7 +82,7 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
else ToggleDoors(false);
}
HurtfulStrikeTimer = 5000;
HatefulStrikeTimer = 5000;
SummonFlameTimer = 20000;
SwitchTargetTimer = 90000;
PhaseSwitchTimer = 60000;
@@ -123,7 +123,7 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
void JustSummoned(Creature *summon) {summons.Summon(summon);}
void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);}
Unit* CalculateHurtfulStrikeTarget()
Unit* CalculateHatefulStrikeTarget()
{
uint32 health = 0;
Unit* target = NULL;
@@ -166,14 +166,14 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI
if(Phase1)
{
if(HurtfulStrikeTimer < diff)
if(HatefulStrikeTimer < diff)
{
if(Unit* target = CalculateHurtfulStrikeTarget())
if(Unit* target = CalculateHatefulStrikeTarget())
{
DoCast(target, SPELL_HURTFUL_STRIKE);
HurtfulStrikeTimer = 5000;
DoCast(target, SPELL_HATEFUL_STRIKE);
HatefulStrikeTimer = 5000;
}
}else HurtfulStrikeTimer -= diff;
}else HatefulStrikeTimer -= diff;
}
if(!Phase1)
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Blackrock_Depths
SD%Complete: 95
SDComment: Quest support: 4001, 4342, 7604. Vendor Lokhtos Darkbargainer.
SDComment: Quest support: 4001, 4342, 7604, 4322. Vendor Lokhtos Darkbargainer.
SDCategory: Blackrock Depths
EndScriptData */
@@ -25,12 +25,15 @@ EndScriptData */
mob_phalanx
npc_kharan_mighthammer
npc_lokhtos_darkbargainer
npc_dughal_stormwing
npc_marshal_windsor
npc_marshal_reginald_windsor
npc_tobias_seecher
EndContentData */
#include "precompiled.h"
#include "../../npc/npc_escortAI.h"
#include "def_blackrock_depths.h"
#include "GameObject.h"
/*######
## mob_phalanx
@@ -281,6 +284,7 @@ CreatureAI* GetAI_npc_dughal_stormwing(Creature *_Creature)
dughal_stormwingAI->AddWaypoint(0, 280.42,-82.86, -77.12,0);
dughal_stormwingAI->AddWaypoint(1, 287.64,-87.01, -76.79,0);
dughal_stormwingAI->AddWaypoint(2, 354.63,-64.95, -67.53,0);
return (CreatureAI*)dughal_stormwingAI;
}
bool GossipHello_npc_dughal_stormwing(Player *player, Creature *_Creature)
@@ -425,6 +429,7 @@ struct TRINITY_DLL_DECL npc_marshal_windsorAI : public npc_escortAI
CreatureAI* GetAI_npc_marshal_windsor(Creature *_Creature)
{
npc_marshal_windsorAI* marshal_windsorAI = new npc_marshal_windsorAI(_Creature);
marshal_windsorAI->AddWaypoint(0, 316.336,-225.528, -77.7258,7000);
marshal_windsorAI->AddWaypoint(1, 316.336,-225.528, -77.7258,2000);
marshal_windsorAI->AddWaypoint(2, 322.96,-207.13, -77.87,0);
@@ -445,6 +450,7 @@ CreatureAI* GetAI_npc_marshal_windsor(Creature *_Creature)
marshal_windsorAI->AddWaypoint(17, 403.61,-51.71, -63.92,2000);
marshal_windsorAI->AddWaypoint(18, 403.61,-51.71, -63.92,1000);
marshal_windsorAI->AddWaypoint(19, 403.61,-51.71, -63.92,0);
return (CreatureAI*)marshal_windsorAI;
}
@@ -545,8 +551,8 @@ struct TRINITY_DLL_DECL npc_marshal_reginald_windsorAI : public npc_escortAI
break;
case 32:
m_creature->Say(SAY_REGINALD_WINDSOR_20_2, LANG_UNIVERSAL, PlayerGUID);
PlayerStart->GroupEventHappens(QUEST_JAIL_BREAK,m_creature);
pInstance->SetData(DATA_SHILL,ENCOUNTER_STATE_ENDED);
PlayerStart->GroupEventHappens(QUEST_JAIL_BREAK, m_creature);
pInstance->SetData(DATA_SHILL, ENCOUNTER_STATE_ENDED);
break;
}
}
@@ -636,6 +642,7 @@ struct TRINITY_DLL_DECL npc_marshal_reginald_windsorAI : public npc_escortAI
CreatureAI* GetAI_npc_marshal_reginald_windsor(Creature *_Creature)
{
npc_marshal_reginald_windsorAI* marshal_reginald_windsorAI = new npc_marshal_reginald_windsorAI(_Creature);
marshal_reginald_windsorAI->AddWaypoint(0, 403.61,-52.71, -63.92,4000);
marshal_reginald_windsorAI->AddWaypoint(1, 403.61,-52.71, -63.92,4000);
marshal_reginald_windsorAI->AddWaypoint(2, 406.33,-54.87, -63.95,0);
@@ -667,10 +674,11 @@ CreatureAI* GetAI_npc_marshal_reginald_windsor(Creature *_Creature)
marshal_reginald_windsorAI->AddWaypoint(28, 484.21,-56.24, -62.43,0);
marshal_reginald_windsorAI->AddWaypoint(29, 470.39,-6.01, -70.10,0);
marshal_reginald_windsorAI->AddWaypoint(30, 451.27,30.85, -70.07,0);
marshal_reginald_windsorAI->AddWaypoint(31, 452.45,29.85, -70.37,1500); //tezi trqbva da se opravqt
marshal_reginald_windsorAI->AddWaypoint(31, 452.45,29.85, -70.37,1500);
marshal_reginald_windsorAI->AddWaypoint(32, 452.45,29.85, -70.37,7000);
marshal_reginald_windsorAI->AddWaypoint(33, 452.45,29.85, -70.37,10000);
marshal_reginald_windsorAI->AddWaypoint(34, 451.27,31.85, -70.07,0);
return (CreatureAI*)marshal_reginald_windsorAI;
}
@@ -742,6 +750,7 @@ CreatureAI* GetAI_npc_tobias_seecher(Creature *_Creature)
tobias_seecherAI->AddWaypoint(2, 533.59, -249.38, -67.04);
tobias_seecherAI->AddWaypoint(3, 519.44, -217.02, -59.34);
tobias_seecherAI->AddWaypoint(4, 506.55, -153.49, -62.34);
return (CreatureAI*)tobias_seecherAI;
}
@@ -161,7 +161,9 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
case 0:
{
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
setCage(true);
GameObject* Cage = FindGameObject(GO_CAGE);
if(Cage)
Cage->SetGoState(0);
DoSay(SAY_START, LANG_UNIVERSAL, player);
break;
}
@@ -196,7 +198,9 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
case 33:
m_creature->SetOrientation(5.858011);
DoSay(SAY_END2, LANG_UNIVERSAL, player);
captainAnswer();
Unit* CaptainHelios = FindCreature(NPC_CAPTAIN_HELIOS, 50);
if(CaptainHelios)
((Creature*)CaptainHelios)->Say(CAPTAIN_ANSWER, LANG_UNIVERSAL, PlayerGUID);
break;
}
}
@@ -207,7 +211,10 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
{
if (!IsBeingEscorted)
m_creature->setFaction(1602);
setCage(false);
GameObject* Cage = FindGameObject(GO_CAGE);
if(Cage)
Cage->SetGoState(1);
}
void JustDied(Unit* killer)
@@ -224,57 +231,6 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
{
npc_escortAI::UpdateAI(diff);
}
void setCage(bool open)
{
CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(pair);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
Trinity::AllGameObjectsWithEntryInGrid go_check(GO_CAGE);
Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid> go_search(CageList, go_check);
TypeContainerVisitor
<Trinity::GameObjectListSearcher<Trinity::AllGameObjectsWithEntryInGrid>, GridTypeMapContainer> go_visit(go_search);
CellLock<GridReadGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, go_visit, *(m_creature->GetMap()));
if (!CageList.empty())
{
for(std::list<GameObject*>::iterator itr = CageList.begin(); itr != CageList.end(); ++itr)
{
if( open )
(*itr)->SetGoState(0);
else
(*itr)->SetGoState(1);
}
} else error_log("SD2 ERROR: CageList is empty!");
}
void captainAnswer()
{
CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(pair);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
std::list<Creature*> NPCList;
Trinity::AllCreaturesOfEntryInRange check(m_creature, NPC_CAPTAIN_HELIOS, 100);
Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(NPCList, check);
TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher);
CellLock<GridReadGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap()));
if (!NPCList.empty())
{
for(std::list<Creature*>::iterator itr = NPCList.begin(); itr != NPCList.end(); ++itr)
{
(*itr)->Say(CAPTAIN_ANSWER, LANG_UNIVERSAL, PlayerGUID);
}
}else error_log("SD2 ERROR: Captain Helios not found!");
}
};
bool QuestAccept_npc_ranger_lilatha(Player* player, Creature* creature, Quest const* quest)
@@ -670,11 +670,13 @@ bool AreaTrigger_at_commander_dawnforge(Player *player, AreaTriggerEntry *at)
## npc_protectorate_nether_drake
######*/
#define GOSSIP_ITEM "I'm ready to fly! Take me up, dragon!"
bool GossipHello_npc_protectorate_nether_drake(Player *player, Creature *_Creature)
{
//On Nethery Wings
if (player->GetQuestStatus(10438) == QUEST_STATUS_INCOMPLETE && player->HasItemCount(29778,1) )
player->ADD_GOSSIP_ITEM(0, "Fly me to Ultris", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
@@ -697,6 +699,49 @@ bool GossipSelect_npc_protectorate_nether_drake(Player *player, Creature *_Creat
return true;
}
/*######
## npc_professor_dabiri
######*/
#define SPELL_PHASE_DISTRUPTOR 35780
#define GOSSIP_ITEM "I need a new phase distruptor, Professor"
#define WHISPER_DABIRI "Saeed is currently engaged or awaiting orders to engage. You may check directly east of me and see if Saeed is ready for you. If he is not present then he is off fighting another battle. I recommend that you wait for him to return before attacking Dimensius."
#define QUEST_DIMENSIUS 10439
#define QUEST_ON_NETHERY_WINGS 10438
bool GossipHello_npc_professor_dabiri(Player *player, Creature *_Creature)
{
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
if(player->GetQuestStatus(QUEST_ON_NETHERY_WINGS) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(29778, 1))
player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_professor_dabiri(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (action == GOSSIP_ACTION_INFO_DEF+1)
{
_Creature->CastSpell(player, SPELL_PHASE_DISTRUPTOR, false);
player->CLOSE_GOSSIP_MENU();
}
return true;
}
bool QuestAccept_npc_professor_dabiri(Player *player, Creature *creature, Quest const *quest )
{
if(quest->GetQuestId() == QUEST_DIMENSIUS)
creature->Whisper(WHISPER_DABIRI, player->GetGUID(), false);
return true;
}
/*######
## npc_veronia
######*/
@@ -870,6 +915,13 @@ void AddSC_netherstorm()
newscript->pGossipSelect = &GossipSelect_npc_protectorate_nether_drake;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_professor_dabiri";
newscript->pGossipHello = &GossipHello_npc_professor_dabiri;
newscript->pGossipSelect = &GossipSelect_npc_professor_dabiri;
newscript->pQuestAccept = &QuestAccept_npc_professor_dabiri;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="npc_veronia";
newscript->pGossipHello = &GossipHello_npc_veronia;
@@ -467,25 +467,13 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
else {
if(LaceratingSlash_Timer < diff)
{
if(!m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT, 0))
DoCast(m_creature->getVictim(), SPELL_LACERATINGSLASH);
else
{
int32 bp0 = 3470;
m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_LACERATINGSLASH, &bp0, NULL, NULL, false);
}
DoCast(m_creature->getVictim(), SPELL_LACERATINGSLASH);
LaceratingSlash_Timer = 18000 + rand()%5000;
}else LaceratingSlash_Timer -= diff;
if(RendFlesh_Timer < diff)
{
if(!m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT, 0))
DoCast(m_creature->getVictim(), SPELL_RENDFLESH);
else
{
int32 bp1 = 4670;
m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_RENDFLESH, NULL, &bp1, NULL, false);
}
DoCast(m_creature->getVictim(), SPELL_RENDFLESH);
RendFlesh_Timer = 5000 + rand()%5000;
}else RendFlesh_Timer -= diff;
+1 -1
View File
@@ -142,7 +142,7 @@ namespace Trinity
void _Execute() { (*m_method)(m_param1, m_param2, m_param3); }
public:
_SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
: m_method(method), m_param1(param1), m_param2(param2) {}
: m_method(method), m_param1(param1), m_param2(param2), m_param3(param3) {}
_SCallback(_SCallback < ParamType1, ParamType2, ParamType3 > const& cb)
: m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
};
-1
View File
@@ -1514,7 +1514,6 @@ void Creature::DeleteFromDB()
WorldDatabase.BeginTransaction();
WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.CommitTransaction();
+4 -1
View File
@@ -446,8 +446,11 @@ void OutdoorPvPObjective::UpdateActivePlayerProximityCheck()
{
for(int team = 0; team < 2; ++team)
{
for(std::set<uint64>::iterator itr = m_ActivePlayerGuids[team].begin(); itr != m_ActivePlayerGuids[team].end(); ++ itr)
std::set<uint64>::iterator itr, next;
for(itr = m_ActivePlayerGuids[team].begin(); itr != m_ActivePlayerGuids[team].end(); itr = next)
{
next = itr;
++next;
// if the player is online
if(Player * pl = objmgr.GetPlayer(*itr))
{
+21
View File
@@ -957,6 +957,25 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
switch(GetEntry())
{
case 1964: //force of nature
SetCreateHealth(30 + 30*petlevel);
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2)));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2)));
break;
case 15352: //earth elemental 36213
SetCreateHealth(100 + 120*petlevel);
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
break;
case 15438: //fire elemental
SetCreateHealth(40*petlevel);
SetCreateMana(28 + 10*petlevel);
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
break;
default:
SetCreateMana(28 + 10*petlevel);
SetCreateHealth(28 + 30*petlevel);
@@ -966,6 +985,8 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
//damage range is then petlevel / 2
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
break;
}
break;
default:
sLog.outError("Pet have incorrect type (%u) for levelup.", getPetType());
+2 -2
View File
@@ -833,7 +833,7 @@ enum Targets
TARGET_GAMEOBJECT = 23,
//TARGET_OBJECT_OPEN
TARGET_IN_FRONT_OF_CASTER = 24,
//TARGET_UNIT_CONE_ENEMY
TARGET_UNIT_CONE_ENEMY = 24,
TARGET_DUELVSPLAYER = 25,
TARGET_UNIT_TARGET_ANY = 25,
TARGET_GAMEOBJECT_ITEM = 26,
@@ -886,7 +886,7 @@ enum Targets
TARGET_UNIT_CONE_ALLY = 59,
TARGET_UNIT_AREA_SCRIPT = 60,
TARGET_AREAEFFECT_PARTY_AND_CLASS = 61,
//TARGET_UNIT_CLASS_TARGET
TARGET_UNIT_CLASS_TARGET = 61,
TARGET_TEST = 62, // for a test spell
TARGET_DUELVSPLAYER_COORDINATES = 63,
TARGET_DEST_TARGET_ENEMY_UNKNOWN = 63,
+110 -67
View File
@@ -174,14 +174,8 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
*data >> m_targetMask;
if(m_targetMask == TARGET_FLAG_SELF)
{
//m_destX = caster->GetPositionX();
//m_destY = caster->GetPositionY();
//m_destZ = caster->GetPositionZ();
//m_unitTarget = caster;
//m_unitTargetGUID = caster->GetGUID();
return true;
}
// TARGET_FLAG_UNK2 is used for non-combat pets, maybe other?
if( m_targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2) )
if(!readGUID(*data, m_unitTargetGUID))
@@ -411,10 +405,11 @@ void Spell::FillTargetMap()
if(!m_spellInfo->Effect[i])
continue;
// TODO: find a way so this is not needed?
// for area auras always add caster as target (needed for totems for example)
if(IsAreaAuraEffect(m_spellInfo->Effect[i]))
AddUnitTarget(m_caster, i);
uint32 effectTargetType = spellmgr.EffectTargetType[m_spellInfo->Effect[i]];
// is it possible that areaaura is not applied to caster?
if(effectTargetType == SPELL_REQUIRE_NONE)
continue;
std::list<Unit*> tmpUnitMap;
uint32 targetA = m_spellInfo->EffectImplicitTargetA[i];
@@ -425,9 +420,11 @@ void Spell::FillTargetMap()
if(targetB) // In very rare case !A && B
SetTargetMap(i, targetB, tmpUnitMap);
if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] != SPELL_REQUIRE_UNIT)
if(effectTargetType != SPELL_REQUIRE_UNIT)
{
if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_DEST)
if(effectTargetType == SPELL_REQUIRE_CASTER)
AddUnitTarget(m_caster, i);
if(effectTargetType == SPELL_REQUIRE_DEST)
{
if(m_targets.HasDest() && m_spellInfo->speed > 0.0f)
{
@@ -436,7 +433,7 @@ void Spell::FillTargetMap()
m_delayMoment = (uint64) floor(dist / m_spellInfo->speed * 1000.0f);
}
}
else if(spellmgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_ITEM)
else if(effectTargetType == SPELL_REQUIRE_ITEM)
{
if(m_targets.getItemTarget())
AddItemTarget(m_targets.getItemTarget(), i);
@@ -726,7 +723,7 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
target.targetGUID = targetGUID; // Store target GUID
target.effectMask = 1<<effIndex; // Store index of effect
target.processed = false; // Effects not apply on target
target.killTarget = false;
target.damage = 0;
// Calculate hit result
if(m_originalCaster)
@@ -947,13 +944,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (!unit)
return;
if(target->killTarget)
{
// remove spell_magnet aura after first spell redirect and destroy target if its totem
if(unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->isTotem())
unit->Kill(unit);
}
// Get original caster (if exist) and calculate damage/healing from him data
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
@@ -968,8 +958,8 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
unitTarget = unit;
// Reset damage/healing counter
m_damage = 0;
m_healing = 0;
m_damage = target->damage;
m_healing = -target->damage;
// Fill base trigger info
uint32 procAttacker = m_procAttacker;
@@ -996,7 +986,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// All calculated do it!
// Do healing and triggers
if (m_healing)
if (m_healing > 0)
{
bool crit = caster->isSpellCrit(NULL, m_spellInfo, m_spellSchoolMask);
uint32 addhealth = m_healing;
@@ -1022,7 +1012,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);
}
// Do damage and triggers
else if (m_damage)
else if (m_damage > 0)
{
// Fill base damage struct (unitTarget - is real spell target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
@@ -1186,8 +1176,9 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
{
if (effectMask & (1<<effectNumber))
{
HandleEffects(unit,NULL,NULL,effectNumber,m_damageMultipliers[effectNumber]);
if ( m_applyMultiplierMask & (1 << effectNumber) )
HandleEffects(unit,NULL,NULL,effectNumber/*,m_damageMultipliers[effectNumber]*/);
//Only damage and heal spells need this
/*if ( m_applyMultiplierMask & (1 << effectNumber) )
{
// Get multiplier
float multiplier = m_spellInfo->DmgMultiplier[effectNumber];
@@ -1196,7 +1187,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier,this);
m_damageMultipliers[effectNumber] *= multiplier;
}
}*/
}
}
@@ -1476,6 +1467,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
else
radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
//Chain: 2, 6, 22, 25, 45, 77
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i];
uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
@@ -1488,6 +1480,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
}
}
if(EffectChainTarget > 1)
{
//otherwise, this multiplier is used for something else
m_damageMultipliers[i] = 1.0f;
m_applyMultiplierMask |= 1 << i;
}
switch(spellmgr.SpellTargetType[cur])
{
case TARGET_TYPE_UNIT_CASTER:
@@ -1595,7 +1594,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
switch(cur)
{
case TARGET_UNIT_AREA_ENEMY_GROUND:
case TARGET_UNIT_AREA_ENEMY_CHANNEL:
m_targets.m_targetMask |= TARGET_FLAG_DEST_LOCATION;
case TARGET_UNIT_AREA_ENEMY:
SearchAreaTarget(TagUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
@@ -2229,23 +2227,6 @@ void Spell::cast(bool skipCheck)
FillTargetMap();
// who did this hack?
// Conflagrate - consumes immolate
if ((m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE) && m_targets.getUnitTarget())
{
// for caster applied auras only
Unit::AuraList const &mPeriodic = m_targets.getUnitTarget()->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
{
if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) &&
(*i)->GetCasterGUID()==m_caster->GetGUID() )
{
m_targets.getUnitTarget()->RemoveAura((*i)->GetId(), (*i)->GetEffIndex());
break;
}
}
}
if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id))
{
for(std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
@@ -2284,13 +2265,10 @@ void Spell::cast(bool skipCheck)
return;
}
SendCastResult(castResult);
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
for(int i = 0; i < 3; ++i)
m_currentBasePoints[i] = CalculateDamage(i, NULL);
CalculateDamageDoneForAllTargets();
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
if (m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo))
@@ -2432,17 +2410,6 @@ void Spell::_handle_immediate_phase()
// Don't do spell log, if is school damage spell
if(m_spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || m_spellInfo->Effect[j] == 0)
m_needSpellLog = false;
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[j];
if(m_originalCaster)
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
// initialize multipliers
m_damageMultipliers[j] = 1.0f;
if( (m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_HEAL) &&
(EffectChainTarget > 1) )
m_applyMultiplierMask |= 1 << j;
}
// initialize Diminishing Returns Data
@@ -3500,7 +3467,7 @@ void Spell::HandleThreatSpells(uint32 spellId)
DEBUG_LOG("Spell %u, rank %u, added an additional %i threat", spellId, spellmgr.GetSpellRank(spellId), threatSpell->threat);
}
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i, float DamageMultiplier)
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i, float /*DamageMultiplier*/)
{
unitTarget = pUnitTarget;
itemTarget = pItemTarget;
@@ -3509,14 +3476,15 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
uint8 eff = m_spellInfo->Effect[i];
uint32 mechanic = m_spellInfo->EffectMechanic[i];
damage = int32(m_currentBasePoints[i] * DamageMultiplier);
sLog.outDebug( "Spell: Effect : %u", eff);
//Simply return. Do not display "immune" in red text on client
if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic))
return;
//we do not need DamageMultiplier here.
damage = CalculateDamage(i, NULL);
if(eff<TOTAL_SPELL_EFFECTS)
{
//sLog.outDebug( "WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff);
@@ -4138,7 +4106,8 @@ uint8 Spell::CanCast(bool strict)
SkillValue = 0;
// add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value)
SkillValue += m_currentBasePoints[i]/*+1*/;
// TODO: is this a hack?
SkillValue += m_currentBasePoints[i]+1;
// get the required lock value
int32 ReqValue=0;
@@ -5395,7 +5364,7 @@ Unit* Spell::SelectMagnetTarget()
{
if (targetGUID == ihit->targetGUID) // Found in list
{
(*ihit).killTarget = true;
(*ihit).damage = target->GetHealth();
break;
}
}
@@ -5573,4 +5542,78 @@ bool Spell::IsValidSingleTargetSpell(Unit const* target) const
// return false;
}
return true;
}
void Spell::CalculateDamageDoneForAllTargets()
{
float multiplier[3];
for(int i = 0; i < 3; ++i)
{
if ( m_applyMultiplierMask & (1 << i) )
{
// Get multiplier
multiplier[i] = m_spellInfo->DmgMultiplier[i];
// Apply multiplier mods
if(m_originalCaster)
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier[i], this);
}
}
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
TargetInfo &target = *ihit;
uint32 mask = target.effectMask;
if(!mask)
continue;
Unit* unit = m_caster->GetGUID()==target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
if (!unit)
continue;
if (target.missCondition==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
target.damage += CalculateDamageDone(unit, mask, multiplier);
else if (target.missCondition == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
{
if (target.reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
target.damage += CalculateDamageDone(m_caster, mask, multiplier);
}
}
}
int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *multiplier)
{
m_damage = 0;
unitTarget = unit;
for(uint32 i = 0; i < 3; ++i)
{
if (effectMask & (1<<i))
{
if(m_applyMultiplierMask & (1 << i))
{
damage = CalculateDamage(i, NULL) * m_damageMultipliers[i];
m_damageMultipliers[i] *= multiplier[i];
}
else
damage = CalculateDamage(i, NULL);
switch(m_spellInfo->Effect[i])
{
case SPELL_EFFECT_SCHOOL_DAMAGE:
SpellDamageSchoolDmg(i);
break;
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
SpellDamageWeaponDmg(i);
break;
case SPELL_EFFECT_HEAL:
SpellDamageHeal(i);
break;
}
}
}
return m_damage;
}
+6 -1
View File
@@ -538,7 +538,7 @@ class Spell
SpellMissInfo reflectResult:8;
uint8 effectMask:8;
bool processed:1;
bool killTarget:1;
int32 damage;
};
std::list<TargetInfo> m_UniqueTargetInfo;
uint8 m_needAliveTargetMask; // Mask req. alive targets
@@ -575,6 +575,11 @@ class Spell
void SearchChainTarget(std::list<Unit*> &data, Unit* pUnitTarget, float max_range, uint32 unMaxTargets);
bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
bool IsValidSingleTargetSpell(Unit const* target) const;
void CalculateDamageDoneForAllTargets();
int32 CalculateDamageDone(Unit *unit, const uint32 effectMask, float *multiplier);
void SpellDamageSchoolDmg(uint32 i);
void SpellDamageWeaponDmg(uint32 i);
void SpellDamageHeal(uint32 i);
// -------------------------------------------
//List For Triggered Spells
+64 -39
View File
@@ -307,6 +307,10 @@ void Spell::EffectEnvirinmentalDMG(uint32 i)
}
void Spell::EffectSchoolDMG(uint32 effect_idx)
{
}
void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
{
if( unitTarget && unitTarget->isAlive())
{
@@ -414,6 +418,22 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE))
damage += int32(damage*0.25f);
}
// Conflagrate - consumes immolate
if (m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE)
{
// for caster applied auras only
Unit::AuraList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
{
if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) &&
(*i)->GetCasterGUID()==m_caster->GetGUID() )
{
unitTarget->RemoveAurasDueToCasterSpell((*i)->GetId(), m_caster->GetGUID());
break;
}
}
}
break;
}
case SPELLFAMILY_DRUID:
@@ -574,6 +594,23 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
{
int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE));
damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f);
bool found = false;
// check dazed affect
Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
for(Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
{
if((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->Dispel==0)
{
found = true;
break;
}
}
//TODO: should this be put on taken but not done?
if(found)
damage += m_spellInfo->EffectBasePoints[1];
}
// Explosive Trap Effect
else if(m_spellInfo->SpellFamilyFlags & 0x00000004)
@@ -1338,7 +1375,7 @@ void Spell::EffectDummy(uint32 i)
//Life Tap (only it have this with dummy effect)
if (m_spellInfo->SpellFamilyFlags == 0x40000)
{
float cost = m_currentBasePoints[0];//+1;
float cost = damage;
if(Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this);
@@ -1458,29 +1495,6 @@ void Spell::EffectDummy(uint32 i)
}
break;
case SPELLFAMILY_HUNTER:
// Steady Shot
if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
{
if( !unitTarget || !unitTarget->isAlive())
return;
bool found = false;
// check dazed affect
Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
for(Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
{
if((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->Dispel==0)
{
found = true;
break;
}
}
if(found)
m_damage+= damage;
return;
}
// Kill command
if(m_spellInfo->SpellFamilyFlags & 0x00080000000000LL)
{
@@ -2155,7 +2169,7 @@ void Spell::EffectApplyAura(uint32 i)
sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[i]);
Aura* Aur = CreateAura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, caster, m_CastItem);
Aura* Aur = CreateAura(m_spellInfo, i, &damage, unitTarget, caster, m_CastItem);
// Now Reduce spell duration using data received at spell hit
int32 duration = Aur->GetAuraMaxDuration();
@@ -2205,7 +2219,7 @@ void Spell::EffectApplyAura(uint32 i)
if (AdditionalSpellInfo)
{
// applied at target by target
Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, &m_currentBasePoints[0], unitTarget,unitTarget, 0);
Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, NULL, unitTarget,unitTarget, 0);
unitTarget->AddAura(AdditionalAura);
sLog.outDebug("Spell: Additional Aura is: %u", AdditionalSpellInfo->EffectApplyAuraName[0]);
}
@@ -2372,10 +2386,16 @@ void Spell::EffectPowerBurn(uint32 i)
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
new_damage = int32(new_damage*multiplier);
m_damage+=new_damage;
//m_damage+=new_damage; should not apply spell bonus
//TODO: no log
unitTarget->ModifyHealth(-new_damage);
}
void Spell::EffectHeal( uint32 /*i*/ )
{
}
void Spell::SpellDamageHeal(uint32 /*i*/)
{
if( unitTarget && unitTarget->isAlive() && damage >= 0)
{
@@ -2447,7 +2467,7 @@ void Spell::EffectHeal( uint32 /*i*/ )
else
addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
m_healing+=addhealth;
m_damage -= addhealth;
}
}
@@ -2548,7 +2568,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)
// TODO: maybe all this can be replaced by using correct calculated `damage` value
if(pProto->Class != ITEM_CLASS_CONSUMABLE || m_spellInfo->SpellFamilyName != SPELLFAMILY_MAGE)
{
num_to_add = m_currentBasePoints[i];
num_to_add = damage;
/*int32 basePoints = m_currentBasePoints[i];
int32 randomPoints = m_spellInfo->EffectDieSides[i];
if (randomPoints)
@@ -2560,7 +2580,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)
num_to_add = 1;
else if(player->getLevel() >= m_spellInfo->spellLevel)
{
num_to_add = m_currentBasePoints[i];
num_to_add = damage;
/*int32 basePoints = m_currentBasePoints[i];
float pointPerLevel = m_spellInfo->EffectRealPointsPerLevel[i];
num_to_add = basePoints + 1 + uint32((player->getLevel() - m_spellInfo->spellLevel)*pointPerLevel);*/
@@ -2974,7 +2994,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)
SkillId = SKILL_LOCKPICKING;
// skill bonus provided by casting spell (mostly item spells)
uint32 spellSkillBonus = uint32(m_currentBasePoints[0]/*+1*/);
uint32 spellSkillBonus = uint32(damage/*m_currentBasePoints[0]+1*/);
uint32 reqSkillValue = lockInfo->Skill[0];
@@ -3154,7 +3174,7 @@ void Spell::EffectApplyAreaAura(uint32 i)
if(!unitTarget->isAlive())
return;
AreaAura* Aur = new AreaAura(m_spellInfo, i, &m_currentBasePoints[i], unitTarget, m_caster, m_CastItem);
AreaAura* Aur = new AreaAura(m_spellInfo, i, &damage, unitTarget, m_caster, m_CastItem);
unitTarget->AddAura(Aur);
}
@@ -4257,6 +4277,10 @@ void Spell::EffectTaunt(uint32 /*i*/)
}
void Spell::EffectWeaponDmg(uint32 i)
{
}
void Spell::SpellDamageWeaponDmg(uint32 i)
{
if(!unitTarget)
return;
@@ -4543,9 +4567,10 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)
if(!unitTarget->isAlive())
return;
uint32 heal = m_caster->GetMaxHealth();
m_healing+=heal;
uint32 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
unitTarget->SetHealth(unitTarget->GetMaxHealth());
if(m_originalCaster)
m_originalCaster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);
}
void Spell::EffectInterruptCast(uint32 i)
@@ -5199,8 +5224,8 @@ void Spell::EffectDuel(uint32 i)
// Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities)
// Don't have to check the target's map since you cannot challenge someone across maps
uint32 mapid = caster->GetMapId();
if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)
if(caster->GetMap()->Instanceable())
//if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)
{
SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
return;
@@ -5485,7 +5510,7 @@ void Spell::EffectEnchantHeldItem(uint32 i)
uint32 enchant_id = m_spellInfo->EffectMiscValue[i];
int32 duration = GetSpellDuration(m_spellInfo); //Try duration index first ..
if(!duration)
duration = m_currentBasePoints[i];//+1; //Base points after ..
duration = damage;//+1; //Base points after ..
if(!duration)
duration = 10; //10 seconds for enchants which don't have listed duration
@@ -5787,7 +5812,7 @@ void Spell::EffectReputation(uint32 i)
Player *_player = (Player*)unitTarget;
int32 rep_change = m_currentBasePoints[i];//+1; // field store reputation change -1
int32 rep_change = damage;//+1; // field store reputation change -1
uint32 faction_id = m_spellInfo->EffectMiscValue[i];
+39 -1
View File
@@ -73,6 +73,14 @@ SpellMgr::SpellMgr()
case SPELL_EFFECT_PROSPECTING:
EffectTargetType[i] = SPELL_REQUIRE_ITEM;
break;
//caster must be pushed otherwise no sound
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
EffectTargetType[i] = SPELL_REQUIRE_CASTER;
break;
default:
EffectTargetType[i] = SPELL_REQUIRE_UNIT;
break;
@@ -113,7 +121,8 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_AREA_ENTRY:
case TARGET_UNIT_AREA_PARTY_GROUND:
case TARGET_UNIT_AREA_PARTY:
case TARGET_UNIT_AREA_ENEMY_CHANNEL:
//case TARGET_UNIT_AREA_ENEMY_CHANNEL:
//case TARGET_UNIT_AREA_ALLY_CHANNEL:
SpellTargetType[i] = TARGET_TYPE_AREA_DEST;
break;
case TARGET_DEST_TARGET_ENEMY:
@@ -151,6 +160,35 @@ SpellMgr::SpellMgr()
SpellTargetType[i] = TARGET_TYPE_DEFAULT;
}
}
for(int i = 0; i < TOTAL_SPELL_TARGETS; ++i)
{
switch(i)
{
case TARGET_UNIT_AREA_ENEMY_GROUND:
case TARGET_UNIT_AREA_ENEMY:
case TARGET_UNIT_AREA_ALLY_GROUND:
case TARGET_UNIT_AREA_ALLY:
case TARGET_UNIT_AREA_ENTRY_GROUND:
case TARGET_UNIT_AREA_ENTRY:
case TARGET_UNIT_AREA_PARTY_GROUND:
case TARGET_UNIT_AREA_PARTY:
//Check persistant aura seperately
//case TARGET_UNIT_AREA_ENEMY_CHANNEL:
//case TARGET_UNIT_AREA_ALLY_CHANNEL:
case TARGET_UNIT_PARTY_TARGET:
case TARGET_UNIT_PARTY_CASTER:
case TARGET_UNIT_CONE_ENEMY:
case TARGET_UNIT_CONE_ALLY:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
case TARGET_UNIT_RAID:
IsAreaEffectTarget[i] = true;
break;
default:
IsAreaEffectTarget[i] = false;
break;
}
}
}
SpellMgr::~SpellMgr()
+5 -28
View File
@@ -259,6 +259,7 @@ enum SpellEffectTargetTypes
SPELL_REQUIRE_UNIT,
SPELL_REQUIRE_DEST,
SPELL_REQUIRE_ITEM,
SPELL_REQUIRE_CASTER,
};
enum SpellSelectTargetTypes
@@ -379,38 +380,14 @@ bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId);
bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id);
inline bool IsAreaEffectTarget( Targets target )
{
switch (target )
{
case TARGET_AREAEFFECT_CUSTOM:
case TARGET_ALL_ENEMY_IN_AREA:
case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
case TARGET_ALL_PARTY_AROUND_CASTER:
case TARGET_ALL_AROUND_CASTER:
case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
case TARGET_ALL_PARTY:
case TARGET_ALL_PARTY_AROUND_CASTER_2:
case TARGET_AREAEFFECT_PARTY:
case TARGET_AREAEFFECT_CUSTOM_2:
case TARGET_AREAEFFECT_PARTY_AND_CLASS:
case TARGET_IN_FRONT_OF_CASTER:
case TARGET_ALL_FRIENDLY_UNITS_IN_AREA:
return true;
default:
break;
}
return false;
}
static bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS];
inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
{
if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[0])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[0])))
if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[0]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[0]])
return true;
if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[1])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[1])))
if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[1]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[1]])
return true;
if(IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[2])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[2])))
if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[2]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[2]])
return true;
return false;
}
+17
View File
@@ -982,6 +982,23 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
frost = 0;
SetBonusDamage( int32(frost * 0.4f));
}
//force of nature
else if(GetEntry() == 1964)
{
int32 spellDmg = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE);
if(spellDmg > 0)
SetBonusDamage(int32(spellDmg * 0.09f));
}
//greater fire elemental
else if(GetEntry() == 15438)
{
if(Unit* shaman = owner->GetOwner())
{
int32 spellDmg = int32(shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
if(spellDmg > 0)
SetBonusDamage(int32(spellDmg * 0.4f));
}
}
}
SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP);
+4 -2
View File
@@ -2997,7 +2997,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
}
}
if(GetTypeId()!=TYPEID_PLAYER && !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) && !((Creature*)this)->isPet() )
if(GetTypeId()!=TYPEID_PLAYER && !(((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH) && !((Creature*)this)->isPet() && !SpellCasted /*Only autoattack can be crushing blow*/ )
{
// mobs can score crushing blows if they're 3 or more levels above victim
// or when their weapon skill is 15 or more above victim's defense skill
@@ -8695,8 +8695,10 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
TakenTotalMod *= (mod+100.0f)/100.0f;
}
break;
//This is changed in WLK, using aura 255
//Mangle
case 2312:
case 44955:
for(int j=0;j<3;j++)
{
if(GetEffectMechanic(spellProto, j)==MECHANIC_BLEED)
@@ -12352,7 +12354,7 @@ uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectT
break;
}
if(IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetA[i])) || IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetB[i])))
if(IsAreaEffectTarget[spellProto->EffectImplicitTargetA[i]] || IsAreaEffectTarget[spellProto->EffectImplicitTargetB[i]])
AreaEffect = true;
}
+9 -3
View File
@@ -36,11 +36,17 @@ void
WaypointMovementGenerator<Creature>::Initialize(Creature &u)
{
u.StopMoving();
i_nextMoveTime.Reset(0);
i_currentNode = -1;
if(!path_id)
path_id = u.GetWaypointPath();
waypoints = WaypointMgr.GetPath(path_id);
waypoints = WaypointMgr.GetPath(path_id);
if(waypoints && waypoints->size())
{
Traveller<Creature> traveller(unit);
node = *(waypoints->at(i_currentNode));
InitTraveller(u,node);
i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
}
}
template<>
+1 -1
View File
@@ -81,7 +81,7 @@ class TRINITY_DLL_SPEC WaypointMovementGenerator
private:
WaypointData node;
uint32 i_currentNode, path_id;
uint32 path_id;
TimeTrackerSmall i_nextMoveTime;
WaypointPath *waypoints;
bool repeating, StopedByPlayer;