diff options
author | megamage <none@none> | 2009-01-02 10:35:19 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-01-02 10:35:19 -0600 |
commit | 3deefb9f00201033728d4467180d8ba9aa265a20 (patch) | |
tree | dcd243f7f2f27f03e8c1f1d74e42aac332e508d8 /src | |
parent | 75f0da72eea3ab2f8a6b5a2a9bc8361c4a656afe (diff) | |
parent | deac8370d71c0f72b5d60709c09dc2830c1680bd (diff) |
*Update to Trinity 759.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/scripts/ScriptMgr.cpp | 2 | ||||
-rw-r--r-- | src/bindings/scripts/include/sc_creature.cpp | 57 | ||||
-rw-r--r-- | src/bindings/scripts/include/sc_creature.h | 4 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp | 14 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp | 2 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp | 4 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp | 379 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp | 7 | ||||
-rw-r--r-- | src/game/Chat.cpp | 1 | ||||
-rw-r--r-- | src/game/Chat.h | 1 | ||||
-rw-r--r-- | src/game/LootMgr.cpp | 3 | ||||
-rw-r--r-- | src/game/Map.cpp | 4 | ||||
-rw-r--r-- | src/game/Spell.cpp | 5 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 7 | ||||
-rw-r--r-- | src/game/Unit.cpp | 5 | ||||
-rw-r--r-- | src/game/World.h | 1 | ||||
-rw-r--r-- | src/trinitycore/CliRunnable.cpp | 375 |
17 files changed, 807 insertions, 64 deletions
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index 8fb5bdb1021..651bc6a95f6 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -342,6 +342,7 @@ extern void AddSC_boss_moroes(); extern void AddSC_bosses_opera(); extern void AddSC_instance_karazhan(); extern void AddSC_karazhan(); +extern void AddSC_boss_nightbane(); //Loch Modan extern void AddSC_loch_modan(); @@ -1547,6 +1548,7 @@ void ScriptsInit() AddSC_bosses_opera(); AddSC_instance_karazhan(); AddSC_karazhan(); + AddSC_boss_nightbane(); //Loch Modan AddSC_loch_modan(); diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index fad8c631e5e..d46d5b68716 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -740,55 +740,24 @@ 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, uint32 district) +Unit* ScriptedAI::FindCreature(uint32 entry, float range) { - CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); - Cell cell(pair); - cell.data.Part.reserved = district; - cell.SetNoCreate(); - - std::list<Creature*> NPCList; - + Creature* target = NULL; 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; + Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(target, check); + m_creature->VisitNearbyGridObject(range, searcher); + if(!target) error_log("SD2 ERROR: Entry: %u not found!", entry); + return target; } -GameObject* ScriptedAI::FindGameObject(uint32 entry, uint32 district) +GameObject* ScriptedAI::FindGameObject(uint32 entry, float range) { - CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); - Cell cell(pair); - cell.data.Part.reserved = 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; + GameObject* target = NULL; + Trinity::AllGameObjectsWithEntryInGrid go_check(entry); + Trinity::GameObjectSearcher<Trinity::AllGameObjectsWithEntryInGrid> searcher(target, go_check); + m_creature->VisitNearbyGridObject(range, searcher); + if(!target) error_log("SD2 ERROR: Entry: %u not found!", entry); + return target; } Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 3ece26bdb6f..9c7ffc022eb 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -149,10 +149,10 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void DoTeleportAll(float x, float y, float z, float o); //Get a single creature of given entry - Unit* FindCreature(uint32 entry, uint32 range, uint32 district = ALL_DISTRICT); + Unit* FindCreature(uint32 entry, float range); //Get a single gameobject of given entry - GameObject* FindGameObject(uint32 entry, uint32 district = ALL_DISTRICT); + GameObject* FindGameObject(uint32 entry, float range); //Returns friendly unit with the most amount of hp missing from max hp Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff = 1); diff --git a/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp b/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp index 92dcb34a433..ad43b63b5f3 100644 --- a/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp +++ b/src/bindings/scripts/scripts/zone/arathi_highlands/arathi_highlands.cpp @@ -34,7 +34,7 @@ EndContentData */ #define SAY_PROGRESS_1 "Ok, $N. Follow me to the cave where I'll attempt to harness the power of the rune stone into these goggles." #define SAY_PROGRESS_2 "I discovered this cave on our first day here. I believe the energy in the stone can be used to our advantage." -#define SAY_PROGRESS_3 "I'll begin drawing energy from the stone. Your job, $N, i to defend me. This place is cursed... trust me." +#define SAY_PROGRESS_3 "I'll begin drawing energy from the stone. Your job, $N, is to defend me. This place is cursed... trust me." #define EMOTE_PROGRESS_4 "begins tinkering with the goggles before the stone." #define SAY_AGGRO "Help!!! Get these things off me so I can get my work done!" #define SAY_PROGRESS_5 "Almost done! Just a little longer!" @@ -61,10 +61,8 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI case 8:DoTextEmote(EMOTE_PROGRESS_4, NULL);break; case 9: { - Creature* sum1 = m_creature->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96, -2142.49, 20.15, 1.0f, TEMPSUMMON_DEAD_DESPAWN, 0); - Creature* sum2 = m_creature->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96, -2142.49, 20.15, 1.0f, TEMPSUMMON_DEAD_DESPAWN, 0); - sum1->Attack(m_creature, true); - sum2->Attack(m_creature, true); + m_creature->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96, -2142.49, 20.15, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); + m_creature->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96, -2142.49, 20.15, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); break; } case 10:DoSay(SAY_PROGRESS_5, LANG_UNIVERSAL, player, true);break; @@ -73,11 +71,17 @@ struct TRINITY_DLL_DECL npc_professor_phizzlethorpeAI : public npc_escortAI case 20: DoTextEmote(EMOTE_PROGRESS_8, NULL); DoSay(SAY_PROGRESS_9, LANG_UNIVERSAL, player, true); + if(player) ((Player*)player)->GroupEventHappens(QUEST_SUNKEN_TREASURE, m_creature); break; } } + void JustSummoned(Creature *summoned) + { + summoned->AI()->AttackStart(m_creature); + } + void Reset(){} void Aggro(Unit* who) diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp index f26209d4340..5274cdc7ec4 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp @@ -1879,7 +1879,7 @@ void boss_illidan_stormrageAI::JustSummoned(Creature* summon) Unit *target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0, 999, true); if(!target || target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0) || target->HasAura(SPELL_PARASITIC_SHADOWFIEND2, 0)) - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true); + target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0, 999, true); if(target) summon->AI()->AttackStart(target); }break; diff --git a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp index b38e21687da..6350040cfe4 100644 --- a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp +++ b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp @@ -161,7 +161,7 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI case 0: { m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - GameObject* Cage = FindGameObject(GO_CAGE); + GameObject* Cage = FindGameObject(GO_CAGE, 99); if(Cage) Cage->SetGoState(0); DoScriptText(SAY_START, m_creature, player); @@ -212,7 +212,7 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI if (!IsBeingEscorted) m_creature->setFaction(1602); - GameObject* Cage = FindGameObject(GO_CAGE); + GameObject* Cage = FindGameObject(GO_CAGE, 99); if(Cage) Cage->SetGoState(1); } diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp index bffb418980a..17fec0d2e75 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_nightbane.cpp @@ -16,18 +16,389 @@ /* ScriptData SDName: Boss_Nightbane -SD%Complete: 0 -SDComment: Place holder +SD%Complete: 50 +SDComment: skelleton adds, optimice some "if"s, timers, rain of bones applied self(!?) SDCategory: Karazhan EndScriptData */ #include "precompiled.h" - +#include "def_karazhan.h" + +//phase 1 #define SPELL_BELLOWING_ROAR 39427 -#define SPELL_CHARRED_EARTH 30129 //Also 30209 (Target Charred Earth) triggers this +#define SPELL_CHARRED_EARTH 30129 //Also 30209 (Target Charred Earth) triggers this #define SPELL_DISTRACTING_ASH 30130 #define SPELL_SMOLDERING_BREATH 30210 #define SPELL_TAIL_SWEEP 25653 +//phase 2 #define SPELL_RAIN_OF_BONES 37098 #define SPELL_SMOKING_BLAST 37057 #define SPELL_FIREBALL_BARRAGE 30282 +#define SPELL_SEARING_CINDERS 30127 + +float IntroWay[8][3] = +{ + {-11053.37,-1794.48,149}, + {-11141.07,-1841.40,125}, + {-11187.28,-1890.23,125}, + {-11189.20,-1931.25,125}, + {-11153.76,-1948.93,125}, + {-11128.73,-1929.75,125}, + {-11140 , -1915 ,122}, + {-11163 , -1903 ,91.473} +}; + +//float IntroWay[5][3] = +//{ +// {-11000.00, -1765.75, 140.40}, +// {-11000.00, -1765.75, 171.00}, +// {-11173.67, -1832.26, 117.76}, +// {-11142.75, -1916.78, 119.769}, +// {-11161.91, -1911.148, 91.473} +//}; + +struct TRINITY_DLL_DECL boss_nightbaneAI : public ScriptedAI +{ + boss_nightbaneAI(Creature* c) : ScriptedAI(c) + { + pInstance = ((ScriptedInstance*)c->GetInstanceData()); + intro = true; + Reset(); + } + + ScriptedInstance* pInstance; + + uint32 phase; + + bool rainbones; + + uint32 bellowingroar_timer; + uint32 charredearth_timer; + uint32 distractingash_timer; + uint32 smolderingbreath_timer; + uint32 tailsweep_timer; + uint32 rainofbones_timer; + uint32 smokingblast_timer; + uint32 fireballbarrage_timer; + uint32 searingcinders_timer; + + uint32 fly_count; + uint32 fly_timer; + + bool intro; + bool flying; + uint32 wait_timer; + uint32 MovePhase; + + void Reset() + { + phase =1; + bellowingroar_timer = 30000; + charredearth_timer = 15000; + distractingash_timer = 20000; + smolderingbreath_timer = 10000; + tailsweep_timer = 12000; + rainofbones_timer = 10000; + smokingblast_timer = 20000; + fireballbarrage_timer = 13000; + searingcinders_timer = 14000; + + fly_count = 0; + + m_creature->SetSpeed(MOVE_RUN,2); + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + m_creature->setActive(true); + wait_timer = 1000; + MovePhase = 0; + + if(pInstance) + pInstance->SetData(DATA_NIGHTBANE_EVENT, NOT_STARTED); + + flying = false; + + if(!intro) + { + m_creature->SetHomePosition(IntroWay[7][0],IntroWay[7][1],IntroWay[7][2],0); + m_creature->GetMotionMaster()->MoveTargetedHome(); + } + } + + void Aggro(Unit *who) + { + if(pInstance) + pInstance->SetData(DATA_NIGHTBANE_EVENT, IN_PROGRESS); + } + void AttackStart(Unit* who) + { + if(!intro && !flying) + ScriptedAI::AttackStart(who); + } + + void JustDied(Unit* killer) + { + if(pInstance) + pInstance->SetData(DATA_NIGHTBANE_EVENT, DONE); + } + void MoveInLineOfSight(Unit *who) + { + if(!intro && !flying) + { + if(!m_creature->getVictim() && m_creature->canStartAttack(who)) + ScriptedAI::AttackStart(who); + } + } + + void MovementInform(uint32 type, uint32 id) + { + if(type != POINT_MOTION_TYPE) + return; + + if(intro) + { + if(id >= 8) + { + intro = false; + m_creature->SetHomePosition(IntroWay[7][0],IntroWay[7][1],IntroWay[7][2],0); + return; + } + + wait_timer = 1; + } + + if(flying) + { + if(id == 0) + { + flying = false; + phase = 2; + return; + } + if(id == 3) + { + MovePhase = 4; + wait_timer = 1; + return; + } + if(id == 8) + { + flying = false; + phase = 1; + return; + } + + wait_timer = 1; + } + } + + void UpdateAI(const uint32 diff) + { + if(wait_timer) + if(wait_timer < diff) + { + if(intro) + { + if(MovePhase >= 7) + { + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + m_creature->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]); + } + else + { + m_creature->GetMotionMaster()->MovePoint(MovePhase,IntroWay[MovePhase][0],IntroWay[MovePhase][1],IntroWay[MovePhase][2]); + MovePhase++; + } + } + + + if(flying) + { + if(MovePhase >= 7) + { + m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + m_creature->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]); + } + else + { + m_creature->GetMotionMaster()->MovePoint(MovePhase,IntroWay[MovePhase][0],IntroWay[MovePhase][1],IntroWay[MovePhase][2]); + MovePhase++; + } + } + + wait_timer = 0; + }else wait_timer -= diff; + + if(!m_creature->SelectHostilTarget()) + return; + + if(flying) + return; + + // Phase 1 "GROUND FIGHT" + if(phase == 1) + { + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + if (bellowingroar_timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_BELLOWING_ROAR); + bellowingroar_timer = 30000+rand()%10000 ; //Timer + }else bellowingroar_timer -= diff; + + if (smolderingbreath_timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_SMOLDERING_BREATH); + smolderingbreath_timer = 20000;//timer + + }else smolderingbreath_timer -= diff; + + if (charredearth_timer < diff) + { + Unit* target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM,0); + DoCast(target,SPELL_CHARRED_EARTH); + charredearth_timer = 20000; //timer + }else charredearth_timer -= diff; + + if (tailsweep_timer < diff) + { + Unit* target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM,0); + + if (!m_creature->HasInArc( M_PI, target)) + DoCast(target,SPELL_TAIL_SWEEP); + tailsweep_timer = 15000;//timer + }else tailsweep_timer -= diff; + + if (searingcinders_timer < diff) + { + Unit* target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM,0); + + DoCast(target,SPELL_SEARING_CINDERS); + searingcinders_timer = 10000; //timer + }else searingcinders_timer -= diff; + + uint32 prozent; + prozent = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth(); + + if (prozent < 75 && fly_count == 0) // first take off 75% + { + m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); + (*m_creature).GetMotionMaster()->Clear(false); + (*m_creature).GetMotionMaster()->MovePoint(0,IntroWay[2][0],IntroWay[2][1],IntroWay[2][2]); + flying = true; + + fly_timer = 45000+rand()%15000; + fly_count++; + + rainofbones_timer = 5000; + rainbones = false; + } + + if (prozent < 50 && fly_count == 1) // secound take off 50% + { + m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); + (*m_creature).GetMotionMaster()->Clear(false); + (*m_creature).GetMotionMaster()->MovePoint(0,IntroWay[2][0],IntroWay[2][1],IntroWay[2][2]); + + flying = true; + fly_timer = 45000+rand()%15000; + fly_count++; + + rainofbones_timer = 5000; + rainbones = false; + } + + if (prozent < 25 && fly_count == 2) // third take off 25% + { + m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); + m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); + (*m_creature).GetMotionMaster()->Clear(false); + (*m_creature).GetMotionMaster()->MovePoint(0,IntroWay[2][0],IntroWay[2][1],IntroWay[2][2]); + + flying = true; + //phase = 2; + fly_timer = 45000+rand()%15000; + fly_count++; + + rainofbones_timer = 5000; + rainbones = false; + } + + DoMeleeAttackIfReady(); + } + + //Phase 2 "FLYING FIGHT" + if (phase == 2) + { + if (!rainbones) + { + if (rainofbones_timer < diff && !rainbones) // only once at the beginning of phase 2 + { + DoCast(m_creature->getVictim(),SPELL_RAIN_OF_BONES); + rainbones = true; + smokingblast_timer = 20000; + }else rainofbones_timer -= diff; + + if (distractingash_timer < diff) + { + Unit* target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM,0); + + DoCast(target,SPELL_DISTRACTING_ASH); + distractingash_timer = 2000;//timer wrong + }else distractingash_timer -= diff; + } + + if (rainbones) + { + if (smokingblast_timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_SMOKING_BLAST); + smokingblast_timer = 1500 ; //timer wrong + }else smokingblast_timer -= diff; + } + + if (fireballbarrage_timer < diff) + { + Unit* target = NULL; + target = SelectUnit(SELECT_TARGET_FARTHEST,0); + + DoCast(target,SPELL_FIREBALL_BARRAGE); + fireballbarrage_timer = 20000; //Timer + }else fireballbarrage_timer -= diff; + + if (fly_timer < diff) //landing + { + //m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + //m_creature->SetHover(false); + (*m_creature).GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MovePoint(3,IntroWay[3][0],IntroWay[3][1],IntroWay[3][2]); + flying = true; + //wait_timer = 1; + //phase = 1; + }else fly_timer -= diff; + } + } +}; + +CreatureAI* GetAI_boss_nightbane(Creature *_Creature) +{ + return new boss_nightbaneAI (_Creature); +} + +void AddSC_boss_nightbane() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_nightbane"; + newscript->GetAI = GetAI_boss_nightbane; + newscript->RegisterSelf(); +}
\ No newline at end of file diff --git a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp index 5af12a4fb0b..9fea30e1c93 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp @@ -59,7 +59,8 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance uint64 MassiveDoor; // Door at Netherspite uint64 GamesmansDoor; // Door before Chess uint64 GamesmansExitDoor; // Door after Chess - uint64 NetherspaceDoor; // Door at Malchezaar + uint64 NetherspaceDoor; // Door at Malchezaar + uint64 MastersTerraceDoor[2]; uint64 ImageGUID; @@ -84,6 +85,8 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance GamesmansDoor = 0; GamesmansExitDoor = 0; NetherspaceDoor = 0; + MastersTerraceDoor[0]= 0; + MastersTerraceDoor[1]= 0; ImageGUID = 0; } @@ -199,6 +202,8 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance case 184276: GamesmansDoor = go->GetGUID(); break; case 184277: GamesmansExitDoor = go->GetGUID(); break; case 185134: NetherspaceDoor = go->GetGUID(); break; + case 184274: MastersTerraceDoor[0] = go->GetGUID(); break; + case 184280: MastersTerraceDoor[1] = go->GetGUID(); break; } switch(OperaEvent) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index fedcd982a35..1d45afef5ea 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -61,6 +61,7 @@ ChatCommand * ChatHandler::getCommandTable() static ChatCommand serverSetCommandTable[] = { { "loglevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogLevelCommand, "", NULL }, + { "difftime", SEC_CONSOLE, true, &ChatHandler::HandleServerSetDiffTimeCommand, "", NULL }, { "motd", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetMotdCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; diff --git a/src/game/Chat.h b/src/game/Chat.h index a3ce666541b..fa6c885bed3 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -288,6 +288,7 @@ class ChatHandler bool HandleServerRestartCommand(const char* args); bool HandleServerSetMotdCommand(const char* args); bool HandleServerSetLogLevelCommand(const char* args); + bool HandleServerSetDiffTimeCommand(const char* args); bool HandleServerShutDownCommand(const char* args); bool HandleServerShutDownCancelCommand(const char* args); diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 61c626a544c..90162a213d7 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -778,8 +778,7 @@ LootStoreItem const * LootTemplate::LootGroup::Roll() const return &ExplicitlyChanced[i]; ItemPrototype const *pProto = objmgr.GetItemPrototype(ExplicitlyChanced[i].itemid); - float qualityMultiplier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; - Roll -= ExplicitlyChanced[i].chance * qualityMultiplier; + Roll -= ExplicitlyChanced[i].chance; if (Roll < 0) return &ExplicitlyChanced[i]; } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 802b0f7feec..b973a8cb11e 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1778,7 +1778,9 @@ bool InstanceMap::Add(Player *player) { sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); if(groupBind) sLog.outError("InstanceMap::Add: the group is bound to instance %d,%d,%d,%d,%d,%d", groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset()); - player->UnbindInstance(GetId(), GetSpawnMode()); + sLog.outError("InstanceMap::Add: do not let player %s enter instance otherwise crash will happen", player->GetName()); + return false; + //player->UnbindInstance(GetId(), GetSpawnMode()); //assert(false); } // bind to the group or keep using the group save diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 1267d2b28aa..f4bb7eeebb6 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1004,6 +1004,11 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) { m_caster->CombatStart(unit); } + else if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_AURA_CC) + { + if(!unit->IsStandState()) + unit->SetStandState(PLAYER_STATE_NONE); + } } } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 91b85df1a39..282fc4bc095 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -5956,6 +5956,13 @@ void Aura::PeriodicTick() int32 gain = pCaster->ModifyPower(power,gain_amount); m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto()); } + // Mark of Kaz'rogal + if(GetId() == 31447 && m_target->GetPower(power) == 0) + { + m_target->CastSpell(m_target, 31463, true, 0, this); + // Remove aura + SetAuraDuration(0); + } break; } case SPELL_AURA_PERIODIC_ENERGIZE: diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 5526e3a7002..93cfb963b00 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7612,7 +7612,8 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, if (spellProto->Id == 15290 || spellProto->Id == 39373 || spellProto->Id == 33778 || spellProto->Id == 379 || spellProto->Id == 38395 || spellProto->Id == 40972 || - spellProto->Id == 22845 || spellProto->Id == 33504) + spellProto->Id == 22845 || spellProto->Id == 33504 || + spellProto->Id == 34299) return healamount; int32 AdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto)); @@ -8238,7 +8239,7 @@ void Unit::SetInCombatWith(Unit* enemy) void Unit::CombatStart(Unit* target) { - if(!target->IsStandState() && !target->hasUnitState(UNIT_STAT_STUNNED)) + if(!target->IsStandState()/* && !target->hasUnitState(UNIT_STAT_STUNNED)*/) target->SetStandState(PLAYER_STATE_NONE); //Call creature group update diff --git a/src/game/World.h b/src/game/World.h index 756343064ed..977e0aef173 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -422,6 +422,7 @@ class World uint32 GetUptime() const { return uint32(m_gameTime - m_startTime); } /// Update time uint32 GetUpdateTime() const { return m_updateTime; } + void SetRecordDiffInterval(int32 t) { if(t >= 0) m_configs[CONFIG_INTERVAL_LOG_UPDATE] = (uint32)t; } /// Get the maximum skill level a player can reach uint16 GetConfigMaxSkillValue() const diff --git a/src/trinitycore/CliRunnable.cpp b/src/trinitycore/CliRunnable.cpp new file mode 100644 index 00000000000..78c6e0dbb85 --- /dev/null +++ b/src/trinitycore/CliRunnable.cpp @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * + * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/// \addtogroup Trinityd +/// @{ +/// \file + +#include "Common.h" +#include "Language.h" +#include "Log.h" +#include "World.h" +#include "ScriptCalls.h" +#include "ObjectMgr.h" +#include "WorldSession.h" +#include "Config/ConfigEnv.h" +#include "Util.h" +#include "AccountMgr.h" +#include "CliRunnable.h" +#include "MapManager.h" +#include "Player.h" +#include "Chat.h" + +void utf8print(const char* str) +{ +#if PLATFORM == PLATFORM_WINDOWS + wchar_t wtemp_buf[6000]; + size_t wtemp_len = 6000-1; + if(!Utf8toWStr(str,strlen(str),wtemp_buf,wtemp_len)) + return; + + char temp_buf[6000]; + CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1); + printf(temp_buf); +#else + printf(str); +#endif +} + +/// Delete a user account and all associated characters in this realm +/// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account +bool ChatHandler::HandleAccountDeleteCommand(const char* args) +{ + if(!*args) + return false; + + ///- Get the account name from the command line + char *account_name_str=strtok ((char*)args," "); + if (!account_name_str) + return false; + + std::string account_name = account_name_str; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 account_id = accmgr.GetId(account_name); + if(!account_id) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + /// Commands not recommended call from chat, but support anyway + if(m_session) + { + uint32 targetSecurity = accmgr.GetSecurity(account_id); + + /// can delete only for account with less security + /// This is also reject self apply in fact + if (targetSecurity >= m_session->GetSecurity()) + { + SendSysMessage (LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage (true); + return false; + } + } + + AccountOpResult result = accmgr.DeleteAccount(account_id); + switch(result) + { + case AOR_OK: + PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str()); + break; + case AOR_NAME_NOT_EXIST: + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + case AOR_DB_INTERNAL_ERROR: + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; + default: + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleCharacterDeleteCommand(const char* args) +{ + if(!*args) + return false; + + char *character_name_str = strtok((char*)args," "); + if(!character_name_str) + return false; + + std::string character_name = character_name_str; + if(!normalizePlayerName(character_name)) + return false; + + uint64 character_guid; + uint32 account_id; + + Player *player = objmgr.GetPlayer(character_name.c_str()); + if(player) + { + character_guid = player->GetGUID(); + account_id = player->GetSession()->GetAccountId(); + player->GetSession()->KickPlayer(); + } + else + { + character_guid = objmgr.GetPlayerGUIDByName(character_name); + if(!character_guid) + { + PSendSysMessage(LANG_NO_PLAYER,character_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + account_id = objmgr.GetPlayerAccountIdByGUID(character_guid); + } + + std::string account_name; + accmgr.GetName (account_id,account_name); + + Player::DeleteFromDB(character_guid, account_id, true); + PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id); + return true; +} + +/// Exit the realm +bool ChatHandler::HandleServerExitCommand(const char* args) +{ + SendSysMessage(LANG_COMMAND_EXIT); + World::StopNow(SHUTDOWN_EXIT_CODE); + return true; +} + +/// Display info on users currently in the realm +bool ChatHandler::HandleAccountOnlineListCommand(const char* args) +{ + ///- Get the list of accounts ID logged to the realm + QueryResult *resultDB = CharacterDatabase.Query("SELECT name,account FROM characters WHERE online > 0"); + if (!resultDB) + return true; + + ///- Display the list of account/characters online + SendSysMessage("====================================================================="); + SendSysMessage(LANG_ACCOUNT_LIST_HEADER); + SendSysMessage("====================================================================="); + + ///- Circle through accounts + do + { + Field *fieldsDB = resultDB->Fetch(); + std::string name = fieldsDB[0].GetCppString(); + uint32 account = fieldsDB[1].GetUInt32(); + + ///- Get the username, last IP and GM level of each account + // No SQL injection. account is uint32. + // 0 1 2 3 + QueryResult *resultLogin = loginDatabase.PQuery("SELECT username, last_ip, gmlevel, expansion FROM account WHERE id = '%u'",account); + + if(resultLogin) + { + Field *fieldsLogin = resultLogin->Fetch(); + PSendSysMessage("|%15s| %20s | %15s |%4d|%5d|", + fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsLogin[2].GetUInt32(),fieldsLogin[3].GetUInt32()); + + delete resultLogin; + } + else + PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); + + }while(resultDB->NextRow()); + + delete resultDB; + + SendSysMessage("====================================================================="); + return true; +} + +/// Create an account +bool ChatHandler::HandleAccountCreateCommand(const char* args) +{ + if(!*args) + return false; + + ///- %Parse the command line arguments + char *szAcc = strtok((char*)args, " "); + char *szPassword = strtok(NULL, " "); + if(!szAcc || !szPassword) + return false; + + // normilized in accmgr.CreateAccount + std::string account_name = szAcc; + std::string password = szPassword; + + AccountOpResult result = accmgr.CreateAccount(account_name, password); + switch(result) + { + case AOR_OK: + PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str()); + break; + case AOR_NAME_TOO_LONG: + SendSysMessage(LANG_ACCOUNT_TOO_LONG); + SetSentErrorMessage(true); + return false; + case AOR_NAME_ALREDY_EXIST: + SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); + SetSentErrorMessage(true); + return false; + case AOR_DB_INTERNAL_ERROR: + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; + default: + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +/// Set the level of logging +bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) +{ + if(!*args) + return false; + + char *NewLevel = strtok((char*)args, " "); + if (!NewLevel) + return false; + + sLog.SetLogLevel(NewLevel); + return true; +} + +/// set diff time record interval +bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args) +{ + if(!*args) + return false; + + char *NewTimeStr = strtok((char*)args, " "); + if(!NewTimeStr) + return false; + + int32 NewTime =atoi(NewTimeStr); + if(NewTime < 0) + return false; + + sWorld.SetRecordDiffInterval(NewTime); + printf( "Record diff every %u ms\n", NewTime); + return true; +} + + +/// @} + +#ifdef linux +// Non-blocking keypress detector, when return pressed, return 1, else always return 0 +int kb_hit_return() +{ + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); +} +#endif + +/// %Thread start +void CliRunnable::run() +{ + ///- Init new SQL thread for the world database (one connection call enough) + WorldDatabase.ThreadStart(); // let thread do safe mySQL requests + + char commandbuf[256]; + + ///- Display the list of available CLI functions then beep + sLog.outString(); + + if(sConfig.GetBoolDefault("BeepAtStart", true)) + printf("\a"); // \a = Alert + + // print this here the first time + // later it will be printed after command queue updates + printf("TC>"); + + ///- As long as the World is running (no World::m_stopEvent), get the command line and handle it + while (!World::IsStopped()) + { + fflush(stdout); + #ifdef linux + while (!kb_hit_return() && !World::IsStopped()) + // With this, we limit CLI to 10commands/second + usleep(100); + if (World::IsStopped()) + break; + #endif + char *command_str = fgets(commandbuf,sizeof(commandbuf),stdin); + if (command_str != NULL) + { + for(int x=0;command_str[x];x++) + if(command_str[x]=='\r'||command_str[x]=='\n') + { + command_str[x]=0; + break; + } + + + if(!*command_str) + { + printf("TC>"); + continue; + } + + std::string command; + if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8 + { + printf("TC>"); + continue; + } + + sWorld.QueueCliCommand(&utf8print,command.c_str()); + } + else if (feof(stdin)) + { + World::StopNow(SHUTDOWN_EXIT_CODE); + } + } + + ///- End the database thread + WorldDatabase.ThreadEnd(); // free mySQL thread resources +} |