diff options
Diffstat (limited to 'src')
31 files changed, 763 insertions, 94 deletions
diff --git a/src/bindings/scripts/scripts/item/item_scripts.cpp b/src/bindings/scripts/scripts/item/item_scripts.cpp index 889a4d900e8..22e437079f3 100644 --- a/src/bindings/scripts/scripts/item/item_scripts.cpp +++ b/src/bindings/scripts/scripts/item/item_scripts.cpp @@ -41,6 +41,7 @@ item_voodoo_charm Provide proper error message and target(q256 item_vorenthals_presence(i30259) Prevents abuse of this item item_yehkinyas_bramble(i10699) Allow cast spell on vale screecher only and remove corpse if cast sucessful (q3520) item_zezzak_shard(i31463) Quest The eyes of Grillok (q10813). Prevents abuse +item_inoculating_crystal Quest Inoculating. Prevent abuse EndContentData */ #include "precompiled.h" @@ -286,6 +287,25 @@ bool ItemUse_item_muiseks_vessel(Player *player, Item* _Item, SpellCastTargets c } /*##### +# item_inoculating_crystal +#####*/ + +bool ItemUse_item_inoculating_crystal(Player *player, Item* _Item, SpellCastTargets const& targets) +{ + if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT && + targets.getUnitTarget()->GetEntry() == 16518 ) + return false; + + WorldPacket data(SMSG_CAST_FAILED, (4+2)); // prepare packet error message + data << uint32(_Item->GetEntry()); // itemId + data << uint8(SPELL_FAILED_BAD_TARGETS); // reason + player->GetSession()->SendPacket(&data); // send message: Invalid target + + player->SendEquipError(EQUIP_ERR_NONE,_Item,NULL); // break spell + return true; +} + +/*##### # item_razorthorn_flayer_gland #####*/ @@ -520,6 +540,11 @@ void AddSC_item_scripts() newscript->RegisterSelf(); newscript = new Script; + newscript->Name="item_inoculating_crystal"; + newscript->pItemUse = &ItemUse_item_inoculating_crystal; + newscript->RegisterSelf(); + + newscript = new Script; newscript->Name="item_razorthorn_flayer_gland"; newscript->pItemUse = &ItemUse_item_razorthorn_flayer_gland; newscript->RegisterSelf(); diff --git a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp index 92ce2caaa40..b4eefc43ce1 100644 --- a/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp +++ b/src/bindings/scripts/scripts/zone/azuremyst_isle/azuremyst_isle.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Azuremyst_Isle SD%Complete: 75 -SDComment: Quest support: 9283, 9537, 9582, 9554, 9531(special flight path, proper model for mount missing). Injured Draenei cosmetic only +SDComment: Quest support: 9283, 9537, 9582, 9554, 9531, 9303(special flight path, proper model for mount missing). Injured Draenei cosmetic only SDCategory: Azuremyst Isle EndScriptData */ @@ -28,6 +28,7 @@ npc_injured_draenei npc_magwin npc_susurrus npc_geezle +mob_nestlewood_owlkin EndContentData */ #include "precompiled.h" @@ -608,9 +609,60 @@ CreatureAI* GetAI_npc_geezleAI(Creature *_Creature) } /*###### -## +## mob_nestlewood_owlkin ######*/ +#define INOCULATION_CHANNEL 29528 +#define INOCULATED_OWLKIN 16534 + +struct TRINITY_DLL_DECL mob_nestlewood_owlkinAI : public ScriptedAI +{ + mob_nestlewood_owlkinAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 ChannelTimer; + bool Channeled; + bool Hitted; + + void Reset() + { + ChannelTimer = 0; + Channeled = false; + Hitted = false; + } + + void Aggro(Unit *who){} + + void SpellHit(Unit* caster, const SpellEntry* spell) + { + if(!caster) + return; + + if(caster->GetTypeId() == TYPEID_PLAYER && spell->Id == INOCULATION_CHANNEL) + { + ChannelTimer = 3000; + Hitted = true; + } + } + + void UpdateAI(const uint32 diff) + { + if(ChannelTimer < diff && !Channeled && Hitted) + { + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_creature->RemoveCorpse(); + m_creature->SummonCreature(INOCULATED_OWLKIN, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 180000); + Channeled = true; + }else ChannelTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_nestlewood_owlkinAI(Creature *_Creature) +{ + return new mob_nestlewood_owlkinAI (_Creature); +} + void AddSC_azuremyst_isle() { Script *newscript; @@ -649,4 +701,9 @@ void AddSC_azuremyst_isle() newscript->GetAI = &GetAI_npc_geezleAI; newscript->RegisterSelf(); + newscript = new Script; + newscript->Name="mob_nestlewood_owlkin"; + newscript->GetAI = &GetAI_mob_nestlewood_owlkinAI; + newscript->RegisterSelf(); + } diff --git a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp index cf35c4b9bc7..879076e1067 100644 --- a/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp +++ b/src/bindings/scripts/scripts/zone/barrens/the_barrens.cpp @@ -366,7 +366,7 @@ CreatureAI* GetAI_npc_twiggy_flathead(Creature *_Creature) } /*##### -## npc_wizzlecrank_shredder TODO: Pilot scripting +## npc_wizzlecrank_shredder NOTE: Part2 will be in ACID #####*/ #define SAY_PROGRESS_1 "Alright, alright I think I can figure out how to operate this thing..." @@ -380,9 +380,6 @@ CreatureAI* GetAI_npc_twiggy_flathead(Creature *_Creature) #define SAY_PROGRESS_7 "That was a close one! Well, let's get going, it's still a ways to Ratchet!" #define SAY_PROGRESS_8 "Hmm... I don't think this blinking red light is a good thing..." -#define SAY_PILOT_9 "Looks like you'll have to go ahead to Ratchet and tell Sputtervalve that I've wrecked the shredder." -#define SAY_PILOT_10 "I'll stay behind and guard the wreck. Hurry! Hopefully no one will notice the smoke..." - #define QUEST_ESCAPE 863 #define NPC_PILOT 3451 #define MOB_MERCENARY 3282 @@ -422,13 +419,7 @@ struct TRINITY_DLL_DECL npc_wizzlecrank_shredderAI : public npc_escortAI m_creature->setDeathState(JUST_DIED); if (player && player->GetTypeId() == TYPEID_PLAYER) ((Player*)player)->GroupEventHappens(QUEST_ESCAPE, m_creature); - break; - case 32: {Unit* Pilot = FindCreature(NPC_PILOT, 30); - if(Pilot) - ((Creature*)Pilot)->Say(SAY_PILOT_9, LANG_UNIVERSAL, NULL);}break; - case 33:{ Unit* Pilot = FindCreature(NPC_PILOT, 30); - if(Pilot) - ((Creature*)Pilot)->Say(SAY_PILOT_10, LANG_UNIVERSAL, NULL);} break; + break; } } @@ -501,8 +492,6 @@ CreatureAI* GetAI_npc_wizzlecrank_shredderAI(Creature *_Creature) thisAI->AddWaypoint(29, 1091.28, -2985.82, 91.74, 3000);//7 thisAI->AddWaypoint(30, 1091.28, -2985.82, 91.74, 7000);//8 thisAI->AddWaypoint(31, 1091.28, -2985.82, 91.74, 3000);//justdied summon creature - thisAI->AddWaypoint(32, 1091.28, -2985.82, 91.74, 2000);//9 - thisAI->AddWaypoint(33, 1091.28, -2985.82, 91.74, 7000);//10 return (CreatureAI*)thisAI; } diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp index cbb8ce53b91..53a013bed5a 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp @@ -230,6 +230,13 @@ void hyjalAI::StartEvent(Player* player) if(!player) return; + Map* Hyjal = m_creature->GetMap(); + if(Hyjal->GetPlayersCountExceptGMs() < 15) //check if there are more than 15 players in hyjal (abuse prevent) + { + //error_log("Some Players try to farm in Hyjal (less than 15 people)"); + return; + } + Talk(BEGIN); EventBegun = true; diff --git a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp index 8d1c528f7ae..34fb3d3b507 100644 --- a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp +++ b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Netherstorm SD%Complete: 75 -SDComment: Quest support: 10438, 10652 (special flight paths), 10299,10321,10322,10323,10329,10330,10338,10365(Shutting Down Manaforge), 10198 +SDComment: Quest support: 10337, 10438, 10652 (special flight paths), 10299,10321,10322,10323,10329,10330,10338,10365(Shutting Down Manaforge), 10198 SDCategory: Netherstorm EndScriptData */ @@ -27,9 +27,11 @@ go_manaforge_control_console npc_commander_dawnforge npc_protectorate_nether_drake npc_veronia +npc_bessy EndContentData */ #include "precompiled.h" +#include "../../npc/npc_escortAI.h" /*###### ## npc_manaforge_control_console @@ -790,9 +792,10 @@ struct TRINITY_DLL_DECL mob_phase_hunterAI : public ScriptedAI bool Weak; bool Materialize; + bool Drained; int WeakPercent; - uint32 PlayerGUID; + uint64 PlayerGUID; uint32 Health; uint32 Level; uint32 PhaseSlipVulnerabilityTimer; @@ -802,6 +805,7 @@ struct TRINITY_DLL_DECL mob_phase_hunterAI : public ScriptedAI { Weak = false; Materialize = false; + Drained = false; WeakPercent = 25 + (rand()%16); // 25-40 PlayerGUID = 0; @@ -820,60 +824,64 @@ struct TRINITY_DLL_DECL mob_phase_hunterAI : public ScriptedAI void UpdateAI(const uint32 diff) { - if(!Materialize) { DoCast(m_creature, SPELL_MATERIALIZE); Materialize = true; } - Player* target = NULL; - target = ((Player*)Unit::GetUnit((*m_creature), PlayerGUID)); + if(m_creature->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || m_creature->hasUnitState(UNIT_STAT_ROOT)) // if the mob is rooted/slowed by spells eg.: Entangling Roots, Frost Nova, Hamstring, Crippling Poison, etc. => remove it + DoCast(m_creature, SPELL_PHASE_SLIP); - if(!target) + if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return; - - if(m_creature->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || m_creature->hasUnitState(UNIT_STAT_ROOT)) // if the mob is rooted/slowed by spells eg.: Entangling Roots, Frost Nova, Hamstring, Crippling Poison, etc. => remove it - DoCast(m_creature, SPELL_PHASE_SLIP); - if(ManaBurnTimer < diff) // cast Mana Burn - { - if(target->GetCreateMana() > 0) + + if(ManaBurnTimer < diff) // cast Mana Burn + { + if(m_creature->getVictim()->GetCreateMana() > 0) + { + DoCast(m_creature->getVictim(), SPELL_MANA_BURN); + ManaBurnTimer = 8000 + (rand()%10 * 1000); // 8-18 sec cd + } + }else ManaBurnTimer -= diff; + + if(PlayerGUID) // start: support for quest 10190 + { + Unit* target = Unit::GetUnit((*m_creature), PlayerGUID); + + if(target && !Weak && m_creature->GetHealth() < (m_creature->GetMaxHealth() / 100 * WeakPercent) && ((Player*)target)->GetQuestStatus(10190) == QUEST_STATUS_INCOMPLETE) { - DoCast(target, SPELL_MANA_BURN); - ManaBurnTimer = 8000 + (rand()%10 * 1000); // 8-18 sec cd + DoTextEmote(EMOTE_WEAK, 0); + Weak = true; } - }else ManaBurnTimer -= diff; - - if(!Weak && m_creature->GetHealth() < (m_creature->GetMaxHealth() / 100 * WeakPercent) && target->GetQuestStatus(10190) == QUEST_STATUS_INCOMPLETE) // start: support for quest 10190 - { - DoTextEmote(EMOTE_WEAK, 0); - Weak = true; - } - if(Weak && m_creature->HasAura(34219, 0)) - { - Health = m_creature->GetHealth(); // get the normal mob's data - Level = m_creature->getLevel(); - + if(Weak && !Drained && m_creature->HasAura(34219, 0)) + { + Drained = true; + + Health = m_creature->GetHealth(); // get the normal mob's data + Level = m_creature->getLevel(); + m_creature->AttackStop(); // delete the normal mob m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); m_creature->RemoveCorpse(); - + Creature* DrainedPhaseHunter = NULL; - + if(!DrainedPhaseHunter) - DrainedPhaseHunter = m_creature->SummonCreature(SUMMONED_MOB, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); // summon the mob - + DrainedPhaseHunter = m_creature->SummonCreature(SUMMONED_MOB, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); // summon the mob + if(DrainedPhaseHunter) { DrainedPhaseHunter->SetLevel(Level); // set the summoned mob's data DrainedPhaseHunter->SetHealth(Health); + DrainedPhaseHunter->AddThreat(target, 10000.0f); DrainedPhaseHunter->AI()->AttackStart(target); - } - } // end: support for quest 10190 + } + } + }// end: support for quest 10190 DoMeleeAttackIfReady(); } - }; CreatureAI* GetAI_mob_phase_hunter(Creature *_Creature) @@ -882,6 +890,121 @@ CreatureAI* GetAI_mob_phase_hunter(Creature *_Creature) } /*###### +## npc_bessy +######*/ + +#define Q_ALMABTRIEB 10337 +#define N_THADELL 20464 +#define SPAWN_FIRST 20512 +#define SPAWN_SECOND 19881 +#define SAY_THADELL_1 "Bessy, is that you?" +#define SAY_THADELL_2 "Thank you for bringing back my Bessy, $N. I couldn't live without her!" + +struct TRINITY_DLL_DECL npc_bessyAI : public npc_escortAI +{ + + npc_bessyAI(Creature *c) : npc_escortAI(c) {Reset();} + + bool Completed; + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + if (Unit* player = Unit::GetUnit((*m_creature), PlayerGUID)) + ((Player*)player)->FailQuest(Q_ALMABTRIEB); + } + } + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + if (!player) + return; + + switch(i) + { + case 3: //first spawn + m_creature->SummonCreature(SPAWN_FIRST, 2449.67, 2183.11, 96.85, 6.20, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(SPAWN_FIRST, 2449.53, 2184.43, 96.36, 6.27, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(SPAWN_FIRST, 2449.85, 2186.34, 97.57, 6.08, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + + case 7: + m_creature->SummonCreature(SPAWN_SECOND, 2309.64, 2186.24, 92.25, 6.06, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(SPAWN_SECOND, 2309.25, 2183.46, 91.75, 6.22, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + + case 12: + if (player) + { + ((Player*)player)->GroupEventHappens(Q_ALMABTRIEB, m_creature); + Completed = true; + } + {Unit* Thadell = FindCreature(N_THADELL, 30); + if(Thadell) + ((Creature*)Thadell)->Say(SAY_THADELL_1, LANG_UNIVERSAL, NULL);}break; + case 13: + {Unit* Thadell = FindCreature(N_THADELL, 30); + if(Thadell) + ((Creature*)Thadell)->Say(SAY_THADELL_2, LANG_UNIVERSAL, NULL);}break; + } + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(m_creature); + } + + void Aggro(Unit* who){} + + void Reset() + { + Completed = false; + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } + +}; + +bool QuestAccept_npc_bessy(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == Q_ALMABTRIEB) + { + creature->setFaction(113); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID()); + } + return true; +} + +CreatureAI* GetAI_npc_bessy(Creature *_Creature) +{ + npc_bessyAI* bessyAI = new npc_bessyAI(_Creature); + + bessyAI->AddWaypoint(0, 2488.77, 2184.89, 104.64); + bessyAI->AddWaypoint(1, 2478.72, 2184.77, 98.58); + bessyAI->AddWaypoint(2, 2473.52, 2184.71, 99.00); + bessyAI->AddWaypoint(3, 2453.15, 2184.96, 97.09,4000); + bessyAI->AddWaypoint(4, 2424.18, 2184.15, 94.11); + bessyAI->AddWaypoint(5, 2413.18, 2184.15, 93.42); + bessyAI->AddWaypoint(6, 2402.02, 2183.90, 87.59); + bessyAI->AddWaypoint(7, 2333.31, 2181.63, 90.03,4000); + bessyAI->AddWaypoint(8, 2308.73, 2184.34, 92.04); + bessyAI->AddWaypoint(9, 2303.10, 2196.89, 94.94); + bessyAI->AddWaypoint(10, 2304.58, 2272.23, 96.67); + bessyAI->AddWaypoint(11, 2297.09, 2271.40, 95.16); + bessyAI->AddWaypoint(12, 2297.68, 2266.79, 95.07,4000); + bessyAI->AddWaypoint(13, 2297.67, 2266.76, 95.07,4000); + + return (CreatureAI*)bessyAI; +} + +/*###### ## ######*/ @@ -932,4 +1055,10 @@ void AddSC_netherstorm() newscript->Name = "mob_phase_hunter"; newscript->GetAI = &GetAI_mob_phase_hunter; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_bessy"; + newscript->GetAI = &GetAI_npc_bessy; + newscript->pQuestAccept = &QuestAccept_npc_bessy; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp b/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp index 28f0c644726..a5ea8dd2226 100644 --- a/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp +++ b/src/bindings/scripts/scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp @@ -17,11 +17,17 @@ /* ScriptData SDName: Stonetalon_Mountains SD%Complete: 95 -SDComment: Quest support: 6627 (Braug Dimspirits questions/'answers' might have more to it, need more info) +SDComment: Quest support: 6627, 6523 SDCategory: Stonetalon Mountains EndScriptData */ +/* ContentData +npc_braug_dimspirit +npc_kaya_flathoof +EndContentData */ + #include "precompiled.h" +#include "../../npc/npc_escortAI.h" /*###### ## npc_braug_dimspirit @@ -65,6 +71,115 @@ bool GossipSelect_npc_braug_dimspirit(Player *player, Creature *_Creature, uint3 } /*###### +## npc_kaya_flathoof +######*/ + +#define SAY_START "Let's go before they find out I'm free!" +#define SAY_AMBUSH "Look out! We're under attack!" +#define SAY_END "Thank you for helping me. I know my way back from here." + +#define QUEST_PK 6523 +#define MOB_GB 11912 +#define MOB_GR 11910 +#define MOB_GS 11913 + +struct TRINITY_DLL_DECL npc_kaya_flathoofAI : public npc_escortAI +{ + npc_kaya_flathoofAI(Creature* c) : npc_escortAI(c) {Reset();} + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + if(!player) + return; + + switch(i) + { + case 22: + DoSay(SAY_AMBUSH, LANG_UNIVERSAL, NULL); + m_creature->SummonCreature(MOB_GB, -48.53, -503.34, -46.31, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(MOB_GR, -38.85, -503.77, -45.90, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(MOB_GS, -36.37, -496.23, -45.71, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + case 23: m_creature->SetInFront(player); + DoSay(SAY_END, LANG_UNIVERSAL, player, true); + if (player && player->GetTypeId() == TYPEID_PLAYER) + ((Player*)player)->GroupEventHappens(QUEST_PK, m_creature); + break; + } + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(m_creature); + } + + void Reset(){} + + void Aggro(Unit* who){} + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + if (player) + ((Player*)player)->FailQuest(QUEST_PK); + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } +}; + +bool QuestAccept_npc_kaya_flathoof(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == QUEST_PK) + { + ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID()); + creature->Say(SAY_START, LANG_UNIVERSAL, NULL); + creature->setFaction(113); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + } + return true; +} + +CreatureAI* GetAI_npc_kaya_flathoofAI(Creature *_Creature) +{ + npc_kaya_flathoofAI* thisAI = new npc_kaya_flathoofAI(_Creature); + + thisAI->AddWaypoint(0, 122.37, -345.80, 3.59); + thisAI->AddWaypoint(1, 113.69, -350.01, 4.54); + thisAI->AddWaypoint(2, 107.32, -353.09, 3.33); + thisAI->AddWaypoint(3, 99.25, -342.43, 2.87); + thisAI->AddWaypoint(4, 111.19, -315.60, 3.71); + thisAI->AddWaypoint(5, 109.99, -293.92, 5.16); + thisAI->AddWaypoint(6, 104.59, -268.27, 4.78); + thisAI->AddWaypoint(7, 82.80, -247.28, 5.73); + thisAI->AddWaypoint(8, 66.44, -245.99, 5.85); + thisAI->AddWaypoint(9, 34.36, -246.01, 5.97); + thisAI->AddWaypoint(10, 13.24, -245.61, 5.25); + thisAI->AddWaypoint(11, -10.27, -248.66, 4.69); + thisAI->AddWaypoint(12, -26.07, -262.76, 0.01); + thisAI->AddWaypoint(13, -33.15, -282.03, -4.12); + thisAI->AddWaypoint(14, -28.42, -315.52, -8.56); + thisAI->AddWaypoint(15, -32.05, -339.34, -10.84); + thisAI->AddWaypoint(16, -35.22, -358.11, -16.20); + thisAI->AddWaypoint(17, -51.57, -391.63, -24.85); + thisAI->AddWaypoint(18, -58.58, -409.08, -29.97); + thisAI->AddWaypoint(19, -60.37, -441.23, -36.80); + thisAI->AddWaypoint(20, -59.03, -476.39, -44.98); + thisAI->AddWaypoint(21, -53.18, -490.31, -46.11); + thisAI->AddWaypoint(22, -43.77, -497.99, -46.13, 3000);// summon + thisAI->AddWaypoint(23, -41.77, -518.15, -46.13, 5000);//end + + return (CreatureAI*)thisAI; +} + +/*###### ## AddSC ######*/ @@ -77,4 +192,10 @@ void AddSC_stonetalon_mountains() newscript->pGossipHello = &GossipHello_npc_braug_dimspirit; newscript->pGossipSelect = &GossipSelect_npc_braug_dimspirit; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_kaya_flathoof"; + newscript->GetAI = &GetAI_npc_kaya_flathoofAI; + newscript->pQuestAccept = &QuestAccept_npc_kaya_flathoof; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp b/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp index 90f680cf82a..6cf663616bf 100644 --- a/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp +++ b/src/bindings/scripts/scripts/zone/tanaris/tanaris.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Tanaris SD%Complete: 80 -SDComment: Quest support: 2954, 4005, 10277, 10279(Special flight path). Noggenfogger vendor +SDComment: Quest support: 2954, 4005, 10277, 648, 10279(Special flight path). Noggenfogger vendor SDCategory: Tanaris EndScriptData */ @@ -27,6 +27,7 @@ npc_custodian_of_time npc_marin_noggenfogger npc_steward_of_time npc_stone_watcher_of_norgannon +npc_OOX17 EndContentData */ #include "precompiled.h" @@ -366,6 +367,208 @@ bool GossipSelect_npc_stone_watcher_of_norgannon(Player *player, Creature *_Crea } /*###### +## npc_OOX17 +######*/ + +#define Q_OOX17 648 +#define SPAWN_FIRST 7803 +#define SPAWN_SECOND_1 5617 +#define SPAWN_SECOND_2 7805 +#define SAY_SCOFF -1060004 +#define SAY_CHICKEN_ACC -1060000 +#define SAY_CHICKEN_AGGRO_1 -1060001 +#define SAY_CHICKEN_AGGRO_2 -1060002 +#define SAY_CHICKEN_AMB -1060003 +#define SAY_CHICKEN_COMP -1060005 + +struct TRINITY_DLL_DECL npc_OOX17AI : public npc_escortAI +{ + npc_OOX17AI(Creature *c) : npc_escortAI(c) {Reset();} + + void WaypointReached(uint32 i) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + if (!player) + return; + + switch(i) { + case 23: + m_creature->SummonCreature(SPAWN_FIRST, -8350.96, -4445.79, 10.10, 6.20, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(SPAWN_FIRST, -8355.96, -4447.79, 10.10, 6.27, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(SPAWN_FIRST, -8353.96, -4442.79, 10.10, 6.08, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->Say(SAY_CHICKEN_AMB, LANG_UNIVERSAL, NULL); + break; + + case 56: + m_creature->SummonCreature(SPAWN_SECOND_1, -7510.07, -4795.50, 9.35, 6.06, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(SPAWN_SECOND_2, -7515.07, -4797.50, 9.35, 6.22, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->SummonCreature(SPAWN_SECOND_2, -7518.07, -4792.50, 9.35, 6.22, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + m_creature->Say(SAY_CHICKEN_AMB, LANG_UNIVERSAL, NULL); + {Unit* scoff = FindCreature(SPAWN_SECOND_2, 30); + if(scoff) + ((Creature*)scoff)->Say(SAY_SCOFF, LANG_UNIVERSAL, NULL);}break; + break; + + case 86: + if (player) + { + m_creature->Say(SAY_CHICKEN_COMP, LANG_UNIVERSAL, NULL); + ((Player*)player)->GroupEventHappens(Q_OOX17, m_creature); + } + break; + } + } + + void Reset(){} + + void Aggro(Unit* who) + { + switch (rand()%2) { + case 0: + m_creature->Say(SAY_CHICKEN_AGGRO_1, LANG_UNIVERSAL, 0); + break; + case 1: + m_creature->Say(SAY_CHICKEN_AGGRO_2, LANG_UNIVERSAL, 0); + break; + } + + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(m_creature); + } + + void JustDied(Unit* killer) + { + if (PlayerGUID) + { + if (Unit* player = Unit::GetUnit((*m_creature), PlayerGUID)) + ((Player*)player)->FailQuest(Q_OOX17); + } + } + + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) + return; + } + }; + +bool QuestAccept_npc_OOX17(Player* player, Creature* creature, Quest const* quest) +{ + if (quest->GetQuestId() == Q_OOX17) + { + creature->setFaction(113); + creature->SetHealth(creature->GetMaxHealth()); + creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); + creature->Say(SAY_CHICKEN_ACC, LANG_UNIVERSAL, NULL); + ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID()); + + } + return true; +} + +CreatureAI* GetAI_npc_OOX17(Creature *_Creature) +{ + npc_OOX17AI* OOX17AI = new npc_OOX17AI(_Creature); + + OOX17AI->AddWaypoint(0, -8843.73, -4374.44, 43.71); + OOX17AI->AddWaypoint(1, -8834.68, -4373.88, 45.71); + OOX17AI->AddWaypoint(2, -8832.93, -4373.85, 45.67); + OOX17AI->AddWaypoint(3, -8829.21, -4373.72, 44.14); + OOX17AI->AddWaypoint(4, -8825.10, -4373.56, 41.44); + OOX17AI->AddWaypoint(5, -8818.88, -4372.75, 36.43); + OOX17AI->AddWaypoint(6, -8803.37, -4369.68, 30.06); + OOX17AI->AddWaypoint(7, -8786.68, -4366.18, 23.91); + OOX17AI->AddWaypoint(8, -8764.97, -4366.94, 25.23); + OOX17AI->AddWaypoint(9, -8745.49, -4363.16, 22.80); + OOX17AI->AddWaypoint(10, -8724.13, -4353.55, 20.72); + OOX17AI->AddWaypoint(11, -8706.77, -4346.14, 16.12); + OOX17AI->AddWaypoint(12, -8688.27, -4372.85, 13.64); + OOX17AI->AddWaypoint(13, -8668.76, -4380.38, 11.69); + OOX17AI->AddWaypoint(14, -8645.19, -4388.62, 12.56); + OOX17AI->AddWaypoint(15, -8614.73, -4398.60, 9.86); + OOX17AI->AddWaypoint(16, -8560.33, -4411.27, 13.17); + OOX17AI->AddWaypoint(17, -8536.45, -4416.49, 11.84); + OOX17AI->AddWaypoint(18, -8503.48, -4423.70, 13.59); + OOX17AI->AddWaypoint(19, -8471.91, -4430.60, 9.56); + OOX17AI->AddWaypoint(20, -8441.36, -4435.31, 9.40); + OOX17AI->AddWaypoint(21, -8403.41, -4441.16, 11.83); + OOX17AI->AddWaypoint(22, -8371.24, -4446.13, 9.47); + OOX17AI->AddWaypoint(23, -8353.96, -4448.79, 10.10); //Scorpid + OOX17AI->AddWaypoint(24, -8336.40, -4446.39, 8.98); + OOX17AI->AddWaypoint(25, -8303.78, -4441.96, 11.89); + OOX17AI->AddWaypoint(26, -8272.20, -4433.31, 9.60); + OOX17AI->AddWaypoint(27, -8224.76, -4419.39, 13.03); + OOX17AI->AddWaypoint(28, -8193.31, -4406.04, 10.17); + OOX17AI->AddWaypoint(29, -8155.65, -4397.74, 8.99); + OOX17AI->AddWaypoint(30, -8129.25, -4394.57, 10.92); + OOX17AI->AddWaypoint(31, -8104.86, -4399.03, 8.93); + OOX17AI->AddWaypoint(32, -8063.15, -4423.40, 10.07); + OOX17AI->AddWaypoint(33, -8032.15, -4443.47, 9.97); + OOX17AI->AddWaypoint(34, -8015.39, -4454.33, 9.39); + OOX17AI->AddWaypoint(35, -7981.64, -4482.44, 10.32); + OOX17AI->AddWaypoint(36, -7958.83, -4503.98, 9.69); + OOX17AI->AddWaypoint(37, -7932.45, -4528.91, 10.08); + OOX17AI->AddWaypoint(38, -7904.09, -4566.67, 12.59); + OOX17AI->AddWaypoint(39, -7883.33, -4593.91, 12.15); + OOX17AI->AddWaypoint(40, -7862.83, -4624.53, 10.21); + OOX17AI->AddWaypoint(41, -7840.79, -4654.26, 9.45); + OOX17AI->AddWaypoint(42, -7826.17, -4673.99, 10.61); + OOX17AI->AddWaypoint(43, -7807.86, -4698.69, 11.24); + OOX17AI->AddWaypoint(44, -7793.88, -4717.55, 10.48); + OOX17AI->AddWaypoint(45, -7778.68, -4738.05, 8.89); + OOX17AI->AddWaypoint(46, -7746.42, -4780.39, 9.84); + OOX17AI->AddWaypoint(47, -7724.11, -4772.75, 10.28); + OOX17AI->AddWaypoint(48, -7697.98, -4763.80, 9.52); + OOX17AI->AddWaypoint(49, -7665.33, -4752.62, 10.56); + OOX17AI->AddWaypoint(50, -7641.47, -4750.33, 8.94); + OOX17AI->AddWaypoint(51, -7620.08, -4753.96, 8.93); + OOX17AI->AddWaypoint(52, -7603.15, -4757.53, 9.06); + OOX17AI->AddWaypoint(53, -7579.43, -4767.07, 8.93); + OOX17AI->AddWaypoint(54, -7558.51, -4779.01, 9.64); + OOX17AI->AddWaypoint(55, -7536.40, -4789.32, 8.92); + OOX17AI->AddWaypoint(56, -7512.07, -4793.50, 9.35); //Wastewander + OOX17AI->AddWaypoint(57, -7490.79, -4788.80, 10.53); + OOX17AI->AddWaypoint(58, -7469.10, -4785.11, 10.42); + OOX17AI->AddWaypoint(59, -7453.18, -4782.41, 9.15); + OOX17AI->AddWaypoint(60, -7426.27, -4777.83, 9.54); + OOX17AI->AddWaypoint(61, -7393.84, -4770.19, 12.57); + OOX17AI->AddWaypoint(62, -7367.25, -4764.17, 11.92); + OOX17AI->AddWaypoint(63, -7341.00, -4752.11, 10.17); + OOX17AI->AddWaypoint(64, -7321.62, -4744.97, 11.58); + OOX17AI->AddWaypoint(65, -7302.35, -4744.35, 11.97); + OOX17AI->AddWaypoint(66, -7281.00, -4743.66, 11.21); + OOX17AI->AddWaypoint(67, -7258.33, -4742.93, 9.64); + OOX17AI->AddWaypoint(68, -7236.70, -4742.24, 10.16); + OOX17AI->AddWaypoint(69, -7217.52, -4743.87, 10.79); + OOX17AI->AddWaypoint(70, -7201.86, -4746.32, 9.58); + OOX17AI->AddWaypoint(71, -7182.01, -4749.41, 9.09); + OOX17AI->AddWaypoint(72, -7159.61, -4752.90, 9.52); + OOX17AI->AddWaypoint(73, -7139.58, -4756.02, 9.53); + OOX17AI->AddWaypoint(74, -7122.60, -4754.91, 9.66); + OOX17AI->AddWaypoint(75, -7101.06, -4753.87, 8.92); + OOX17AI->AddWaypoint(76, -7082.79, -4752.99, 9.97); + OOX17AI->AddWaypoint(77, -7061.81, -4751.98, 9.26); + OOX17AI->AddWaypoint(78, -7035.12, -4754.39, 9.19); + OOX17AI->AddWaypoint(79, -7013.90, -4758.64, 10.28); + OOX17AI->AddWaypoint(80, -7001.71, -4769.73, 10.59); + OOX17AI->AddWaypoint(81, -6984.95, -4788.61, 9.30); + OOX17AI->AddWaypoint(82, -6970.41, -4788.77, 9.42); + OOX17AI->AddWaypoint(83, -6957.16, -4788.92, 6.26); + OOX17AI->AddWaypoint(84, -6951.29, -4802.73, 4.45); + OOX17AI->AddWaypoint(85, -6944.81, -4816.58, 1.60); + OOX17AI->AddWaypoint(86, -6942.06, -4839.40, 0.66,5000); + + return (CreatureAI*)OOX17AI; +} + +/*###### ## AddSC ######*/ @@ -401,4 +604,10 @@ void AddSC_tanaris() newscript->pGossipHello = &GossipHello_npc_stone_watcher_of_norgannon; newscript->pGossipSelect = &GossipSelect_npc_stone_watcher_of_norgannon; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_OOX17"; + newscript->GetAI = &GetAI_npc_OOX17; + newscript->pQuestAccept = &QuestAccept_npc_OOX17; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/undercity/undercity.cpp b/src/bindings/scripts/scripts/zone/undercity/undercity.cpp index 9b2dc13ac20..a5ba4abfd9a 100644 --- a/src/bindings/scripts/scripts/zone/undercity/undercity.cpp +++ b/src/bindings/scripts/scripts/zone/undercity/undercity.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: Undercity SD%Complete: 95 -SDComment: Quest support: 6628(Parqual Fintallas questions/'answers' might have more to it, need more info), 9180(post-event). +SDComment: Quest support: 6628, 9180(post-event). SDCategory: Undercity EndScriptData */ diff --git a/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp index 51cb2b4456d..5d1bc072867 100644 --- a/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp +++ b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp @@ -126,8 +126,9 @@ bool QuestAccept_npc_ame(Player* player, Creature* creature, Quest const* quest) { ((npc_escortAI*)(creature->AI()))->Start(false, true, false, player->GetGUID()); DoScriptText(SAY_READY, creature, player); + creature->SetUInt32Value(UNIT_FIELD_BYTES_1,0); // Change faction so mobs attack - creature->setFaction(775); + creature->setFaction(113); } return true; } diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp index 27cd169ffc3..6b892a0fa5d 100644 --- a/src/game/BattleGroundAV.cpp +++ b/src/game/BattleGroundAV.cpp @@ -125,7 +125,7 @@ void BattleGroundAV::HandleQuestComplete(uint32 questid, Player *player) return;//maybe we should log this, cause this must be a cheater or a big bug uint8 team = GetTeamIndexByTeamId(player->GetTeam()); //TODO add reputation, events (including quest not available anymore, next quest availabe, go/npc de/spawning)and maybe honor - sLog.outError("BG_AV Quest %i completed",questid); + sLog.outDebug("BG_AV Quest %i completed",questid); switch(questid) { case AV_QUEST_A_SCRAPS1: diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 7556e9e7c86..14c78201999 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -473,7 +473,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) SendPacket( &data ); std::string IP_str = GetRemoteAddress(); - sLog.outBasic("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); + sLog.outDetail("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); sLog.outChar("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); } @@ -523,7 +523,7 @@ void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) return; std::string IP_str = GetRemoteAddress(); - sLog.outBasic("Account: %d (IP: %s) Delete Character:[%s] (guid:%u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); + sLog.outDetail("Account: %d (IP: %s) Delete Character:[%s] (guid:%u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); if(sLog.IsOutCharDump()) // optimize GetPlayerDump call diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 2b7b8fbbe41..300bb3cf3e8 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -443,6 +443,7 @@ ChatCommand * ChatHandler::getCommandTable() { "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL }, { "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL }, { "addtemp", SEC_GAMEMASTER, false, &ChatHandler::HandleTempAddSpwCommand, "", NULL }, + { "addformation", SEC_MODERATOR, false, &ChatHandler::HandleNpcAddFormationCommand, "", NULL }, //{ TODO: fix or remove this commands { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNameCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 2626ebeb3ae..e83aef41c5b 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -205,6 +205,7 @@ class ChatHandler bool HandleNpcUnFollowCommand(const char* args); bool HandleNpcWhisperCommand(const char* args); bool HandleNpcYellCommand(const char* args); + bool HandleNpcAddFormationCommand(const char* args); bool HandleReloadAllCommand(const char* args); bool HandleReloadAllAreaCommand(const char* args); diff --git a/src/game/GameEvent.cpp b/src/game/GameEvent.cpp index 17084dd3ebf..9ceed9024c4 100644 --- a/src/game/GameEvent.cpp +++ b/src/game/GameEvent.cpp @@ -1016,7 +1016,7 @@ uint32 GameEvent::Update() // return the next e nextEventDelay = 0; for(std::set<uint16>::iterator itr = deactivate.begin(); itr != deactivate.end(); ++itr) StopEvent(*itr); - sLog.outBasic("Next game event check in %u seconds.", nextEventDelay + 1); + sLog.outDetail("Next game event check in %u seconds.", nextEventDelay + 1); return (nextEventDelay + 1) * 1000; // Add 1 second to be sure event has started/stopped at next call } diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 8afac50da13..8254bf88bb8 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -295,12 +295,14 @@ bool Group::AddMember(const uint64 &guid, const char* name) uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method) { + BroadcastGroupUpdate(); + // remove member and change leader (if need) only if strong more 2 members _before_ member remove if(GetMembersCount() > (isBGGroup() ? 1 : 2)) // in BG group case allow 1 members group { bool leaderChanged = _removeMember(guid); - Player *player = objmgr.GetPlayer( guid ); + Player *player = objmgr.GetPlayer( guid ); // FG: TODO: could be removed, its just here for consistency if (player) { WorldPacket data; @@ -1521,3 +1523,20 @@ void Group::_homebindIfInstance(Player *player) player->m_InstanceValid = false; } } + +void Group::BroadcastGroupUpdate(void) +{ + // FG: HACK: force flags update on group leave - for values update hack + // -- not very efficient but safe + for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + { + + Player *pp = objmgr.GetPlayer(citr->guid); + if(pp && pp->IsInWorld()) + { + pp->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2); + pp->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE); + DEBUG_LOG("-- Forced group value update for '%s'", pp->GetName()); + } + } +}
\ No newline at end of file diff --git a/src/game/Group.h b/src/game/Group.h index 5edc99f8c0c..aef5a8619af 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -331,6 +331,9 @@ class TRINITY_DLL_SPEC Group InstanceGroupBind* GetBoundInstance(uint32 mapid, uint8 difficulty); BoundInstancesMap& GetBoundInstances(uint8 difficulty) { return m_boundInstances[difficulty]; } + // FG: evil hacks + void BroadcastGroupUpdate(void); + protected: bool _addMember(const uint64 &guid, const char* name, bool isAssistant=false); bool _addMember(const uint64 &guid, const char* name, bool isAssistant, uint8 group); diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index ab6b8d4a939..5a74550c12a 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -216,6 +216,8 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ ) uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID()); GetPlayer()->SetGroup(group, subgroup); + + group->BroadcastGroupUpdate(); } void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ ) @@ -724,8 +726,9 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke uint32 updatedAura = player->GetVisibleAura(i); *data << uint32(updatedAura); *data << uint8(1); - if(!updatedAura) - player->UnsetAuraUpdateMask(i); + //TODO: find a safe place to do this cleanup + //if(!updatedAura) + //player->UnsetAuraUpdateMask(i); } } } @@ -808,8 +811,9 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke uint32 updatedAura = pet->GetVisibleAura(i); *data << uint32(updatedAura); *data << uint8(1); - if(!updatedAura) - pet->UnsetAuraUpdateMask(i); + //TODO: find a safe place to do this cleanup + //if(!updatedAura) + //pet->UnsetAuraUpdateMask(i); } } } diff --git a/src/game/Item.cpp b/src/game/Item.cpp index ccd5a4d558c..c39b573e24a 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -645,14 +645,14 @@ void Item::AddToUpdateQueueOf(Player *player) player = GetOwner(); if (!player) { - sLog.outError("Item::AddToUpdateQueueOf - GetPlayer didn't find a player matching owner's guid (%u)!", GUID_LOPART(GetOwnerGUID())); + sLog.outDebug("Item::AddToUpdateQueueOf - GetPlayer didn't find a player matching owner's guid (%u)!", GUID_LOPART(GetOwnerGUID())); return; } } if (player->GetGUID() != GetOwnerGUID()) { - sLog.outError("Item::AddToUpdateQueueOf - Owner's guid (%u) and player's guid (%u) don't match!", GUID_LOPART(GetOwnerGUID()), player->GetGUIDLow()); + sLog.outDebug("Item::AddToUpdateQueueOf - Owner's guid (%u) and player's guid (%u) don't match!", GUID_LOPART(GetOwnerGUID()), player->GetGUIDLow()); return; } @@ -671,14 +671,14 @@ void Item::RemoveFromUpdateQueueOf(Player *player) player = GetOwner(); if (!player) { - sLog.outError("Item::RemoveFromUpdateQueueOf - GetPlayer didn't find a player matching owner's guid (%u)!", GUID_LOPART(GetOwnerGUID())); + sLog.outDebug("Item::RemoveFromUpdateQueueOf - GetPlayer didn't find a player matching owner's guid (%u)!", GUID_LOPART(GetOwnerGUID())); return; } } if (player->GetGUID() != GetOwnerGUID()) { - sLog.outError("Item::RemoveFromUpdateQueueOf - Owner's guid (%u) and player's guid (%u) don't match!", GUID_LOPART(GetOwnerGUID()), player->GetGUIDLow()); + sLog.outDebug("Item::RemoveFromUpdateQueueOf - Owner's guid (%u) and player's guid (%u) don't match!", GUID_LOPART(GetOwnerGUID()), player->GetGUIDLow()); return; } diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index a54a66300be..ebf17571b35 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -4366,3 +4366,49 @@ bool ChatHandler::HandleTempGameObjectCommand(const char* args) return true; } + +bool ChatHandler::HandleNpcAddFormationCommand(const char* args) +{ + if (!*args) + return false; + + uint32 leaderGUID = (uint32) atoi((char*)args); + Creature *pCreature = getSelectedCreature(); + + if(!pCreature || !pCreature->GetDBTableGUIDLow()) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint32 lowguid = pCreature->GetDBTableGUIDLow(); + if(pCreature->GetFormationID()) + { + PSendSysMessage("Selected creature is already member of group %u", pCreature->GetFormationID()); + return false; + } + + if (!lowguid) + return false; + + Player *chr = m_session->GetPlayer(); + FormationMember *group_member; + + group_member = new FormationMember; + group_member->follow_angle = pCreature->GetAngle(chr) - chr->GetOrientation(); + group_member->follow_dist = sqrtf(pow(chr->GetPositionX() - pCreature->GetPositionX(),int(2))+pow(chr->GetPositionY()-pCreature->GetPositionY(),int(2))); + group_member->memberGUID = lowguid; + group_member->leaderGUID = leaderGUID; + group_member->groupAI = 0; + + CreatureGroupMap[lowguid] = group_member; + pCreature->SearchFormation(); + + WorldDatabase.PExecuteLog("INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`) VALUES ('%u','%u','%f', '%f', '%u')", + leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI); + + PSendSysMessage("Creature %u added to formation with leader %u", lowguid, leaderGUID); + + return true; + } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 19de60c6b53..a99208e63bd 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -328,9 +328,9 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) { // recheck CHECK_PACKET_SIZE(recv_data,8+4+1); - sLog.outBasic("reading string"); + sLog.outDebug("reading string"); recv_data >> code; - sLog.outBasic("string read: %s", code.c_str()); + sLog.outDebug("string read: %s", code.c_str()); } Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_NONE); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 226129c392d..50ed59d2486 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -653,6 +653,38 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask else *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_OTHER_TAGGER); } + // FG: pretend that OTHER players in own group are friendly ("blue") + else if(index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE) + { + bool ch = false; + if(target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER && target != this) + { + if(target->IsInSameGroupWith((Player*)this) || target->IsInSameRaidWith((Player*)this)) + { + if(index == UNIT_FIELD_BYTES_2) + { + DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (flag)", target->GetName(), ((Player*)this)->GetName()); + *data << ( m_uint32Values[ index ] & (UNIT_BYTE2_FLAG_SANCTUARY << 8) ); // this flag is at uint8 offset 1 !! + ch = true; + } + else if(index == UNIT_FIELD_FACTIONTEMPLATE) + { + FactionTemplateEntry const *ft1, *ft2; + ft1 = ((Player*)this)->getFactionTemplateEntry(); + ft2 = ((Player*)target)->getFactionTemplateEntry(); + if(ft1 && ft2 && !ft1->IsFriendlyTo(*ft2)) + { + uint32 faction = ((Player*)target)->getFaction(); // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work) + DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (faction %u)", target->GetName(), ((Player*)this)->GetName(), faction); + *data << uint32(faction); + ch = true; + } + } + } + } + if(!ch) + *data << m_uint32Values[ index ]; + } else { // send in current format (float as float, uint32 as uint32) @@ -1324,6 +1356,19 @@ void WorldObject::SendPlaySound(uint32 Sound, bool OnlySelf) SendMessageToSet( &data, true ); // ToSelf ignored in this case } +void Object::ForceValuesUpdateAtIndex(uint32 i) +{ + m_uint32Values_mirror[i] = GetUInt32Value(i) + 1; // makes server think the field changed + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } +} + namespace Trinity { class MessageChatLocaleCacheDo diff --git a/src/game/Object.h b/src/game/Object.h index 815111eb91b..2e29b4daec1 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -302,6 +302,10 @@ class TRINITY_DLL_SPEC Object virtual bool hasQuest(uint32 /* quest_id */) const { return false; } virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; } + + // FG: some hacky helpers + void ForceValuesUpdateAtIndex(uint32); + protected: Object ( ); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 834362a0d5c..6c77138c38c 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -736,10 +736,10 @@ bool Pet::CreateBaseAtCreature(Creature* creature) } uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET); - sLog.outBasic("SetInstanceID()"); + sLog.outDebug("SetInstanceID()"); SetInstanceId(creature->GetInstanceId()); - sLog.outBasic("Create pet"); + sLog.outDebug("Create pet"); uint32 pet_number = objmgr.GeneratePetNumber(); if(!Create(guid, creature->GetMap(), creature->GetEntry(), pet_number)) return false; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 6ee750e6e83..182bacf8ee8 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3371,7 +3371,7 @@ void Aura::HandleModStealth(bool apply, bool Real) Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) { - if ((*i)->GetSpellProto()->SpellIconID == 2114) + if ((*i)->GetSpellProto()->SpellIconID == 2114 && Real) { if (apply) { diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp index 58a18896e9f..dc3bd020ccf 100644 --- a/src/game/TradeHandler.cpp +++ b/src/game/TradeHandler.cpp @@ -536,7 +536,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) return; } - if(pOther->GetTeam() !=_player->GetTeam() ) + if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeam() !=_player->GetTeam() ) { SendTradeStatus(TRADE_STATUS_WRONG_FACTION); return; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 54d0f54c88f..9b41f52e124 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -382,9 +382,9 @@ void Unit::GetRandomContactPoint( const Unit* obj, float &x, float &y, float &z, float combat_reach = GetCombatReach(); if(combat_reach < 0.1) // sometimes bugged for players { - sLog.outError("Unit %u (Type: %u) has invalid combat_reach %f",GetGUIDLow(),GetTypeId(),combat_reach); - if(GetTypeId() == TYPEID_UNIT) - sLog.outError("Creature entry %u has invalid combat_reach", ((Creature*)this)->GetEntry()); + //sLog.outError("Unit %u (Type: %u) has invalid combat_reach %f",GetGUIDLow(),GetTypeId(),combat_reach); + // if(GetTypeId() == TYPEID_UNIT) + // sLog.outError("Creature entry %u has invalid combat_reach", ((Creature*)this)->GetEntry()); combat_reach = DEFAULT_COMBAT_REACH; } uint32 attacker_number = getAttackers().size(); @@ -3927,6 +3927,11 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) Aura* Aur = i->second; SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); + // some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura + // remove aura from list before to prevent deleting it before + m_Auras.erase(i); + ++m_removedAuras; // internal count used by unit update + Unit* caster = NULL; if (IsSingleTargetSpell(AurSpellInfo)) { @@ -3946,22 +3951,20 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) { - m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); - if((*i).second->GetSpellProto()->AuraInterruptFlags) + m_modAuras[Aur->GetModifier()->m_auraname].remove(Aur); + + if(Aur->GetSpellProto()->AuraInterruptFlags) { - m_interruptableAuras.remove((*i).second); + m_interruptableAuras.remove(Aur); UpdateInterruptMask(); } - if((*i).second->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) - m_ccAuras.remove((*i).second); + + if(Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) + m_ccAuras.remove(Aur); } // Set remove mode Aur->SetRemoveMode(mode); - // some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura - // remove aura from list before to prevent deleting it before - m_Auras.erase(i); - ++m_removedAuras; // internal count used by unit update // Statue unsummoned at aura remove Totem* statue = NULL; @@ -3982,12 +3985,12 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)Aur->GetSpellProto()->Id)) { - for(std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i) + for(std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr) { if(spell_triggered < 0) - RemoveAurasDueToSpell(-(*i)); + RemoveAurasDueToSpell(-(*itr)); else if(Unit* caster = Aur->GetCaster()) - CastSpell(this, *i, true, 0, 0, caster->GetGUID()); + CastSpell(this, *itr, true, 0, 0, caster->GetGUID()); } } @@ -11251,6 +11254,8 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura ) void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) { uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); + if(target_guid == GetGUID()) + return; if(!IS_UNIT_GUID(target_guid)) return; diff --git a/src/game/World.cpp b/src/game/World.cpp index 8861005e55c..82821f44544 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -612,6 +612,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Mail",false); m_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfig.GetBoolDefault("AllowTwoSide.WhoList", false); m_configs[CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND] = sConfig.GetBoolDefault("AllowTwoSide.AddFriend", false); + m_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfig.GetBoolDefault("AllowTwoSide.trade", false); m_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfig.GetIntDefault("StrictPlayerNames", 0); m_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfig.GetIntDefault("StrictCharterNames", 0); m_configs[CONFIG_STRICT_PET_NAMES] = sConfig.GetIntDefault("StrictPetNames", 0); @@ -736,7 +737,7 @@ void World::LoadConfigSettings(bool reload) { sLog.outError("StartArenaPoints (%i) must be in range 0..MaxArenaPoints(%u). Set to %u.", m_configs[CONFIG_START_ARENA_POINTS],m_configs[CONFIG_MAX_ARENA_POINTS],0); - m_configs[CONFIG_MAX_ARENA_POINTS] = 0; + m_configs[CONFIG_START_ARENA_POINTS] = 0; } else if(m_configs[CONFIG_START_ARENA_POINTS] > m_configs[CONFIG_MAX_ARENA_POINTS]) { @@ -1360,7 +1361,7 @@ void World::SetInitialWorldSettings() exit(1); ///- Initialize game time and timers - sLog.outString( "DEBUG:: Initialize game time and timers" ); + sLog.outDebug( "DEBUG:: Initialize game time and timers" ); m_gameTime = time(NULL); m_startTime=m_gameTime; @@ -1505,7 +1506,7 @@ void World::Update(time_t diff) { if(m_updateTimeSum > m_configs[CONFIG_INTERVAL_LOG_UPDATE]) { - sLog.outString("Update time diff: %u. Players online: %u.", m_updateTimeSum / m_updateTimeCount, GetActiveSessionCount()); + sLog.outBasic("Update time diff: %u. Players online: %u.", m_updateTimeSum / m_updateTimeCount, GetActiveSessionCount()); m_updateTimeSum = m_updateTime; m_updateTimeCount = 1; } diff --git a/src/game/World.h b/src/game/World.h index 76fd396d5b6..c684ac11e96 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -96,6 +96,7 @@ enum WorldConfigs CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL, CONFIG_ALLOW_TWO_SIDE_WHO_LIST, CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND, + CONFIG_ALLOW_TWO_SIDE_TRADE, CONFIG_STRICT_PLAYER_NAMES, CONFIG_STRICT_CHARTER_NAMES, CONFIG_STRICT_PET_NAMES, diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index 5dc8c4cddb3..a25d05567b3 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -939,7 +939,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) SendPacket (packet); - sLog.outBasic ("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); + sLog.outDetail ("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); return -1; } diff --git a/src/trinitycore/Master.cpp b/src/trinitycore/Master.cpp index c1484fede8e..ed526f497c3 100644 --- a/src/trinitycore/Master.cpp +++ b/src/trinitycore/Master.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> * * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> @@ -408,7 +408,7 @@ bool Master::_StartDB() sLog.outError("Database not specified in configuration file"); return false; } - sLog.outString("World Database: %s", dbstring.c_str()); + sLog.outDetail("World Database: %s", dbstring.c_str()); ///- Initialise the world database if(!WorldDatabase.Initialize(dbstring.c_str())) @@ -422,7 +422,7 @@ bool Master::_StartDB() sLog.outError("Character Database not specified in configuration file"); return false; } - sLog.outString("Character Database: %s", dbstring.c_str()); + sLog.outDetail("Character Database: %s", dbstring.c_str()); ///- Initialise the Character database if(!CharacterDatabase.Initialize(dbstring.c_str())) @@ -439,7 +439,7 @@ bool Master::_StartDB() } ///- Initialise the login database - sLog.outString("Login Database: %s", dbstring.c_str() ); + sLog.outDetail("Login Database: %s", dbstring.c_str() ); if(!LoginDatabase.Initialize(dbstring.c_str())) { sLog.outError("Cannot connect to login database %s",dbstring.c_str()); diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 91b0209acd4..af81a84038f 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -670,6 +670,7 @@ AllowTwoSide.Interaction.Auction = 0 AllowTwoSide.Interaction.Mail = 0 AllowTwoSide.WhoList = 0 AllowTwoSide.AddFriend = 0 +AllowTwoSide.Trade = 0 TalentsInspecting = 1 ################################################################################################################### |