aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgvcoman <none@none>2008-11-21 19:16:19 -0500
committergvcoman <none@none>2008-11-21 19:16:19 -0500
commit9ceb36a5274611e576aa4c5bd4488b9b9bdf18cc (patch)
treeece878258f15fb5af52e5829e640734dee9c1df2
parent1bd37790b564be487ed16ae897484a4d8c80a2de (diff)
parentb2ba78e57a7c1895d1bacf950a3705eedd01c256 (diff)
Merge with 273 (aab191f73e46).
--HG-- branch : trunk
-rw-r--r--sql/updates/273_world_scripts.sql2
-rw-r--r--src/bindings/scripts/scripts/creature/mob_event_ai.cpp39
-rw-r--r--src/bindings/scripts/scripts/creature/mob_event_ai.h8
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp157
-rw-r--r--src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp98
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp2
-rw-r--r--src/game/GridStates.cpp8
-rw-r--r--src/game/Map.cpp125
-rw-r--r--src/game/Map.h6
-rw-r--r--src/game/Object.cpp19
-rw-r--r--src/game/Object.h2
-rw-r--r--src/game/ObjectAccessor.cpp44
-rw-r--r--src/game/ObjectAccessor.h6
-rw-r--r--src/game/Player.h2
17 files changed, 395 insertions, 129 deletions
diff --git a/sql/updates/273_world_scripts.sql b/sql/updates/273_world_scripts.sql
new file mode 100644
index 00000000000..d3188c1306c
--- /dev/null
+++ b/sql/updates/273_world_scripts.sql
@@ -0,0 +1,2 @@
+UPDATE `creature_template` SET `ScriptName`='npc_wounded_blood_elf' WHERE `entry`='16993';
+UPDATE `creature_template` SET `ScriptName` = 'mob_phase_hunter' WHERE `entry` = '18879'; \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
index af945282935..289b6b925c5 100644
--- a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
+++ b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
@@ -6,12 +6,12 @@
*
* 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
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
@@ -965,6 +965,17 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
DoZoneInCombat();
}
break;
+
+ // TRINITY ONLY
+ case ACTION_T_SET_ACTIVE:
+ m_creature->setActive(param1 ? true : false);
+ break;
+ case ACTION_T_SET_AGGRESSIVE:
+ m_creature->SetAggressive(param1 ? true : false);
+ break;
+ case ACTION_T_ATTACK_START_PULSE:
+ AttackStart(m_creature->SelectNearestTarget((float)param1));
+ break;
}
}
@@ -1192,24 +1203,12 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
}
}
- if (m_creature->isCivilian() && m_creature->IsNeutralToAll())
- return;
-
- if (m_creature->canAttack(who) && who->isInAccessiblePlaceFor(m_creature) && m_creature->IsHostileTo(who))
- {
- if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
- return;
+ // do we need this?
+ //if (m_creature->isCivilian() && m_creature->IsNeutralToAll())
+ // return;
- float attackRadius = m_creature->GetAttackDistance(who);
- if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
- {
- //if(who->HasStealthAura())
- // who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
-
- //Begin melee attack if we are within range
- AttackStart(who);
- }
- }
+ if(m_creature->canStartAttack(who))
+ AttackStart(who);
}
void SpellHit(Unit* pUnit, const SpellEntry* pSpell)
@@ -1292,6 +1291,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
//Do not decrement timers if event cannot trigger in this phase
if (!((*i).Event.event_inverse_phase_mask & (1 << Phase)))
(*i).Time -= EventDiff;
+
//Skip processing of events that have time remaining
continue;
}
@@ -1328,6 +1328,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
//Melee Auto-Attack
if (Combat && MeleeEnabled)
DoMeleeAttackIfReady();
+
}
};
diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.h b/src/bindings/scripts/scripts/creature/mob_event_ai.h
index 1183fdd3c73..d08a6b33a2b 100644
--- a/src/bindings/scripts/scripts/creature/mob_event_ai.h
+++ b/src/bindings/scripts/scripts/creature/mob_event_ai.h
@@ -1,6 +1,6 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
-* This program is free software licensed under GPL version 2
-* Please see the included DOCS/LICENSE.TXT for more information */
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_EVENTAI_H
#define SC_EVENTAI_H
@@ -76,6 +76,10 @@ enum Action_Types
ACTION_T_DIE = 37, //No Params
ACTION_T_ZONE_COMBAT_PULSE = 38, //No Params
+ ACTION_T_SET_ACTIVE = 101, //Apply
+ ACTION_T_SET_AGGRESSIVE = 102, //Apply
+ ACTION_T_ATTACK_START_PULSE = 103, //Distance
+
ACTION_T_END,
};
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 3ccd790a648..2f92a1e6cd4 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
@@ -301,7 +301,7 @@ void hyjalAI::UpdateWorldState(uint32 field, uint32 value)
data << field;
data << value;
- ((InstanceMap*)map)->SendToPlayers(&data);
+ map->SendToPlayers(&data);
// TODO: Uncomment and remove everything above this line only when the core patch for this is accepted
//m_creature->GetMap()->UpdateWorldState(field, value);
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp
index 3c3971d6036..66b9a7bfcc3 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp
@@ -149,7 +149,7 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance
data << field;
data << value;
- ((InstanceMap*)instance)->SendToPlayers(&data);
+ instance->SendToPlayers(&data);
}
const char* Save()
diff --git a/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp b/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
index 81d23457aab..d272ac81cb1 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Hellfire_Peninsula
SD%Complete: 100
-SDComment: Quest support: 10129, 10146, 10162, 10163, 10340, 10346, 10347, 10382 (Special flight paths)
+SDComment: Quest support: 9375, 10129, 10146, 10162, 10163, 10340, 10346, 10347, 10382 (Special flight paths)
SDCategory: Hellfire Peninsula
EndScriptData */
@@ -25,9 +25,11 @@ EndScriptData */
npc_wing_commander_dabiree
npc_gryphoneer_windbellow
npc_wing_commander_brack
+npc_wounded_blood_elf
EndContentData */
#include "precompiled.h"
+#include "../../npc/npc_escortAI.h"
/*######
## npc_wing_commander_dabiree
@@ -160,6 +162,151 @@ bool GossipSelect_npc_wing_commander_brack(Player *player, Creature *_Creature,
}
/*######
+## npc_wounded_blood_elf
+######*/
+
+#define QUEST_THE_ROAD_TO_FALCON_WATCH 9375
+#define SAY1 "Thank you for agreeing to help. Now, let's get out of here $N."
+#define SAY2 "Over there! They're following us!"
+#define SAY3 "Allow me a moment to rest. The journey taxes what little strength I have."
+#define SAY4 "Did you hear something?"
+#define SAY5 "Falcon Watch, at last! Now, where's my... Oh no! My pack, it's missing! Where has -"
+#define SAYAGGRO "You won't keep me from getting to Falcon Watch!"
+
+struct TRINITY_DLL_DECL npc_wounded_blood_elfAI : public npc_escortAI
+{
+ npc_wounded_blood_elfAI(Creature *c) : npc_escortAI(c) {Reset();}
+
+ void WaypointReached(uint32 i)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+
+ if (!player)
+ return;
+
+ switch (i)
+ {
+
+ case 0:
+ DoSay(SAY1, LANG_UNIVERSAL, player);
+ // Change faction, so mobs can attack
+ m_creature->setFaction(1610);
+ break;
+
+ case 9:
+ DoSay(SAY2, LANG_UNIVERSAL, player);
+ // Spawn two Haal'eshi Talonguard
+ {
+ Creature* temp1 = m_creature->SummonCreature(16967, m_creature->GetPositionX()-15, m_creature->GetPositionY()-15, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
+ if (temp1) temp1->AI()->AttackStart(m_creature);
+ Creature* temp2 = m_creature->SummonCreature(16967, m_creature->GetPositionX()-17, m_creature->GetPositionY()-17, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
+ if (temp2) temp2->AI()->AttackStart(m_creature);
+ }
+ break;
+
+ case 13:
+ DoSay(SAY3, LANG_UNIVERSAL, player);
+ // NPC "should" kneel
+ m_creature->HandleEmoteCommand(EMOTE_STATE_KNEEL);
+ break;
+
+ case 14:
+ DoSay(SAY4, LANG_UNIVERSAL, player);
+ // Spawn two Haal'eshi Windwalker
+ {
+ Creature* temp3 = m_creature->SummonCreature(16966, m_creature->GetPositionX()-15, m_creature->GetPositionY()-15, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
+ if (temp3) temp3->AI()->AttackStart(m_creature);
+ Creature* temp4 = m_creature->SummonCreature(16966, m_creature->GetPositionX()-17, m_creature->GetPositionY()-17, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
+ if (temp4) temp4->AI()->AttackStart(m_creature);
+ }
+ break;
+
+ case 27:
+ DoSay(SAY5, LANG_UNIVERSAL, player);
+ // Set faction back to normal
+ m_creature->setFaction(1604);
+ // Award quest credit
+ if( PlayerGUID )
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+ if( player && player->GetTypeId() == TYPEID_PLAYER )
+ ((Player*)player)->GroupEventHappens(9375,m_creature);
+ }
+ break;
+ }
+ }
+
+ void Aggro(Unit* who)
+ {
+ DoSay(SAYAGGRO, LANG_UNIVERSAL, who);
+ }
+
+ void Reset() { }
+
+ void JustDied(Unit* killer)
+ // If NPC dies, Quest fail
+ {
+ if (PlayerGUID)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+ if (player)
+ ((Player*)player)->FailQuest(QUEST_THE_ROAD_TO_FALCON_WATCH);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ npc_escortAI::UpdateAI(diff);
+ }
+};
+
+bool QuestAccept_wounded_blood_elf(Player* player, Creature* creature, Quest const* quest)
+// Begin the escort quest
+{
+ if (quest->GetQuestId() == QUEST_THE_ROAD_TO_FALCON_WATCH)
+ {
+ ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID());
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_wounded_blood_elf(Creature *_Creature)
+{
+ npc_wounded_blood_elfAI* thisAI = new npc_wounded_blood_elfAI(_Creature);
+
+ thisAI->AddWaypoint(0, -1137.72, 4272.10, 14.04, 3000);
+ thisAI->AddWaypoint(1, -1141.34, 4232.42, 14.63);
+ thisAI->AddWaypoint(2, -1133.47, 4220.88, 11.78);
+ thisAI->AddWaypoint(3, -1126.18, 4213.26, 13.51);
+ thisAI->AddWaypoint(4, -1100.12, 4204.32, 16.41);
+ thisAI->AddWaypoint(5, -1063.68, 4197.92, 15.51);
+ thisAI->AddWaypoint(6, -1027.28, 4194.36, 15.52);
+ thisAI->AddWaypoint(7, -995.68, 4189.59, 19.84);
+ thisAI->AddWaypoint(8, -970.90, 4188.60, 24.61);
+ thisAI->AddWaypoint(9, -961.93, 4193.34, 26.11, 80000); // Summon 1
+ thisAI->AddWaypoint(10, -935.52, 4210.99, 31.98);
+ thisAI->AddWaypoint(11, -913.42, 4218.27, 37.29);
+ thisAI->AddWaypoint(12, -896.53, 4207.73, 43.23);
+ thisAI->AddWaypoint(13, -868.49, 4194.77, 46.75, 17000); // Kneel and Rest Here
+ thisAI->AddWaypoint(14, -852.83, 4198.29, 47.28, 80000); // Summon 2
+ thisAI->AddWaypoint(15, -819.85, 4200.50, 46.37);
+ thisAI->AddWaypoint(16, -791.92, 4201.96, 44.19);
+ thisAI->AddWaypoint(17, -774.42, 4202.46, 47.41);
+ thisAI->AddWaypoint(18, -762.90, 4202.17, 48.81);
+ thisAI->AddWaypoint(19, -728.25, 4195.35, 50.68);
+ thisAI->AddWaypoint(20, -713.58, 4192.07, 53.98);
+ thisAI->AddWaypoint(21, -703.09, 4189.74, 56.96);
+ thisAI->AddWaypoint(22, -693.70, 4185.43, 57.06);
+ thisAI->AddWaypoint(23, -686.38, 4159.81, 60.26);
+ thisAI->AddWaypoint(24, -679.88, 4147.04, 64.20);
+ thisAI->AddWaypoint(25, -656.74, 4147.72, 64.11);
+ thisAI->AddWaypoint(26, -652.22, 4137.50, 64.58);
+ thisAI->AddWaypoint(27, -649.99, 4136.38, 64.63, 20000); // Award Quest Credit
+
+ return (CreatureAI*)thisAI;
+}
+
+/*######
##
######*/
@@ -184,4 +331,10 @@ void AddSC_hellfire_peninsula()
newscript->pGossipHello = &GossipHello_npc_wing_commander_brack;
newscript->pGossipSelect = &GossipSelect_npc_wing_commander_brack;
newscript->RegisterSelf();
-}
+
+ newscript = new Script;
+ newscript->Name="npc_wounded_blood_elf";
+ newscript->GetAI = &GetAI_npc_wounded_blood_elf;
+ newscript->pQuestAccept = &QuestAccept_wounded_blood_elf;
+ newscript->RegisterSelf();
+} \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
index 4125c4e888e..fbb4c20379b 100644
--- a/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
+++ b/src/bindings/scripts/scripts/zone/netherstorm/netherstorm.cpp
@@ -390,6 +390,99 @@ bool GossipSelect_npc_veronia(Player *player, Creature *_Creature, uint32 sender
}
/*######
+## mob_phase_hunter
+######*/
+
+#define SUMMONED_MOB 19595
+#define EMOTE_WEAK "is very weak"
+
+// Spells
+#define SPELL_PHASE_SLIP 36574
+#define SPELL_MANA_BURN 13321
+
+struct TRINITY_DLL_DECL mob_phase_hunterAI : public ScriptedAI
+{
+
+ mob_phase_hunterAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+ bool Weak;
+ int WeakPercent;
+ uint32 PlayerGUID;
+ uint32 Health;
+ uint32 Level;
+ uint32 PhaseSlipVulnerabilityTimer;
+ uint32 ManaBurnTimer;
+
+ void Reset()
+ {
+ Weak = false;
+ WeakPercent = 25 + (rand()%16); // 25-40
+ PlayerGUID = 0;
+ ManaBurnTimer = 5000 + (rand()%3 * 1000); // 5-8 sec cd
+ }
+
+ void Aggro(Unit *who)
+ {
+ PlayerGUID = who->GetGUID();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+
+ Player* target = NULL;
+ target = ((Player*)Unit::GetUnit((*m_creature), PlayerGUID));
+
+ if(!target)
+ 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)
+ {
+ DoCast(target, SPELL_MANA_BURN);
+ ManaBurnTimer = 8000 + (rand()%10 * 1000); // 8-18 sec cd
+ }
+ }
+ 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();
+
+ 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
+
+ if(DrainedPhaseHunter)
+ {
+ DrainedPhaseHunter->SetLevel(Level); // set the summoned mob's data
+ DrainedPhaseHunter->SetHealth(Health);
+ DrainedPhaseHunter->AI()->AttackStart(target);
+ }
+ } // end: support for quest 10190
+ }
+
+};
+
+CreatureAI* GetAI_mob_phase_hunter(Creature *_Creature)
+{
+ return new mob_phase_hunterAI (_Creature);
+}
+
+/*######
##
######*/
@@ -418,4 +511,9 @@ void AddSC_netherstorm()
newscript->pGossipHello = &GossipHello_npc_veronia;
newscript->pGossipSelect = &GossipSelect_npc_veronia;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_phase_hunter";
+ newscript->GetAI = GetAI_mob_phase_hunter;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
index 4b9eb2afa88..8f4b4b8d942 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp
@@ -169,7 +169,7 @@ struct TRINITY_DLL_DECL boss_akilzonAI : public ScriptedAI
WorldPacket data(SMSG_WEATHER, (4+4+4));
data << uint32(weather) << (float)grade << uint8(0);
- ((InstanceMap*)map)->SendToPlayers(&data);
+ map->SendToPlayers(&data);
}
void HandleStormSequence(Unit *Cloud) // 1: begin, 2-9: tick, 10: end
diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
index c0c68c1a2e4..bb847169e78 100644
--- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
+++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp
@@ -176,7 +176,7 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance
{
WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8);
data << field << value;
- ((InstanceMap*)instance)->SendToPlayers(&data);
+ instance->SendToPlayers(&data);
}
const char* Save()
diff --git a/src/game/GridStates.cpp b/src/game/GridStates.cpp
index 1f2df5e7c59..5cf5c8b8c11 100644
--- a/src/game/GridStates.cpp
+++ b/src/game/GridStates.cpp
@@ -10,12 +10,12 @@
*
* 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
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "GridStates.h"
@@ -36,7 +36,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
info.UpdateTimeTracker(t_diff);
if( info.getTimeTracker().Passed() )
{
- if( grid.ActiveObjectsInGrid() == 0 && !ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, m.GetId(), m.GetInstanceId()) )
+ if( grid.ActiveObjectsInGrid() == 0 && !m.ActiveObjectsNearGrid(x, y) )
{
ObjectGridStoper stoper(grid);
stoper.StopN();
@@ -50,7 +50,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
}
void
-IdleState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 &x, const uint32 &y, const uint32 &) const
+IdleState::Update(Map &m, NGridType &grid, GridInfo &, const uint32 &x, const uint32 &y, const uint32 &) const
{
m.ResetGridExpiry(grid);
grid.SetGridState(GRID_STATE_REMOVAL);
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 39006c932c6..f8201f53219 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -594,57 +594,69 @@ bool Map::loaded(const GridPair &p) const
return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) );
}
-void Map::Update(const uint32 &t_diff)
+void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff)
{
- // TODO: need have an active object list for every map
+ CellPair standing_cell(Trinity::ComputeCellPair(x, y));
- /*resetMarkedCells();
+ // Check for correctness of standing_cell, it also avoids problems with update_cell
+ if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
+ return;
+ // will this reduce the speed?
Trinity::ObjectUpdater updater(t_diff);
// for creature
TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);
// for pets
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
- for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
- {
- Player* plr = iter->getSource();
- if(!plr->IsInWorld())
- continue;
-
- CellPair standing_cell(Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()));
-
- // Check for correctness of standing_cell, it also avoids problems with update_cell
- if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
- continue;
+ // the overloaded operators handle range checking
+ // so ther's no need for range checking inside the loop
+ CellPair begin_cell(standing_cell), end_cell(standing_cell);
+ begin_cell << 1; begin_cell -= 1; // upper left
+ end_cell >> 1; end_cell += 1; // lower right
- // the overloaded operators handle range checking
- // so ther's no need for range checking inside the loop
- CellPair begin_cell(standing_cell), end_cell(standing_cell);
- begin_cell << 1; begin_cell -= 1; // upper left
- end_cell >> 1; end_cell += 1; // lower right
-
- for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
+ for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
+ {
+ for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
{
- for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
+ // marked cells are those that have been visited
+ // don't visit the same cell twice
+ uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
+ if(!isCellMarked(cell_id))
{
- // marked cells are those that have been visited
- // don't visit the same cell twice
- uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
- if(!isCellMarked(cell_id))
- {
- markCell(cell_id);
- CellPair pair(x,y);
- Cell cell(pair);
- cell.data.Part.reserved = CENTER_DISTRICT;
- cell.SetNoCreate();
- CellLock<NullGuard> cell_lock(cell, pair);
- cell_lock->Visit(cell_lock, grid_object_update, *this);
- cell_lock->Visit(cell_lock, world_object_update, *this);
- }
+ markCell(cell_id);
+ CellPair pair(x,y);
+ Cell cell(pair);
+ cell.data.Part.reserved = CENTER_DISTRICT;
+ cell.SetNoCreate();
+ CellLock<NullGuard> cell_lock(cell, pair);
+ cell_lock->Visit(cell_lock, grid_object_update, *this);
+ cell_lock->Visit(cell_lock, world_object_update, *this);
}
}
- }*/
+ }
+}
+
+void Map::Update(const uint32 &t_diff)
+{
+ resetMarkedCells();
+
+ // update cells around players
+ for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
+ {
+ Player* plr = iter->getSource();
+ if(plr->IsInWorld())
+ UpdateActiveCells(plr->GetPositionX(), plr->GetPositionY(), t_diff);
+ }
+
+ // update cells around active objects
+ // clone the active object list, because update might remove from it
+ std::set<WorldObject *> activeObjects(i_activeObjects);
+ for(std::set<WorldObject *>::iterator iter = activeObjects.begin(); iter != activeObjects.end(); ++iter)
+ {
+ if((*iter)->IsInWorld())
+ UpdateActiveCells((*iter)->GetPositionX(), (*iter)->GetPositionY(), t_diff);
+ }
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
// This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
@@ -813,8 +825,13 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
#endif
AddCreatureToMoveList(creature,x,y,z,ang);
// in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList
- if(creature->isPossessedByPlayer())
- EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false);
+ if(creature->isActive())
+ {
+ if(creature->isPossessedByPlayer())
+ EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false);
+ else
+ EnsureGridLoadedForPlayer(new_cell, NULL, false);
+ }
}
else
{
@@ -1509,6 +1526,36 @@ bool Map::PlayersNearGrid(uint32 x, uint32 y) const
return false;
}
+bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
+{
+ CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
+ CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
+ cell_min << 2;
+ cell_min -= 2;
+ cell_max >> 2;
+ cell_max += 2;
+
+ for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
+ {
+ Player* plr = iter->getSource();
+
+ CellPair p = Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY());
+ if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
+ (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
+ return true;
+ }
+
+ for(std::set<WorldObject*>::const_iterator itr = i_activeObjects.begin(); itr != i_activeObjects.end(); ++itr)
+ {
+ CellPair p = Trinity::ComputeCellPair((*itr)->GetPositionX(), (*itr)->GetPositionY());
+ if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
+ (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
+ return true;
+ }
+
+ return false;
+}
+
template void Map::Add(Corpse *);
template void Map::Add(Creature *);
template void Map::Add(GameObject *);
diff --git a/src/game/Map.h b/src/game/Map.h
index 6e0e9cb37a9..cd476f5e3c6 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -242,6 +242,10 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
uint32 GetPlayersCountExceptGMs() const;
bool PlayersNearGrid(uint32 x,uint32 y) const;
+ bool ActiveObjectsNearGrid(uint32 x, uint32 y) const;
+
+ void AddActiveObject(WorldObject* obj) { i_activeObjects.insert(obj); }
+ void RemoveActiveObject(WorldObject* obj) { i_activeObjects.erase(obj); }
void SendToPlayers(WorldPacket const* data) const;
@@ -287,6 +291,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
inline void setNGrid(NGridType* grid, uint32 x, uint32 y);
+ void UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff);
protected:
typedef Trinity::ObjectLevelLockable<Map, ZThread::Mutex>::Lock Guard;
@@ -307,6 +312,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
time_t i_gridExpiry;
+ std::set<WorldObject *> i_activeObjects;
std::set<WorldObject *> i_objectsToRemove;
// Type specific code for add/remove to/from grid
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index ea59a448f7f..cc754f32bd3 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -990,36 +990,37 @@ WorldObject::WorldObject()
WorldObject::~WorldObject()
{
- if(m_isActive && IsInWorld())
- ObjectAccessor::Instance().RemoveActiveObject(this);
+ if(m_isActive && !isType(TYPEMASK_PLAYER) && IsInWorld())
+ GetMap()->RemoveActiveObject(this);
}
void WorldObject::setActive(bool isActive)
{
// if already in the same activity state as we try to set, do nothing
- if(isActive == m_isActive)
+ if(isActive == m_isActive || isType(TYPEMASK_PLAYER))
return;
+
m_isActive = isActive;
if(IsInWorld())
{
if(isActive)
- ObjectAccessor::Instance().AddActiveObject(this);
+ GetMap()->AddActiveObject(this);
else
- ObjectAccessor::Instance().RemoveActiveObject(this);
+ GetMap()->RemoveActiveObject(this);
}
}
void WorldObject::AddToWorld()
{
Object::AddToWorld();
- if(m_isActive)
- ObjectAccessor::Instance().AddActiveObject(this);
+ if(m_isActive && !isType(TYPEMASK_PLAYER))
+ GetMap()->AddActiveObject(this);
}
void WorldObject::RemoveFromWorld()
{
- if(m_isActive)
- ObjectAccessor::Instance().RemoveActiveObject(this);
+ if(m_isActive && !isType(TYPEMASK_PLAYER))
+ GetMap()->RemoveActiveObject(this);
Object::RemoveFromWorld();
}
diff --git a/src/game/Object.h b/src/game/Object.h
index 2d8f3a134e6..43ecca2afb0 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -455,7 +455,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime);
bool isActive() const { return m_isActive; }
- virtual void setActive(bool isActive);
+ void setActive(bool isActive);
protected:
explicit WorldObject();
std::string m_name;
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index 8d9f3f63fc2..75f0d697771 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -487,24 +487,10 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
}
void
-ObjectAccessor::AddActiveObject( WorldObject * obj )
-{
- i_activeobjects.insert(obj);
-}
-
-void
-ObjectAccessor::RemoveActiveObject( WorldObject * obj )
-{
- i_activeobjects.erase(obj);
-}
-
-void
ObjectAccessor::Update(uint32 diff)
{
-
- {
+/* {
//Player update now in MapManager -> UpdatePlayers
- /*
// player update might remove the player from grid, and that causes crashes. We HAVE to update players first, and then the active objects.
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
@@ -513,7 +499,7 @@ ObjectAccessor::Update(uint32 diff)
{
iter->second->Update(diff);
}
- }*/
+ }
// TODO: move this to Map::Update
// clone the active object list, because update might remove from it
@@ -574,7 +560,7 @@ ObjectAccessor::Update(uint32 diff)
}
}
}
- }
+ }*/
UpdateDataMapType update_players;
{
@@ -608,30 +594,6 @@ ObjectAccessor::UpdatePlayers(uint32 diff)
iter->second->Update(diff);
}
-bool
-ObjectAccessor::ActiveObjectsNearGrid(uint32 x, uint32 y, uint32 m_id, uint32 i_id) const
-{
- CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
- CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
- cell_min << 2;
- cell_min -= 2;
- cell_max >> 2;
- cell_max += 2;
-
- for(std::set<WorldObject*>::const_iterator itr = i_activeobjects.begin(); itr != i_activeobjects.end(); ++itr)
- {
- if( m_id != (*itr)->GetMapId() || i_id != (*itr)->GetInstanceId() )
- continue;
-
- CellPair p = Trinity::ComputeCellPair((*itr)->GetPositionX(), (*itr)->GetPositionY());
- if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
- (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
- return true;
- }
-
- return false;
-}
-
void
ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m)
{
diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
index 89ea6d1e43d..21ede723da5 100644
--- a/src/game/ObjectAccessor.h
+++ b/src/game/ObjectAccessor.h
@@ -194,16 +194,11 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
Corpse* ConvertCorpseForPlayer(uint64 player_guid);
- bool ActiveObjectsNearGrid(uint32 x,uint32 y,uint32 m_id,uint32 i_id) const;
-
static void UpdateObject(Object* obj, Player* exceptPlayer);
static void _buildUpdateObject(Object* obj, UpdateDataMapType &);
static void UpdateObjectVisibility(WorldObject* obj);
static void UpdateVisibilityForPlayer(Player* player);
-
- void AddActiveObject(WorldObject*);
- void RemoveActiveObject(WorldObject*);
private:
struct WorldObjectChangeAccumulator
{
@@ -228,7 +223,6 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
void _update(void);
std::set<Object *> i_objects;
- std::set<WorldObject *> i_activeobjects;
LockType i_playerGuard;
LockType i_updateGuard;
LockType i_corpseGuard;
diff --git a/src/game/Player.h b/src/game/Player.h
index 87f0ad11ae8..540d569ebbf 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -897,8 +897,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void AddToWorld();
void RemoveFromWorld();
- // always active
- void setActive(bool) {}
void SetViewport(uint64 guid, bool movable);
void Possess(Unit *target);