diff options
author | megamage <none@none> | 2009-08-29 23:20:16 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-08-29 23:20:16 -0500 |
commit | d802cd3811c77a1b0bef95a65fdfc4872ff557a8 (patch) | |
tree | 68be363ef1f3ce843a32254a9b8fd122b7803434 | |
parent | 6954eae60ac320639451bd83782f294da367b733 (diff) |
*More update about positions.
*Ulduar: do not allow demolisher to regenerate pyrite. Player must shoot down and grab the containers to refill pyrite.
--HG--
branch : trunk
33 files changed, 352 insertions, 391 deletions
diff --git a/sql/FULL/world_spell_full.sql b/sql/FULL/world_spell_full.sql index aa5bb7610a6..7e54af3df84 100644 --- a/sql/FULL/world_spell_full.sql +++ b/sql/FULL/world_spell_full.sql @@ -2193,12 +2193,13 @@ spell5 = VALUES(spell5), spell6 = VALUES(spell6), vehicleid = VALUES(vehicleid); -DELETE FROM `spell_script_target` WHERE `entry` IN (62427,62374,62399,62056,63985); +DELETE FROM `spell_script_target` WHERE `entry` IN (62427,62496,62374,62399,62056,63985); INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES (62427, 1, 33109), # Load into Catapult (62374, 1, 33060), # Pursued (62374, 1, 33109), (62399, 1, 33139), # Overload Circuit +(62496, 1, 33167), # Liquid Pyrite - Salvaged Demolisher Mechanic Seat (63985, 1, 32934), # Stone Grip (62056, 1, 32934); diff --git a/sql/updates/5475_world_scripts_ulduar.sql b/sql/updates/5475_world_scripts_ulduar.sql new file mode 100644 index 00000000000..8939ee109a7 --- /dev/null +++ b/sql/updates/5475_world_scripts_ulduar.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_target` WHERE `entry` IN (62496); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +(62496, 1, 33167); # Liquid Pyrite - Salvaged Demolisher Mechanic Seat diff --git a/src/bindings/scripts/scripts/eastern_kingdoms/hinterlands.cpp b/src/bindings/scripts/scripts/eastern_kingdoms/hinterlands.cpp index fbcbd2f6045..5542c06e2e4 100644 --- a/src/bindings/scripts/scripts/eastern_kingdoms/hinterlands.cpp +++ b/src/bindings/scripts/scripts/eastern_kingdoms/hinterlands.cpp @@ -81,19 +81,19 @@ struct MANGOS_DLL_DECL npc_00x09hlAI : public npc_escortAI case 27: for(uint8 i = 0; i < 3; ++i) { - float fX, fY, fZ; - m_creature->GetRandomPoint(147.927444f, -3851.513428f, 130.893f, 7.0f, fX, fY, fZ); - - m_creature->SummonCreature(NPC_MARAUDING_OWL, fX, fY, fZ, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 25000); + const Position src = {147.927444f, -3851.513428f, 130.893f, 0}; + Position pos; + me->GetRandomNearPosition(pos, 7.0f); + DoSummon(NPC_MARAUDING_OWL, pos, 25000, TEMPSUMMON_CORPSE_TIMED_DESPAWN); } break; case 44: for(uint8 i = 0; i < 3; ++i) { - float fX, fY, fZ; - m_creature->GetRandomPoint(-141.151581f, -4291.213867f, 120.130f, 7.0f, fX, fY, fZ); - - m_creature->SummonCreature(NPC_VILE_AMBUSHER, fX, fY, fZ, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 25000); + const Position src = {-141.151581f, -4291.213867f, 120.130f, 0}; + Position dst; + m_creature->GetRandomPoint(src, 7.0f, dst); + m_creature->SummonCreature(NPC_VILE_AMBUSHER, dst, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 25000); } break; } diff --git a/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp b/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp index 7bcf8fa44ba..d960cfb2222 100644 --- a/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp +++ b/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp @@ -339,23 +339,18 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI void SummonInfernal(const uint32 diff) { InfernalPoint *point = NULL; - float posX,posY,posZ; + Position pos; if ((m_creature->GetMapId() != 532) || positions.empty()) - { - m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 60, posX, posY, posZ); - } + me->GetRandomNearPosition(pos, 60); else { std::vector<InfernalPoint*>::iterator itr = positions.begin()+rand()%positions.size(); point = *itr; positions.erase(itr); - - posX = point->x; - posY = point->y; - posZ = INFERNAL_Z; + pos.Relocate(point->x, point->y, INFERNAL_Z); } - Creature *Infernal = m_creature->SummonCreature(NETHERSPITE_INFERNAL, posX, posY, posZ, 0, TEMPSUMMON_TIMED_DESPAWN, 180000); + Creature *Infernal = m_creature->SummonCreature(NETHERSPITE_INFERNAL, pos, TEMPSUMMON_TIMED_DESPAWN, 180000); if (Infernal) { diff --git a/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp b/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp index 01a12847bd9..2952d47b540 100644 --- a/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp +++ b/src/bindings/scripts/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp @@ -654,11 +654,9 @@ struct TRINITY_DLL_DECL mob_cycloneAI : public ScriptedAI if (MoveTimer < diff) { - float x,y,z; - m_creature->GetPosition(x,y,z); - float PosX, PosY, PosZ; - m_creature->GetRandomPoint(x,y,z,10, PosX, PosY, PosZ); - m_creature->GetMotionMaster()->MovePoint(0, PosX, PosY, PosZ); + Position pos; + m_creature->GetRandomNearPosition(pos, 10); + m_creature->GetMotionMaster()->MovePoint(0, pos); MoveTimer = 5000 + rand()%3000; }else MoveTimer -= diff; } diff --git a/src/bindings/scripts/scripts/eastern_kingdoms/stratholme/stratholme.cpp b/src/bindings/scripts/scripts/eastern_kingdoms/stratholme/stratholme.cpp index ea8fe41fef0..02c10b348f8 100644 --- a/src/bindings/scripts/scripts/eastern_kingdoms/stratholme/stratholme.cpp +++ b/src/bindings/scripts/scripts/eastern_kingdoms/stratholme/stratholme.cpp @@ -205,13 +205,10 @@ struct TRINITY_DLL_DECL mobs_spectral_ghostly_citizenAI : public ScriptedAI { for(uint32 i = 1; i <= 4; ++i) { - float x,y,z; - m_creature->GetRandomPoint(m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),20.0f,x,y,z); - //100%, 50%, 33%, 25% chance to spawn uint32 j = urand(1,i); if (j==1) - m_creature->SummonCreature(ENTRY_RESTLESS,x,y,z,0,TEMPSUMMON_CORPSE_DESPAWN,600000); + DoSummon(ENTRY_RESTLESS, me, 20.0f, 600000); } } } diff --git a/src/bindings/scripts/scripts/eastern_kingdoms/undercity.cpp b/src/bindings/scripts/scripts/eastern_kingdoms/undercity.cpp index 8b27dc1beeb..d3bcb63a139 100644 --- a/src/bindings/scripts/scripts/eastern_kingdoms/undercity.cpp +++ b/src/bindings/scripts/scripts/eastern_kingdoms/undercity.cpp @@ -63,16 +63,8 @@ struct TRINITY_DLL_DECL npc_lady_sylvanas_windrunnerAI : public ScriptedAI bool LamentEvent; uint64 targetGUID; - float myX; - float myY; - float myZ; - void Reset() { - myX = m_creature->GetPositionX(); - myY = m_creature->GetPositionY(); - myZ = m_creature->GetPositionZ(); - LamentEvent_Timer = 5000; LamentEvent = false; targetGUID = 0; @@ -86,8 +78,8 @@ struct TRINITY_DLL_DECL npc_lady_sylvanas_windrunnerAI : public ScriptedAI { if (Unit* target = Unit::GetUnit(*summoned,targetGUID)) { - target->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), myZ+15.0,0); - target->GetMap()->CreatureRelocation(m_creature, target->GetPositionX(), target->GetPositionY(), myZ+15.0, 0.0f); + target->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0,0); + target->GetMap()->CreatureRelocation(m_creature, target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0, 0.0f); summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false); } @@ -102,12 +94,7 @@ struct TRINITY_DLL_DECL npc_lady_sylvanas_windrunnerAI : public ScriptedAI { if (LamentEvent_Timer < diff) { - float raX = myX; - float raY = myY; - float raZ = myZ; - - m_creature->GetRandomPoint(myX, myY, myZ, 20.0, raX, raY, raZ); - m_creature->SummonCreature(ENTRY_HIGHBORNE_BUNNY, raX, raY, myZ, 0, TEMPSUMMON_TIMED_DESPAWN, 3000); + DoSummon(ENTRY_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN); LamentEvent_Timer = 2000; if (!m_creature->HasAura(SPELL_SYLVANAS_CAST)) diff --git a/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp b/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp index 8c82722ed5d..6984f287950 100644 --- a/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp +++ b/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp @@ -286,20 +286,15 @@ struct TRINITY_DLL_DECL npc_time_riftAI : public ScriptedAI return; } - float x,y,z; - m_creature->GetRandomPoint(m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ(),10.0f,x,y,z); + Position pos; + m_creature->GetRandomNearPosition(pos, 10.0f); //normalize Z-level if we can, if rift is not at ground level. - z = std::max(m_creature->GetMap()->GetHeight(x, y, MAX_HEIGHT), m_creature->GetMap()->GetWaterLevel(x, y)); + pos.m_positionZ = std::max(m_creature->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), m_creature->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); - Unit *Summon = m_creature->SummonCreature(creature_entry,x,y,z,m_creature->GetOrientation(), - TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); - - if (Summon) - { + if(Unit *Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) if (Unit *temp = Unit::GetUnit(*m_creature, pInstance ? pInstance->GetData64(DATA_MEDIVH) : 0)) Summon->AddThreat(temp,0.0f); - } } void DoSelectSummon() diff --git a/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp b/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp index f406bca7113..b6d08ee82d8 100644 --- a/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp +++ b/src/bindings/scripts/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp @@ -245,25 +245,23 @@ struct TRINITY_DLL_DECL instance_dark_portal : public ScriptedInstance return 0; } - Creature* SummonedPortalBoss(Creature* pSource) + Creature* SummonedPortalBoss(Creature* m_creature) { uint32 entry = RiftWaves[GetRiftWaveId()].PortalBoss; if (entry == RIFT_BOSS) entry = RandRiftBoss(); - float x,y,z; - pSource->GetRandomPoint(pSource->GetPositionX(),pSource->GetPositionY(),pSource->GetPositionZ(),10.0f,x,y,z); - //normalize Z-level if we can, if rift is not at ground level. - z = std::max(instance->GetHeight(x, y, MAX_HEIGHT), instance->GetWaterLevel(x, y)); - debug_log("TSCR: Instance Dark Portal: Summoning rift boss entry %u.",entry); - Creature* pSummoned = pSource->SummonCreature(entry,x,y,z,pSource->GetOrientation(), - TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,600000); + Position pos; + m_creature->GetRandomNearPosition(pos, 10.0f); + + //normalize Z-level if we can, if rift is not at ground level. + pos.m_positionZ = std::max(m_creature->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), m_creature->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); - if (pSummoned) - return pSummoned; + if(Creature *summon = m_creature->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) + return summon; debug_log("TSCR: Instance Dark Portal: what just happened there? No boss, no loot, no fun..."); return NULL; diff --git a/src/bindings/scripts/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp b/src/bindings/scripts/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp index 4819a74fc0c..f017c274eba 100644 --- a/src/bindings/scripts/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp +++ b/src/bindings/scripts/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp @@ -165,9 +165,9 @@ struct TRINITY_DLL_DECL mob_doomfire_targettingAI : public ScriptedAI } else { - float x,y,z = 0.0; - m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 40, x, y, z); - m_creature->GetMotionMaster()->MovePoint(0, x, y, z); + Position pos; + m_creature->GetRandomNearPosition(pos, 40); + m_creature->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ); } ChangeTargetTimer = 5000; diff --git a/src/bindings/scripts/scripts/northrend/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/northrend/naxxramas/boss_sapphiron.cpp index 9813fddcd6a..62b90bbb742 100644 --- a/src/bindings/scripts/scripts/northrend/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/northrend/naxxramas/boss_sapphiron.cpp @@ -255,9 +255,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public BossAI case EVENT_BLIZZARD: { //DoCastAOE(SPELL_SUMMON_BLIZZARD); - float x, y, z; - me->GetGroundPointAroundUnit(x, y, z, rand_norm()*20, rand_norm()*2*M_PI); - if (Creature *summon = me->SummonCreature(MOB_BLIZZARD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 25000+rand()%5000)) + if(Creature *summon = DoSummon(MOB_BLIZZARD, me, 25000+rand()%5000, TEMPSUMMON_TIMED_DESPAWN)) summon->GetMotionMaster()->MoveRandom(40); events.ScheduleEvent(EVENT_BLIZZARD, HEROIC(20000,7000), 0, PHASE_GROUND); break; diff --git a/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp index 98238022d36..9e46a377701 100644 --- a/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp @@ -295,12 +295,7 @@ struct TRINITY_DLL_DECL boss_flame_leviathan_safety_containerAI : public Passive void UpdateAI(const uint32 diff) { if(!me->GetVehicle() && me->isSummon() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) - { - //me->AddUnitMovementFlag(MOVEMENTFLAG_FALLING); - me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - me->SendMovementFlagUpdate(); - me->GetMotionMaster()->MovePoint(me->GetEntry(), me->GetPositionX(), me->GetPositionY(), 409.8f); - } + me->GetMotionMaster()->MoveFall(409.8f, me->GetEntry()); } }; diff --git a/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp b/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp index b17682a9104..9242f5184e5 100644 --- a/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp +++ b/src/bindings/scripts/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp @@ -44,7 +44,20 @@ struct TRINITY_DLL_DECL boss_kologarnAI : public BossAI void AttackStart(Unit *who) { - me->Attack(who, false); + me->Attack(who, true); + if(leftArm) + leftArm->Attack(who, true); + if(rightArm) + rightArm->Attack(who, true); + } + + void MeleeSwing(WeaponAttackType type) + { + me->AttackerStateUpdate(me->getVictim(), type); + if(leftArm) + leftArm->AttackerStateUpdate(me->getVictim(), type); + if(rightArm) + rightArm->AttackerStateUpdate(me->getVictim(), type); } void PassengerBoarded(Unit *who, int8 seatId, bool apply) @@ -66,10 +79,9 @@ struct TRINITY_DLL_DECL boss_kologarnAI : public BossAI //If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) { - Unit *attacker = me; - if(leftArm) attacker = leftArm; - if(rightArm && rand()%2) attacker = rightArm; - attacker->AttackerStateUpdate(me->getVictim()); + WeaponAttackType type = BASE_ATTACK; + if(leftArm && (!rightArm || rand()%2)) type = OFF_ATTACK; + MeleeSwing(type); me->resetAttackTimer(); } } diff --git a/src/bindings/scripts/scripts/outland/shadowmoon_valley.cpp b/src/bindings/scripts/scripts/outland/shadowmoon_valley.cpp index e7ee5a45569..9580752caca 100644 --- a/src/bindings/scripts/scripts/outland/shadowmoon_valley.cpp +++ b/src/bindings/scripts/scripts/outland/shadowmoon_valley.cpp @@ -274,19 +274,17 @@ struct TRINITY_DLL_DECL mob_enslaved_netherwing_drakeAI : public ScriptedAI m_creature->GetRandomPoint(x, y, z, 20, dx, dy, dz); dz += 20; // so it's in the air, not ground*/ - float dx, dy, dz; - - Unit* EscapeDummy = me->FindNearestCreature(CREATURE_ESCAPE_DUMMY, 30); - if (EscapeDummy) - EscapeDummy->GetPosition(dx, dy, dz); + Position pos; + if(Unit* EscapeDummy = me->FindNearestCreature(CREATURE_ESCAPE_DUMMY, 30)) + EscapeDummy->GetPosition(&pos); else { - m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 20, dx, dy, dz); - dz += 25; + m_creature->GetRandomNearPosition(pos, 20); + pos.m_positionZ += 25; } m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - m_creature->GetMotionMaster()->MovePoint(1, dx, dy, dz); + m_creature->GetMotionMaster()->MovePoint(1, pos); } } }else FlyTimer -= diff; @@ -962,10 +960,7 @@ struct TRINITY_DLL_DECL npc_earthmender_wildaAI : public npc_escortAI void DoSpawnAssassin() { //unknown where they actually appear - float fX, fY, fZ; - m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 15.0f, fX, fY, fZ); - - m_creature->SummonCreature(NPC_COILSKAR_ASSASSIN, fX, fY, fZ, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + DoSummon(NPC_COILSKAR_ASSASSIN, me, 15.0f, 5000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT); } void Aggro(Unit* pWho) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 40507387226..47515638490 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -556,7 +556,10 @@ void Creature::Update(uint32 diff) RegenerateHealth(); if(getPowerType() == POWER_ENERGY) - Regenerate(POWER_ENERGY); + { + if(!IsVehicle() || GetVehicleKit()->GetVehicleInfo()->m_powerType != POWER_PYRITE) + Regenerate(POWER_ENERGY); + } else RegenerateMana(); @@ -1834,11 +1837,7 @@ bool Creature::FallGround() if (fabs(ground_Z - z) < 0.1f) return false; - SetFlying(false); - RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - SendMovementFlagUpdate(); - //AddUnitMovementFlag(MOVEMENTFLAG_FALLING); - GetMotionMaster()->MovePoint(EVENT_FALL_GROUND, x, y, ground_Z); + GetMotionMaster()->MoveFall(ground_Z, EVENT_FALL_GROUND); Unit::setDeathState(DEAD_FALLING); return true; } diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index d143daa288c..569c0fad9da 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -332,18 +332,19 @@ inline Creature *CreatureAI::DoSummon(uint32 uiEntry, const Position &pos, uint3 return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime); } -inline Creature *CreatureAI::DoSummon(uint32 uiEntry, WorldObject* pGo, float fRadius, uint32 uiDespawntime, TempSummonType uiType) +inline Creature *CreatureAI::DoSummon(uint32 uiEntry, WorldObject* obj, float fRadius, uint32 uiDespawntime, TempSummonType uiType) { - float fX, fY, fZ; - pGo->GetGroundPointAroundUnit(fX, fY, fZ, fRadius * rand_norm(), rand_norm()*2*M_PI); - return me->SummonCreature(uiEntry, fX, fY, fZ, me->GetOrientation(), uiType, uiDespawntime); + Position pos; + obj->GetRandomNearPosition(pos, fRadius); + return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime); } inline Creature *CreatureAI::DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float _fZ, float fRadius, uint32 uiDespawntime, TempSummonType uiType) { - float fX, fY, fZ; - obj->GetGroundPointAroundUnit(fX, fY, fZ, fRadius * rand_norm(), rand_norm()*2*M_PI); - return me->SummonCreature(uiEntry, fX, fY, fZ + _fZ, me->GetOrientation(), uiType, uiDespawntime); + Position pos; + obj->GetRandomNearPosition(pos, fRadius); + pos.m_positionZ += _fZ; + return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime); } #endif diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index c0af3a9be00..7e459c61e8b 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1678,7 +1678,7 @@ struct VehicleEntry uint32 m_uiLocomotionType; // 34 float m_msslTrgtImpactTexRadius; // 35 uint32 m_uiSeatIndicatorType; // 36 - // 37, new in 3.1 + uint32 m_powerType; // 37, new in 3.1 // 38, new in 3.1 // 39, new in 3.1 }; diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index 290514872f9..7487ac116a2 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -86,7 +86,7 @@ const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char SpellCastTimefmt[]="nixx"; const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixx"; +const char SpellEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixx"; const std::string CustomSpellEntryfmt="pappppppppaaapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaa"; const std::string CustomSpellEntryIndex = "Id"; const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; @@ -104,7 +104,7 @@ const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii"; const char TaxiPathEntryfmt[]="niii"; const char TaxiPathNodeEntryfmt[]="diiifffiixx"; const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; -const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifixxx"; +const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx"; const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx"; const char WorldMapAreaEntryfmt[]="xinxffffix"; const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx"; diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 34b009bc7d4..5dd4059e21c 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -70,12 +70,10 @@ void DynamicObject::RemoveFromWorld() } } -bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, float x, float y, float z, int32 duration, float radius, bool active) +bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, const Position &pos, int32 duration, float radius, bool active) { SetMap(caster->GetMap()); - - Relocate(x, y, z, 0); - + Relocate(pos); if(!IsPositionValid()) { sLog.outError("DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effMask,GetPositionX(),GetPositionY()); @@ -90,9 +88,9 @@ bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 ); SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId ); SetFloatValue( DYNAMICOBJECT_RADIUS, radius); - SetFloatValue( DYNAMICOBJECT_POS_X, x ); - SetFloatValue( DYNAMICOBJECT_POS_Y, y ); - SetFloatValue( DYNAMICOBJECT_POS_Z, z ); + SetFloatValue( DYNAMICOBJECT_POS_X, pos.m_positionX ); + SetFloatValue( DYNAMICOBJECT_POS_Y, pos.m_positionY ); + SetFloatValue( DYNAMICOBJECT_POS_Z, pos.m_positionZ ); SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() ); // new 2.4.0 m_aliveDuration = duration; diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h index 94985f247d7..13747891964 100644 --- a/src/game/DynamicObject.h +++ b/src/game/DynamicObject.h @@ -35,7 +35,7 @@ class DynamicObject : public WorldObject void AddToWorld(); void RemoveFromWorld(); - bool Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, float x, float y, float z, int32 duration, float radius, bool active); + bool Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, const Position &pos, int32 duration, float radius, bool active); void Update(uint32 p_time); void Delete(); uint32 GetSpellId() const { return m_spellId; } diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index b1168cac78d..81d72f8db6f 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -344,7 +344,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee } void -MotionMaster::MoveCharge(float x, float y, float z, float speed) +MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id) { if(Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE) return; @@ -354,16 +354,24 @@ MotionMaster::MoveCharge(float x, float y, float z, float speed) if(i_owner->GetTypeId()==TYPEID_PLAYER) { DEBUG_LOG("Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z ); - Mutate(new PointMovementGenerator<Player>(0,x,y,z), MOTION_SLOT_CONTROLLED); + Mutate(new PointMovementGenerator<Player>(id,x,y,z), MOTION_SLOT_CONTROLLED); } else { DEBUG_LOG("Creature (Entry: %u GUID: %u) charge point (X: %f Y: %f Z: %f)", i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z ); - Mutate(new PointMovementGenerator<Creature>(0,x,y,z), MOTION_SLOT_CONTROLLED); + Mutate(new PointMovementGenerator<Creature>(id,x,y,z), MOTION_SLOT_CONTROLLED); } } +void MotionMaster::MoveFall(float z, uint32 id) +{ + i_owner->SetFlying(false); + i_owner->SendMovementFlagUpdate(); + //AddUnitMovementFlag(MOVEMENTFLAG_FALLING); + MoveCharge(i_owner->GetPositionX(), i_owner->GetPositionY(), z, SPEED_CHARGE, id); +} + void MotionMaster::MoveSeekAssistance(float x, float y, float z) { diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h index 197f0d07499..9494627f166 100644 --- a/src/game/MotionMaster.h +++ b/src/game/MotionMaster.h @@ -149,8 +149,11 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *> void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f); void MoveConfused(); void MoveFleeing(Unit* enemy, uint32 time = 0); + void MovePoint(uint32 id, const Position &pos) + { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ); } void MovePoint(uint32 id, float x,float y,float z); - void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE); + void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE); + void MoveFall(float z, uint32 id = 0); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(float x, float y, float z, float speedXY, float speedZ); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 7d365b35710..5206a5a4219 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1079,7 +1079,7 @@ bool Object::PrintIndexError(uint32 index, bool set) const return false; } -bool Position::IsInLine(const Unit * const target, float distance, float width) const +bool Position::HasInLine(const Unit * const target, float distance, float width) const { if(!HasInArc(M_PI, target) || !target->IsWithinDist3d(m_positionX, m_positionY, m_positionZ, distance)) return false; width += target->GetObjectSize(); @@ -1382,13 +1382,11 @@ bool WorldObject::IsInBetween(const WorldObject *obj1, const WorldObject *obj2, return abs(sin(angle)) * GetExactDist2d(obj1->GetPositionX(), obj1->GetPositionY()) < size; } -void WorldObject::GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z) const +void WorldObject::GetRandomPoint(const Position &pos, float distance, float &rand_x, float &rand_y, float &rand_z) const { - if(distance == 0) + if(!distance) { - rand_x = x; - rand_y = y; - rand_z = z; + pos.GetPosition(rand_x, rand_y, rand_z); return; } @@ -1396,9 +1394,9 @@ void WorldObject::GetRandomPoint( float x, float y, float z, float distance, flo float angle = rand_norm()*2*M_PI; float new_dist = rand_norm()*distance; - rand_x = x + new_dist * cos(angle); - rand_y = y + new_dist * sin(angle); - rand_z = z; + rand_x = pos.m_positionX + new_dist * cos(angle); + rand_y = pos.m_positionY + new_dist * sin(angle); + rand_z = pos.m_positionZ; Trinity::NormalizeMapCoord(rand_x); Trinity::NormalizeMapCoord(rand_y); @@ -2175,14 +2173,15 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, */ } -void WorldObject::GetGroundPoint(float &x, float &y, float &z, float dist, float angle) +void WorldObject::MovePosition(Position &pos, float dist, float angle) { - angle += GetOrientation(); - x += dist * cos(angle); - y += dist * sin(angle); - Trinity::NormalizeMapCoord(x); - Trinity::NormalizeMapCoord(y); - UpdateGroundPositionZ(x, y, z); + angle += m_orientation; + pos.m_positionX += dist * cos(angle); + pos.m_positionY += dist * sin(angle); + Trinity::NormalizeMapCoord(pos.m_positionX); + Trinity::NormalizeMapCoord(pos.m_positionY); + UpdateGroundPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ); + pos.m_orientation = m_orientation; } void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update) diff --git a/src/game/Object.h b/src/game/Object.h index af4b6eb5301..761495b7f48 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -417,22 +417,22 @@ struct TRINITY_DLL_SPEC Position bool IsInDist(const Position *pos, float dist) const { return GetExactDistSq(pos) < dist * dist; } bool HasInArc(float arcangle, const Position *pos) const; - bool IsInLine(const Unit *target, float distance, float width) const; + bool HasInLine(const Unit *target, float distance, float width) const; }; +#define MAPID_INVALID 0xFFFFFFFF + class WorldLocation : public Position { public: - explicit WorldLocation(uint32 _mapid = 0, float _x = 0, float _y = 0, float _z = 0, float _o = 0) + explicit WorldLocation(uint32 _mapid = MAPID_INVALID, float _x = 0, float _y = 0, float _z = 0, float _o = 0) : m_mapId(_mapid) { Relocate(_x, _y, _z, _o); } - WorldLocation(const WorldLocation &loc) - : m_mapId(loc.GetMapId()) { Relocate(&loc); } + WorldLocation(const WorldLocation &loc) { WorldRelocate(loc); } - //void GetPosition(const WorldLocation &loc) const - // { loc.mapid = GetMapId(); Position::GetPosition(loc.coord_x, loc.coord_y, loc.coord_z); loc.orientation = GetOrientation(); } + void WorldRelocate(const WorldLocation &loc) + { m_mapId = loc.GetMapId(); Relocate(loc); } uint32 GetMapId() const { return m_mapId; } - protected: uint32 m_mapId; }; @@ -452,12 +452,18 @@ class TRINITY_DLL_SPEC WorldObject : public Object, public WorldLocation // angle calculated from current orientation GetNearPoint(NULL,x,y,z,size,distance2d,GetOrientation() + angle); } - void GetGroundPoint(float &x, float &y, float &z, float dist, float angle); - void GetGroundPointAroundUnit(float &x, float &y, float &z, float dist, float angle) + void MovePosition(Position &pos, float dist, float angle); + void GetNearPosition(Position &pos, float dist, float angle) + { + GetPosition(&pos); + MovePosition(pos, dist, angle); + } + void GetRandomNearPosition(Position &pos, float radius) { - GetPosition(x, y, z); - GetGroundPoint(x, y, z, dist, angle); + GetPosition(&pos); + MovePosition(pos, radius * rand_norm(), rand_norm() * 2 * M_PI); } + void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const { // angle to face `obj` to `this` using distance includes size of `obj` @@ -470,7 +476,13 @@ class TRINITY_DLL_SPEC WorldObject : public Object, public WorldLocation } void UpdateGroundPositionZ(float x, float y, float &z) const; - void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const; + void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const; + void GetRandomPoint(const Position &srcPos, float distance, Position &pos) const + { + float x, y, z; + GetRandomPoint(srcPos, distance, x, y, z); + pos.Relocate(x, y, z, GetOrientation()); + } uint32 GetInstanceId() const { return m_InstanceId; } @@ -490,8 +502,10 @@ class TRINITY_DLL_SPEC WorldObject : public Object, public WorldLocation virtual const char* GetNameForLocaleIdx(int32 /*locale_idx*/) const { return GetName(); } - float GetDistance( const WorldObject* obj ) const + float GetDistance(const WorldObject *obj) const { return GetExactDist(obj) + GetObjectSize() + obj->GetObjectSize(); } + float GetDistance(const Position &pos) const + { return GetExactDist(&pos) + GetObjectSize(); } float GetDistance(float x, float y, float z) const { return GetExactDist(x, y, z) + GetObjectSize(); } float GetDistance2d(const WorldObject* obj) const @@ -506,8 +520,12 @@ class TRINITY_DLL_SPEC WorldObject : public Object, public WorldLocation } bool IsWithinDist3d(float x, float y, float z, float dist) const { return IsInDist(x, y, z, dist + GetObjectSize()); } + bool IsWithinDist3d(const Position *pos, float dist) const + { return IsInDist(pos, dist + GetObjectSize()); } bool IsWithinDist2d(float x, float y, float dist) const { return IsInDist2d(x, y, dist + GetObjectSize()); } + bool IsWithinDist2d(const Position *pos, float dist) const + { return IsInDist2d(pos, dist + GetObjectSize()); } bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const; bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const // use only if you will sure about placing both object at same map diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 9da36fc9215..53c9873be72 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -167,7 +167,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid else if(pet->GetOwnerGUID() == GetPlayer()->GetGUID()) { assert(pet->GetTypeId() == TYPEID_UNIT); - if(((Creature*)pet)->isPet()) + if(pet->isPet()) { if(((Pet*)pet)->getPetType() == HUNTER_PET) GetPlayer()->RemovePet((Pet*)pet, PET_SAVE_AS_DELETED); @@ -175,7 +175,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid //dismissing a summoned pet is like killing them (this prevents returning a soulshard...) pet->setDeathState(CORPSE); } - else if(((Creature*)pet)->HasUnitTypeMask(UNIT_MASK_MINION)) + else if(pet->HasUnitTypeMask(UNIT_MASK_MINION)) { ((Minion*)pet)->UnSummon(); } @@ -232,7 +232,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid SpellCastResult result = spell->CheckPetCast(unit_target); //auto turn to target unless possessed - if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed()) + if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed() && !pet->IsVehicle()) { if(unit_target) { @@ -267,7 +267,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid pet->SendPetAIReaction(guid1); } - if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed()) + if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed() && !pet->IsVehicle()) { // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != unit_target) @@ -284,7 +284,7 @@ void WorldSession::HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid } else { - if(pet->isPossessed()) + if(pet->isPossessed() || pet->IsVehicle()) Spell::SendCastResult(GetPlayer(),spellInfo,0,result); else pet->SendPetCastFail(spellid, result); diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp index a24178ccb99..035c046b26a 100644 --- a/src/game/PointMovementGenerator.cpp +++ b/src/game/PointMovementGenerator.cpp @@ -68,8 +68,7 @@ void PointMovementGenerator<T>:: Finalize(T &unit) { if(unit.hasUnitState(UNIT_STAT_CHARGING)) unit.clearUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING); - else if(arrived) - MovementInform(unit); + MovementInform(unit); } template<class T> diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 1037b65b624..8731fe1a399 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -2525,6 +2525,7 @@ enum EventId { EVENT_SPELLCLICK = 1001, EVENT_FALL_GROUND = 1002, + EVENT_CHARGE = 1003, }; enum ResponseCodes diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 848f7e6e02c..3eada04fe42 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -124,7 +124,7 @@ SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0) m_itemTargetGUID = 0; m_itemTargetEntry = 0; - m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0; + m_srcPos.Relocate(0,0,0,0); m_strTarget = ""; m_targetMask = 0; } @@ -145,48 +145,36 @@ void SpellCastTargets::setUnitTarget(Unit *target) void SpellCastTargets::setSrc(float x, float y, float z) { - m_srcX = x; - m_srcY = y; - m_srcZ = z; + m_srcPos.Relocate(x, y, z); m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; } -void SpellCastTargets::setSrc(WorldObject *target) +void SpellCastTargets::setSrc(Position *pos) { - if(!target) - return; - - target->GetPosition(m_srcX, m_srcY, m_srcZ); - m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; + if(pos) + { + m_srcPos.Relocate(pos); + m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; + } } -void SpellCastTargets::setDestination(float x, float y, float z, int32 mapId) +void SpellCastTargets::setDst(float x, float y, float z, uint32 mapId) { - m_destX = x; - m_destY = y; - m_destZ = z; + m_dstPos.Relocate(x, y, z); m_targetMask |= TARGET_FLAG_DEST_LOCATION; - if(mapId >= 0) - m_mapId = mapId; + if(mapId != MAPID_INVALID) + m_dstPos.m_mapId = mapId; } -void SpellCastTargets::setDestination(WorldObject *target) +void SpellCastTargets::setDst(Position *pos) { - if(!target) - return; - - target->GetPosition(m_destX, m_destY, m_destZ); - m_targetMask |= TARGET_FLAG_DEST_LOCATION; + if(pos) + { + m_dstPos.Relocate(pos); + m_targetMask |= TARGET_FLAG_DEST_LOCATION; + } } -/*void SpellCastTargets::setSource(float x, float y, float z) -{ - m_srcX = x; - m_srcY = y; - m_srcZ = z; - m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; -}*/ - void SpellCastTargets::setGOTarget(GameObject *target) { m_GOTarget = target; @@ -269,10 +257,12 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster ) if(data->rpos() + 4 + 4 + 4 > data->size()) return false; - *data >> m_srcX >> m_srcY >> m_srcZ; - if(!Trinity::IsValidMapCoord(m_srcX, m_srcY, m_srcZ)) + *data >> m_srcPos.m_positionX >> m_srcPos.m_positionY >> m_srcPos.m_positionZ; + if(!m_srcPos.IsPositionValid()) return false; } + else + m_srcPos.Relocate(caster); if( m_targetMask & TARGET_FLAG_DEST_LOCATION ) { @@ -282,8 +272,8 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster ) if(!data->readPackGUID(m_unitTargetGUID)) return false; - *data >> m_destX >> m_destY >> m_destZ; - if(!Trinity::IsValidMapCoord(m_destX, m_destY, m_destZ)) + *data >> m_dstPos.m_positionX >> m_dstPos.m_positionY >> m_dstPos.m_positionZ; + if(!m_dstPos.IsPositionValid()) return false; if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION ) @@ -291,11 +281,15 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster ) if(data->rpos() + 4 + 4 <= data->size()) { *data >> m_elevation >> m_speed; + // TODO: should also read + m_srcPos.m_orientation = caster->GetOrientation(); //*data >> uint16 >> uint8 >> uint32 >> uint32; //*data >> float >> float >> float >> float... } } } + else + m_dstPos.Relocate(caster); if( m_targetMask & TARGET_FLAG_STRING ) { @@ -346,7 +340,7 @@ void SpellCastTargets::write ( WorldPacket * data ) } if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION ) - *data << m_srcX << m_srcY << m_srcZ; + *data << m_srcPos.m_positionX << m_srcPos.m_positionY << m_srcPos.m_positionZ; if( m_targetMask & TARGET_FLAG_DEST_LOCATION ) { @@ -355,7 +349,7 @@ void SpellCastTargets::write ( WorldPacket * data ) else *data << uint8(0); - *data << m_destX << m_destY << m_destZ; + *data << m_dstPos.m_positionX << m_dstPos.m_positionY << m_dstPos.m_positionZ; } if( m_targetMask & TARGET_FLAG_STRING ) @@ -760,7 +754,7 @@ void Spell::SelectSpellTargets() } else if(m_spellInfo->speed > 0.0f) { - float dist = m_caster->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); + float dist = m_caster->GetDistance(m_targets.m_dstPos); m_delayMoment = (uint64) floor(dist / m_spellInfo->speed * 1000.0f); } } @@ -1683,20 +1677,16 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry) { - float x, y, z; + Position *pos; switch(type) { case PUSH_DST_CENTER: CheckDst(); - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; + pos = &m_targets.m_dstPos; break; case PUSH_SRC_CENTER: CheckSrc(); - x = m_targets.m_srcX; - y = m_targets.m_srcY; - z = m_targets.m_srcZ; + pos = &m_targets.m_srcPos; break; case PUSH_CHAIN: { @@ -1706,24 +1696,20 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNo sLog.outError( "SPELL: cannot find unit target for spell ID %u\n", m_spellInfo->Id ); return; } - x = target->GetPositionX(); - y = target->GetPositionY(); - z = target->GetPositionZ(); + pos = target; break; } default: - x = m_caster->GetPositionX(); - y = m_caster->GetPositionY(); - z = m_caster->GetPositionZ(); + pos = m_caster; break; } - Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry, x, y, z); + Trinity::SpellNotifierCreatureAndPlayer notifier(m_caster, TagUnitMap, radius, type, TargetType, pos, entry); if((m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY) || TargetType == SPELL_TARGETS_ENTRY && !entry) - m_caster->GetMap()->VisitWorld(x, y, radius, notifier); + m_caster->GetMap()->VisitWorld(pos->m_positionX, pos->m_positionY, radius, notifier); else - m_caster->GetMap()->VisitAll(x, y, radius, notifier); + m_caster->GetMap()->VisitAll(pos->m_positionX, pos->m_positionY, radius, notifier); if(m_customAttr & SPELL_ATTR_CU_EXCLUDE_SELF) TagUnitMap.remove(m_caster); @@ -1847,7 +1833,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) float dis = rand_norm() * (max_dis - min_dis) + min_dis; float x, y, z; m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis); - m_targets.setDestination(x, y, z); + m_targets.setDst(x, y, z); break; } case TARGET_UNIT_MASTER: @@ -1983,11 +1969,11 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) } else if(cur == TARGET_DST_CASTER) { - m_targets.setDestination(m_caster); + m_targets.setDst(m_caster); break; } - float x, y, z, angle, dist; + float angle, dist; float objSize = m_caster->GetObjectSize(); dist = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); @@ -2011,8 +1997,9 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) default: angle = rand_norm()*2*M_PI; break; } - m_caster->GetGroundPointAroundUnit(x, y, z, dist, angle); - m_targets.setDestination(x, y, z); + Position pos; + m_caster->GetNearPosition(pos, dist, angle); + m_targets.setDst(&pos); // also flag break; } @@ -2027,11 +2014,11 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if(cur == TARGET_DST_TARGET_ENEMY || cur == TARGET_DEST_TARGET_ANY) { - m_targets.setDestination(target); + m_targets.setDst(target); break; } - float x, y, z, angle, dist; + float angle, dist; float objSize = target->GetObjectSize(); dist = target->GetSpellRadiusForTarget(target, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); @@ -2053,8 +2040,9 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) default: angle = rand_norm()*2*M_PI; break; } - target->GetGroundPointAroundUnit(x, y, z, dist, angle); - m_targets.setDestination(x, y, z); + Position pos; + target->GetNearPosition(pos, dist, angle); + m_targets.setDst(&pos); break; } @@ -2088,16 +2076,13 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) default: angle = rand_norm()*2*M_PI; break; } - float dist, x, y, z; + float dist; dist = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); if (cur == TARGET_DEST_DEST_RANDOM) dist *= rand_norm(); - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; - m_caster->GetGroundPoint(x, y, z, dist, angle); - m_targets.setDestination(x, y, z); + // must has dst, no need to set flag + m_caster->MovePosition(m_targets.m_dstPos, dist, angle); break; } @@ -2112,9 +2097,9 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if(m_spellInfo->Effect[0] == SPELL_EFFECT_TELEPORT_UNITS || m_spellInfo->Effect[1] == SPELL_EFFECT_TELEPORT_UNITS || m_spellInfo->Effect[2] == SPELL_EFFECT_TELEPORT_UNITS) - m_targets.setDestination(st->target_X, st->target_Y, st->target_Z, (int32)st->target_mapId); + m_targets.setDst(st->target_X, st->target_Y, st->target_Z, (int32)st->target_mapId); else if(st->target_mapId == m_caster->GetMapId()) - m_targets.setDestination(st->target_X, st->target_Y, st->target_Z); + m_targets.setDst(st->target_X, st->target_Y, st->target_Z); } else { @@ -2122,12 +2107,12 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) Unit *target = NULL; if(uint64 guid = m_caster->GetUInt64Value(UNIT_FIELD_TARGET)) target = ObjectAccessor::GetUnit(*m_caster, guid); - m_targets.setDestination(target ? target : m_caster); + m_targets.setDst(target ? target : m_caster); } break; case TARGET_DST_HOME: if(m_caster->GetTypeId() == TYPEID_PLAYER) - m_targets.setDestination(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, ((Player*)m_caster)->m_homebindMapId); + m_targets.setDst(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, ((Player*)m_caster)->m_homebindMapId); break; case TARGET_DST_NEARBY_ENTRY: { @@ -2135,7 +2120,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if(modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this); if(WorldObject *target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY)) - m_targets.setDestination(target); + m_targets.setDst(target); break; } } @@ -2162,7 +2147,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if(m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets.HasDst()) m_targets = m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets; else if(Unit* target = m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets.getUnitTarget()) - m_targets.setDestination(target); + m_targets.setDst(target); else sLog.outError( "SPELL: cannot find channel spell destination for spell ID %u", m_spellInfo->Id ); break; @@ -2300,7 +2285,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) switch(result->GetTypeId()) { case TYPEID_UNIT: - m_targets.setDestination(result); + m_targets.setDst(result); } } break; @@ -2389,22 +2374,17 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if(cur == TARGET_OBJECT_AREA_SRC) { if(m_targets.HasSrc()) - { - x = m_targets.m_srcX; - y = m_targets.m_srcY; - z = m_targets.m_srcZ; - } + m_targets.m_srcPos.GetPosition(x, y, z); else break; } - else if(m_targets.HasDst()) + else { - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; + if(m_targets.HasDst()) + m_targets.m_dstPos.GetPosition(x, y, z); + else + break; } - else - break; Trinity::GameObjectInRangeCheck check(x, y, z, radius + 50); std::list<GameObject*> goList; @@ -3127,7 +3107,7 @@ void Spell::_handle_immediate_phase() if(EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_DEST) { if(!m_targets.HasDst()) // FIXME: this will ignore dest set in effect - m_targets.setDestination(m_caster); + m_targets.setDst(m_caster); HandleEffects(m_originalCaster, NULL, NULL, j); m_effectMask |= (1<<j); } @@ -4419,6 +4399,7 @@ SpellCastResult Spell::CheckCast(bool strict) if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster)) return SPELL_FAILED_CASTER_AURASTATE; + // Note: spell 62473 requres casterAuraSpell = triggering spell if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell)) @@ -4705,7 +4686,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY || m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY ) { - m_targets.setDestination(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ()); + m_targets.setDst(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ()); if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) AddUnitTarget(creatureScriptTarget, j); @@ -4720,7 +4701,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY || m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY ) { - m_targets.setDestination(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ()); + m_targets.setDst(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ()); if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) AddGOTarget(goScriptTarget, j); @@ -5465,11 +5446,11 @@ SpellCastResult Spell::CheckRange(bool strict) return SPELL_FAILED_UNIT_NOT_INFRONT; } - if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0) + if(m_targets.HasDst() && !m_targets.HasTraj()) { - if(!m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, max_range)) + if(!m_caster->IsWithinDist3d(&m_targets.m_dstPos, max_range)) return SPELL_FAILED_OUT_OF_RANGE; - if(min_range && m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, min_range)) + if(min_range && m_caster->IsWithinDist3d(&m_targets.m_dstPos, min_range)) return SPELL_FAILED_TOO_CLOSE; } @@ -6613,7 +6594,7 @@ void Spell::SelectTrajTargets() if(!dist2d) return; - float dz = m_targets.m_destZ - m_targets.m_srcZ; + float dz = m_targets.m_dstPos.m_positionZ - m_targets.m_srcPos.m_positionZ; UnitList unitList; SearchAreaTarget(unitList, dist2d, PUSH_IN_THIN_LINE, SPELL_TARGETS_ANY); @@ -6627,7 +6608,8 @@ void Spell::SelectTrajTargets() if(a > -0.0001f) a = 0; DEBUG_TRAJ(sLog.outError("Spell::SelectTrajTargets: a %f b %f", a, b);) - float bestDist; + float bestDist = GetSpellMaxRange(m_spellInfo, false); + UnitList::const_iterator itr = unitList.begin(); for(; itr != unitList.end(); ++itr) { @@ -6636,15 +6618,15 @@ void Spell::SelectTrajTargets() const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3) // TODO: all calculation should be based on src instead of m_caster - const float objDist2d = (*itr)->GetExactDist2d(m_targets.m_srcX, m_targets.m_srcY) * cos(m_caster->GetRelativeAngle(*itr)); - const float dz = (*itr)->GetPositionZ() - m_targets.m_srcZ; + const float objDist2d = m_targets.m_srcPos.GetExactDist2d(*itr) * cos(m_targets.m_srcPos.GetRelativeAngle(*itr)); + const float dz = (*itr)->GetPositionZ() - m_targets.m_srcPos.m_positionZ; DEBUG_TRAJ(sLog.outError("Spell::SelectTrajTargets: check %u, dist between %f %f, height between %f %f.", (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);) float dist = objDist2d - size; float height = dist * (a * dist + b); DEBUG_TRAJ(sLog.outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height);) - if(height < dz + size && height > dz - size) + if(dist < bestDist && height < dz + size && height > dz - size) { bestDist = dist > 0 ? dist : 0; break; @@ -6652,8 +6634,8 @@ void Spell::SelectTrajTargets() #define CHECK_DIST {\ DEBUG_TRAJ(sLog.outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height);)\ - if(dist < objDist2d + size && dist > objDist2d - size)\ - { bestDist = dist; break; }\ + if(dist > bestDist) continue;\ + if(dist < objDist2d + size && dist > objDist2d - size) { bestDist = dist; break; }\ } if(!a) @@ -6697,28 +6679,31 @@ void Spell::SelectTrajTargets() } } - if(itr != unitList.end()) + if(m_targets.m_srcPos.GetExactDist2d(&m_targets.m_dstPos) > bestDist) { - float x = m_targets.m_srcX + cos(m_caster->GetOrientation()) * bestDist; - float y = m_targets.m_srcY + sin(m_caster->GetOrientation()) * bestDist; - float z = m_targets.m_srcZ + bestDist * (a * bestDist + b); + float x = m_targets.m_srcPos.m_positionX + cos(m_caster->GetOrientation()) * bestDist; + float y = m_targets.m_srcPos.m_positionY + sin(m_caster->GetOrientation()) * bestDist; + float z = m_targets.m_srcPos.m_positionZ + bestDist * (a * bestDist + b); - float distSq = (*itr)->GetExactDistSq(x, y, z); - float sizeSq = (*itr)->GetObjectSize(); - sizeSq *= sizeSq; - DEBUG_TRAJ(sLog.outError("Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);) - if(distSq > sizeSq) + if(itr != unitList.end()) { - float factor = 1 - sqrt(sizeSq / distSq); - x += factor * ((*itr)->GetPositionX() - x); - y += factor * ((*itr)->GetPositionY() - y); - z += factor * ((*itr)->GetPositionZ() - z); - - distSq = (*itr)->GetExactDistSq(x, y, z); + float distSq = (*itr)->GetExactDistSq(x, y, z); + float sizeSq = (*itr)->GetObjectSize(); + sizeSq *= sizeSq; DEBUG_TRAJ(sLog.outError("Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);) + if(distSq > sizeSq) + { + float factor = 1 - sqrt(sizeSq / distSq); + x += factor * ((*itr)->GetPositionX() - x); + y += factor * ((*itr)->GetPositionY() - y); + z += factor * ((*itr)->GetPositionZ() - z); + + distSq = (*itr)->GetExactDistSq(x, y, z); + DEBUG_TRAJ(sLog.outError("Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);) + } } - m_targets.setDestination(x, y, z); + m_targets.setDst(x, y, z); } } diff --git a/src/game/Spell.h b/src/game/Spell.h index b6aab83bea8..997800d9989 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -131,13 +131,8 @@ class SpellCastTargets m_itemTargetEntry = target.m_itemTargetEntry; - m_srcX = target.m_srcX; - m_srcY = target.m_srcY; - m_srcZ = target.m_srcZ; - - m_destX = target.m_destX; - m_destY = target.m_destY; - m_destZ = target.m_destZ; + m_srcPos = target.m_srcPos; + m_dstPos.Relocate(target.m_dstPos); m_elevation = target.m_elevation; m_speed = target.m_speed; @@ -146,8 +141,6 @@ class SpellCastTargets m_targetMask = target.m_targetMask; - m_mapId = -1; - return *this; } @@ -155,9 +148,9 @@ class SpellCastTargets Unit *getUnitTarget() const { return m_unitTarget; } void setUnitTarget(Unit *target); void setSrc(float x, float y, float z); - void setSrc(WorldObject *target); - void setDestination(float x, float y, float z, int32 mapId = -1); - void setDestination(WorldObject *target); + void setSrc(Position *pos); + void setDst(float x, float y, float z, uint32 mapId = MAPID_INVALID); + void setDst(Position *pos); uint64 getGOTargetGUID() const { return m_GOTargetGUID; } GameObject *getGOTarget() const { return m_GOTarget; } @@ -183,22 +176,15 @@ class SpellCastTargets bool HasDst() const { return m_targetMask & TARGET_FLAG_DEST_LOCATION; } bool HasTraj() const { return m_speed != 0; } - float GetDist2d() const - { - float dx = m_destX - m_srcX; - float dy = m_destY - m_srcY; - return sqrt(dx*dx + dy*dy); - } - + float GetDist2d() const { return m_srcPos.GetExactDist2d(&m_dstPos); } float GetSpeedXY() const { return m_speed * cos(m_elevation); } float GetSpeedZ() const { return m_speed * sin(m_elevation); } void Update(Unit* caster); - float m_srcX, m_srcY, m_srcZ; - float m_destX, m_destY, m_destZ; + Position m_srcPos; + WorldLocation m_dstPos; float m_elevation, m_speed; - int32 m_mapId; std::string m_strTarget; uint32 m_targetMask; @@ -434,7 +420,7 @@ class Spell bool CheckTarget( Unit* target, uint32 eff ); bool CanAutoCast(Unit* target); void CheckSrc() { if(!m_targets.HasSrc()) m_targets.setSrc(m_caster); } - void CheckDst() { if(!m_targets.HasDst()) m_targets.setDestination(m_caster); } + void CheckDst() { if(!m_targets.HasDst()) m_targets.setDst(m_caster); } static void MANGOS_DLL_SPEC SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 cast_count, SpellCastResult result); void SendCastResult(SpellCastResult result); @@ -678,20 +664,18 @@ namespace Trinity struct TRINITY_DLL_DECL SpellNotifierCreatureAndPlayer { std::list<Unit*> *i_data; - Spell &i_spell; SpellNotifyPushType i_push_type; float i_radius; SpellTargets i_TargetType; - Unit* i_source; + const Unit * const i_source; uint32 i_entry; - float i_x, i_y, i_z; + const Position * const i_pos; - SpellNotifierCreatureAndPlayer(Spell &spell, std::list<Unit*> &data, float radius, SpellNotifyPushType type, - SpellTargets TargetType = SPELL_TARGETS_ENEMY, uint32 entry = 0, float x = 0, float y = 0, float z = 0) - : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius) - , i_TargetType(TargetType), i_entry(entry), i_x(x), i_y(y), i_z(z) + SpellNotifierCreatureAndPlayer(Unit *source, std::list<Unit*> &data, float radius, SpellNotifyPushType type, + SpellTargets TargetType = SPELL_TARGETS_ENEMY, const Position *pos = NULL, uint32 entry = 0) + : i_source(source), i_data(&data), i_radius(radius), i_push_type(type) + , i_TargetType(TargetType), i_pos(pos), i_entry(entry) { - i_source = spell.GetCaster(); assert(i_source); } @@ -701,14 +685,13 @@ namespace Trinity { Unit *target = (Unit*)itr->getSource(); - // mostly phase check - if(!itr->getSource()->IsInMap(i_source)) + if(!target->InSamePhase(i_source)) continue; switch (i_TargetType) { case SPELL_TARGETS_ENEMY: - if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem()) + if(target->isTotem()) continue; if(!target->isAttackableByAOE()) continue; @@ -724,7 +707,7 @@ namespace Trinity } break; case SPELL_TARGETS_ALLY: - if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem()) + if(target->isTotem()) continue; if(!target->isAttackableByAOE() || !i_source->IsFriendlyTo(target)) continue; @@ -744,7 +727,7 @@ namespace Trinity case PUSH_DST_CENTER: case PUSH_CHAIN: default: - if(target->IsWithinDist3d(i_x, i_y, i_z, i_radius)) + if(target->IsWithinDist3d(i_pos, i_radius)) i_data->push_back(target); break; case PUSH_IN_FRONT: @@ -756,11 +739,11 @@ namespace Trinity i_data->push_back(target); break; case PUSH_IN_LINE: - if(i_source->IsInLine(target, i_radius, i_source->GetObjectSize())) + if(i_source->HasInLine(target, i_radius, i_source->GetObjectSize())) i_data->push_back(target); break; - case PUSH_IN_THIN_LINE: - if(i_source->IsInLine(target, i_radius, 0)) + case PUSH_IN_THIN_LINE: // only traj + if(i_pos->HasInLine(target, i_radius, 0)) i_data->push_back(target); break; } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 5fa12a92eca..8629c544b28 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1247,7 +1247,7 @@ void Spell::EffectDummy(uint32 i) if(Unit *device = seat->GetPassenger(2)) if(!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) { - float dist = (*itr)->GetExactDistSq(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); + float dist = (*itr)->GetExactDistSq(&m_targets.m_dstPos); if(dist < minDist) { minDist = dist; @@ -1255,12 +1255,14 @@ void Spell::EffectDummy(uint32 i) } } } - if(target && target->GetBase()->IsWithinDist2d(m_targets.m_destX, m_targets.m_destY, GetSpellRadius(m_spellInfo, i, false) * 2)) // now we use *2 because the location of the seat is not correct + if(target && target->GetBase()->IsWithinDist2d(&m_targets.m_dstPos, GetSpellRadius(m_spellInfo, i, false) * 2)) // now we use *2 because the location of the seat is not correct passenger->EnterVehicle(target, 0); else { passenger->ExitVehicle(); - passenger->GetMotionMaster()->MoveJump(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, m_targets.GetSpeedXY(), m_targets.GetSpeedZ()); + float x, y, z; + m_targets.m_dstPos.GetPosition(x, y, z); + passenger->GetMotionMaster()->MoveJump(x, y, z, m_targets.GetSpeedXY(), m_targets.GetSpeedZ()); } } } @@ -1922,11 +1924,11 @@ void Spell::EffectDummy(uint32 i) if (m_targets.HasDst()) { - targets.setDestination(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); + targets.setDst(&m_targets.m_dstPos); } else { - targets.setDestination(m_caster); + targets.setDst(m_caster); // Corpse not found - take reagents ( only not triggered cast can take them) triggered = false; } @@ -1938,7 +1940,7 @@ void Spell::EffectDummy(uint32 i) else if (m_spellInfo->Id ==48289) { if (m_targets.HasDst()) - targets.setDestination(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); + targets.setDst(&m_targets.m_dstPos); spell_id = m_currentBasePoints[0]; } @@ -2268,7 +2270,9 @@ void Spell::EffectTriggerMissileSpell(uint32 effect_idx) && m_spellInfo->Category == spellInfo->Category) ((Player*)m_caster)->RemoveSpellCooldown(spellInfo->Id); - m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo->Id, true, m_CastItem, 0, m_originalCasterGUID); + float x, y, z; + m_targets.m_dstPos.GetPosition(x, y, z); + m_caster->CastSpell(x, y, z, spellInfo->Id, true, m_CastItem, 0, m_originalCasterGUID); } void Spell::EffectJump(uint32 i) @@ -2280,9 +2284,7 @@ void Spell::EffectJump(uint32 i) float x,y,z,o; if(m_targets.HasDst()) { - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; + m_targets.m_dstPos.GetPosition(x, y, z); if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_TARGET_BACK) { @@ -2342,11 +2344,10 @@ void Spell::EffectTeleportUnits(uint32 i) } // Init dest coordinates - int32 mapid = m_targets.m_mapId; - if(mapid < 0) mapid = (int32)unitTarget->GetMapId(); - float x = m_targets.m_destX; - float y = m_targets.m_destY; - float z = m_targets.m_destZ; + uint32 mapid = m_targets.m_dstPos.GetMapId(); + if(mapid == MAPID_INVALID) mapid = unitTarget->GetMapId(); + float x, y, z; + m_targets.m_dstPos.GetPosition(x, y, z); float orientation = m_targets.getUnitTarget() ? m_targets.getUnitTarget()->GetOrientation() : unitTarget->GetOrientation(); sLog.outDebug("Spell::EffectTeleportUnits - teleport unit to %u %f %f %f\n", mapid, x, y, z); @@ -2948,7 +2949,7 @@ void Spell::EffectPersistentAA(uint32 i) Unit *caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster; int32 duration = GetSpellDuration(m_spellInfo); DynamicObject* dynObj = new DynamicObject; - if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, 1<<i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius, false)) + if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, 1<<i, m_targets.m_dstPos, duration, radius, false)) { delete dynObj; return; @@ -3679,7 +3680,7 @@ void Spell::EffectDistract(uint32 /*i*/) if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING ) ) return; - float angle = unitTarget->GetAngle(m_targets.m_destX, m_targets.m_destY); + float angle = unitTarget->GetAngle(&m_targets.m_dstPos); if ( unitTarget->GetTypeId() == TYPEID_PLAYER ) { @@ -3733,7 +3734,7 @@ void Spell::EffectAddFarsight(uint32 i) float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); int32 duration = GetSpellDuration(m_spellInfo); DynamicObject* dynObj = new DynamicObject; - if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, 0, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius, true)) + if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, 0, m_targets.m_dstPos, duration, radius, true)) { delete dynObj; return; @@ -4635,11 +4636,7 @@ void Spell::EffectSummonObjectWild(uint32 i) float x, y, z; if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; - } + m_targets.m_dstPos.GetPosition(x, y, z); else m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); @@ -5163,7 +5160,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) float radius = GetSpellRadius(m_spellInfo, effIndex, true); for(uint32 i = 0; i < 15; ++i) { - m_caster->GetRandomPoint(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, radius, x, y, z); + m_caster->GetRandomPoint(m_targets.m_dstPos, radius, x, y, z); m_caster->CastSpell(x, y, z, 54522, true); } break; @@ -5306,7 +5303,8 @@ void Spell::EffectScriptEffect(uint32 effIndex) { if(Creature *oldContainer = dynamic_cast<Creature*>(seat->GetPassenger(1))) oldContainer->DisappearAndDie(); - unitTarget->CastSpell(seat->GetBase(), 62473, true); + // TODO: a hack, range = 11, should after some time cast, otherwise too far + unitTarget->CastSpell(seat->GetBase(), 62496, true); unitTarget->EnterVehicle(seat, 1); } } @@ -6093,12 +6091,8 @@ void Spell::EffectSummonObject(uint32 i) float x, y, z; // If dest location if present - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; - } + if (m_targets.HasDst()) + m_targets.m_dstPos.GetPosition(x, y, z); // Summon in random point all other units if location present else m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); @@ -6373,11 +6367,7 @@ void Spell::EffectCharge2(uint32 /*i*/) { float x, y, z; if(m_targets.HasDst()) - { - x = m_targets.m_destX; - y = m_targets.m_destY; - z = m_targets.m_destZ; - } + m_targets.m_dstPos.GetPosition(x, y, z); else if(Unit *target = m_targets.getUnitTarget()) { target->GetContactPoint(m_caster, x, y, z); @@ -6423,16 +6413,10 @@ void Spell::EffectKnockBack(uint32 i) return; float x, y; - if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - x = m_targets.m_destX; - y = m_targets.m_destY; - } + if(m_targets.HasDst()) + m_targets.m_dstPos.GetPosition(x, y); else - { - x = m_caster->GetPositionX(); - y = m_caster->GetPositionY(); - } + m_caster->GetPosition(x, y); unitTarget->KnockbackFrom(x, y, speedxy, speedz); } @@ -6615,12 +6599,8 @@ void Spell::EffectTransmitted(uint32 effIndex) float fx, fy, fz; - if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - fx = m_targets.m_destX; - fy = m_targets.m_destY; - fz = m_targets.m_destZ; - } + if(m_targets.HasDst()) + m_targets.m_dstPos.GetPosition(fx, fy, fz); //FIXME: this can be better check for most objects but still hack else if(m_spellInfo->EffectRadiusIndex[effIndex] && m_spellInfo->speed==0) { @@ -7014,11 +6994,13 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const * void Spell::GetSummonPosition(uint32 i, Position &pos, float radius, uint32 count) { + pos.SetOrientation(m_caster->GetOrientation()); + if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) { // Summon 1 unit in dest location if (count == 0) - pos.Relocate(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, m_caster->GetOrientation()); + pos.Relocate(m_targets.m_dstPos); // Summon in random point all other units if location present else { @@ -7027,22 +7009,14 @@ void Spell::GetSummonPosition(uint32 i, Position &pos, float radius, uint32 coun { case TARGET_MINION: case TARGET_DEST_CASTER_RANDOM: - { - float x, y, z; - m_caster->GetGroundPointAroundUnit(x, y, z, radius * rand_norm(), rand_norm()*2*M_PI); - pos.Relocate(x, y, z, m_caster->GetOrientation()); + m_caster->GetNearPosition(pos, radius * rand_norm(), rand_norm()*2*M_PI); break; - } case TARGET_DEST_DEST_RANDOM: case TARGET_DEST_TARGET_RANDOM: - { - float x, y, z; - m_caster->GetRandomPoint(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,radius,x,y,z); - pos.Relocate(x, y, z, m_caster->GetOrientation()); + m_caster->GetRandomPoint(m_targets.m_dstPos, radius, pos); break; - } default: - pos.Relocate(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, m_caster->GetOrientation()); + pos.Relocate(m_targets.m_dstPos); break; } } @@ -7052,7 +7026,7 @@ void Spell::GetSummonPosition(uint32 i, Position &pos, float radius, uint32 coun { float x, y, z; m_caster->GetClosePoint(x,y,z,3.0f); - pos.Relocate(x, y, z, m_caster->GetOrientation()); + pos.Relocate(x, y, z); } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 34661a91c4f..6600879d0eb 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -936,7 +936,7 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I sLog.outError("CastSpell: spell id %i by caster: %s %u) does not have destination", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } - targets.setDestination(Victim); + targets.setDst(Victim); } if (castItem) @@ -1003,7 +1003,7 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* sLog.outError("CastSpell: spell id %i by caster: %s %u) does not have destination", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } - targets.setDestination(Victim); + targets.setDst(Victim); } if(!originalCaster && triggeredByAura) @@ -1043,7 +1043,7 @@ void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Spell *spell = new Spell(this, spellInfo, triggered, originalCaster ); SpellCastTargets targets; - targets.setDestination(x, y, z); + targets.setDst(x, y, z); if(OriginalVictim) targets.setUnitTarget(OriginalVictim); spell->m_CastItem = castItem; diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index 510214c5a23..853440169eb 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -52,23 +52,36 @@ void Vehicle::Install() { if(Creature *cre = dynamic_cast<Creature*>(me)) { - for(uint32 i = 0; i < MAX_SPELL_VEHICLE; ++i) + if(m_vehicleInfo->m_powerType == POWER_STEAM) { - if(!cre->m_spells[i]) - continue; - - SpellEntry const *spellInfo = sSpellStore.LookupEntry(cre->m_spells[i]); - if(!spellInfo) - continue; - - if(spellInfo->powerType == POWER_MANA) - break; - - if(spellInfo->powerType == POWER_ENERGY) + me->setPowerType(POWER_ENERGY); + me->SetMaxPower(POWER_ENERGY, 100); + } + else if(m_vehicleInfo->m_powerType == POWER_PYRITE) + { + me->setPowerType(POWER_ENERGY); + me->SetMaxPower(POWER_ENERGY, 50); + } + else + { + for(uint32 i = 0; i < MAX_SPELL_VEHICLE; ++i) { - me->setPowerType(POWER_ENERGY); - me->SetMaxPower(POWER_ENERGY, 100); - break; + if(!cre->m_spells[i]) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(cre->m_spells[i]); + if(!spellInfo) + continue; + + if(spellInfo->powerType == POWER_MANA) + break; + + if(spellInfo->powerType == POWER_ENERGY) + { + me->setPowerType(POWER_ENERGY); + me->SetMaxPower(POWER_ENERGY, 100); + break; + } } } } diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h index 3c1bd3508f5..620f194a15b 100644 --- a/src/game/Vehicle.h +++ b/src/game/Vehicle.h @@ -25,6 +25,12 @@ struct VehicleEntry; struct VehicleSeatEntry; class Unit; +enum PowerType +{ + POWER_STEAM = 61, + POWER_PYRITE = 41, +}; + struct VehicleSeat { explicit VehicleSeat(VehicleSeatEntry const *_seatInfo) : seatInfo(_seatInfo), passenger(NULL) {} |