Core/Movement: Implement spline movement subsystem.
Spline movement controls movements of server-side controlled units (monster movement, taxi movement, etc). Proper implementation of effects such as charge, jump, cyclic movement will rely on it. However, need improve our states system before. Technical changes: * Added linear, catmullrom and bezier3 splines which based on client's algorthims. They can be reused for proper transport position interpolation. * Precission increased. There are no more position desync issues since client's position calculation formulas used. * Now possible to move by paths with multiple points, send whole path to client. -- Original author of research and implementation: SilverIce. Massive kudos. Original port for Trinity (ref #4629) Chaplain and Venugh With the following incremental fixes during my review: - Restore flightmaster end grid pre-loading - Fix uninitialized Creature::m_path_id - Add missing trinity_string entries for .movegens command - Fix a bug in WaypointMovementGenerator that would trigger unexpected pausing at waypoints for various amounts of time Known issues: - Errors like WaypointMovementGenerator::LoadPath creature XXX (Entry: YYYYY GUID: ZZZZZZ) doesn't have waypoint path id: 0. This is caused by bad DB data. This commit didn't "break" it. Do not forget to re-run CMake before compiling.
This commit is contained in:
+1
-5
@@ -592,11 +592,8 @@ public:
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
//At hit the ground
|
||||
me->GetPosition(x, y, z);
|
||||
z = me->GetMap()->GetHeight(x, y, z, true, 50);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
|
||||
me->GetMotionMaster()->MoveFall(z, 0);
|
||||
//me->FallGround(); //need correct vmap use (i believe it isn't working properly right now)
|
||||
me->GetMotionMaster()->MoveFall();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,7 +607,6 @@ public:
|
||||
case 0:
|
||||
me->RemoveAurasDueToSpell(SPELL_FROST_SPHERE);
|
||||
me->SetDisplayId(11686);
|
||||
me->Relocate(x, y, z, me->GetOrientation());
|
||||
DoCast(SPELL_PERMAFROST_VISUAL);
|
||||
DoCast(SPELL_PERMAFROST);
|
||||
me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
|
||||
|
||||
@@ -201,7 +201,7 @@ class mob_corrupted_soul_fragment : public CreatureScript
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != TARGETED_MOTION_TYPE)
|
||||
if (type != CHASE_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (instance)
|
||||
|
||||
@@ -1159,7 +1159,7 @@ class npc_ball_of_flame : public CreatureScript
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == TARGETED_MOTION_TYPE && id == GUID_LOPART(_chaseGUID) && _chaseGUID)
|
||||
if (type == CHASE_MOTION_TYPE && id == GUID_LOPART(_chaseGUID) && _chaseGUID)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_BALL_OF_FLAMES_PERIODIC);
|
||||
DoCast(me, SPELL_FLAMES);
|
||||
|
||||
@@ -608,7 +608,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
|
||||
me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f);
|
||||
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
|
||||
for (std::list<Creature*>::iterator itr = _guardList.begin(); itr != _guardList.end(); ++itr)
|
||||
(*itr)->AI()->DoAction(ACTION_DESPAWN);
|
||||
break;
|
||||
@@ -815,7 +815,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
|
||||
me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f);
|
||||
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
|
||||
for (std::list<Creature*>::iterator itr = _guardList.begin(); itr != _guardList.end(); ++itr)
|
||||
(*itr)->AI()->DoAction(ACTION_DESPAWN);
|
||||
break;
|
||||
|
||||
@@ -508,7 +508,7 @@ class boss_the_lich_king : public CreatureScript
|
||||
if (fabs(ground_Z - z) < 0.1f)
|
||||
return;
|
||||
|
||||
me->GetMotionMaster()->MoveFall(ground_Z);
|
||||
me->GetMotionMaster()->MoveFall();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* target)
|
||||
@@ -801,7 +801,7 @@ class boss_the_lich_king : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_INTRO_TALK_1, 9000, 0, PHASE_INTRO);
|
||||
break;
|
||||
case POINT_CENTER_1:
|
||||
me->SetFacing(0.0f);
|
||||
me->SetFacingTo(0.0f);
|
||||
Talk(SAY_LK_REMORSELESS_WINTER);
|
||||
SendMusicToPlayers(MUSIC_SPECIAL);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
@@ -818,7 +818,7 @@ class boss_the_lich_king : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_SOUL_REAPER, 94000, 0, PHASE_TWO);
|
||||
break;
|
||||
case POINT_CENTER_2:
|
||||
me->SetFacing(0.0f);
|
||||
me->SetFacingTo(0.0f);
|
||||
Talk(SAY_LK_REMORSELESS_WINTER);
|
||||
SendMusicToPlayers(MUSIC_SPECIAL);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
@@ -1047,14 +1047,14 @@ class boss_the_lich_king : public CreatureScript
|
||||
break;
|
||||
case EVENT_OUTRO_TALK_3:
|
||||
if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
|
||||
me->SetFacing(0.0f, tirion);
|
||||
me->SetFacingToObject(tirion);
|
||||
Talk(SAY_LK_OUTRO_3);
|
||||
break;
|
||||
case EVENT_OUTRO_MOVE_CENTER:
|
||||
me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_1, CenterPosition);
|
||||
break;
|
||||
case EVENT_OUTRO_TALK_4:
|
||||
me->SetFacing(0.01745329f);
|
||||
me->SetFacingTo(0.01745329f);
|
||||
Talk(SAY_LK_OUTRO_4);
|
||||
break;
|
||||
case EVENT_OUTRO_RAISE_DEAD:
|
||||
@@ -1070,7 +1070,7 @@ class boss_the_lich_king : public CreatureScript
|
||||
case EVENT_OUTRO_TALK_6:
|
||||
Talk(SAY_LK_OUTRO_6);
|
||||
if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
|
||||
tirion->SetFacing(0.0f, me);
|
||||
tirion->SetFacingToObject(me);
|
||||
me->ClearUnitState(UNIT_STAT_CASTING);
|
||||
DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE_3);
|
||||
SetEquipmentSlots(false, EQUIP_UNEQUIP);
|
||||
@@ -1222,7 +1222,7 @@ class npc_tirion_fordring_tft : public CreatureScript
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_ICE_LOCK)
|
||||
me->SetFacing(3.085098f);
|
||||
me->SetFacingTo(3.085098f);
|
||||
else if (spell->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK)
|
||||
SetEquipmentSlots(true); // remove glow on ashbringer
|
||||
}
|
||||
@@ -1285,7 +1285,7 @@ class npc_tirion_fordring_tft : public CreatureScript
|
||||
SetEquipmentSlots(false, EQUIP_ASHBRINGER_GLOWING);
|
||||
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
|
||||
{
|
||||
me->SetFacing(0.0f, lichKing);
|
||||
me->SetFacingToObject(lichKing);
|
||||
lichKing->AI()->DoAction(ACTION_PLAY_MUSIC);
|
||||
}
|
||||
break;
|
||||
@@ -1621,7 +1621,7 @@ class npc_strangulate_vehicle : public CreatureScript
|
||||
|
||||
void IsSummonedBy(Unit* summoner)
|
||||
{
|
||||
me->SetFacing(0.0f, summoner);
|
||||
me->SetFacingToObject(summoner);
|
||||
DoCast(summoner, SPELL_HARVEST_SOUL_VEHICLE);
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_MOVE_TO_LICH_KING, 2000);
|
||||
@@ -1789,7 +1789,7 @@ class npc_terenas_menethil : public CreatureScript
|
||||
_events.Reset();
|
||||
_events.SetPhase(PHASE_OUTRO);
|
||||
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
|
||||
me->SetFacing(0.0f, lichKing);
|
||||
me->SetFacingToObject(lichKing);
|
||||
|
||||
_events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_1, 2000, 0, PHASE_OUTRO);
|
||||
_events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_2, 14000, 0, PHASE_OUTRO);
|
||||
|
||||
@@ -1264,7 +1264,7 @@ struct npc_argent_captainAI : public ScriptedAI
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
// not yet following
|
||||
if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != TARGETED_MOTION_TYPE || IsUndead)
|
||||
if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != CHASE_MOTION_TYPE || IsUndead)
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
return;
|
||||
|
||||
@@ -838,7 +838,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
|
||||
me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ public:
|
||||
{
|
||||
if (m_uiPause_Timer <= uiDiff)
|
||||
{
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
|
||||
if (me->getVictim())
|
||||
me->GetMotionMaster()->MoveChase(me->getVictim());
|
||||
|
||||
@@ -421,7 +421,7 @@ public:
|
||||
// me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); //Set in DB
|
||||
if (me->IsNonMeleeSpellCasted(false))
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
m_bIsFrozen = true;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
bIsSlam = false;
|
||||
|
||||
//and correct movement, if not already
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
|
||||
{
|
||||
if (me->getVictim())
|
||||
me->GetMotionMaster()->MoveChase(me->getVictim());
|
||||
|
||||
@@ -634,7 +634,7 @@ class boss_stormcaller_brundir : public CreatureScript
|
||||
|
||||
// Prevent to have Brundir somewhere in the air when he die in Air phase
|
||||
if (me->GetPositionZ() > FLOOR_Z)
|
||||
me->GetMotionMaster()->MoveFall(FLOOR_Z);
|
||||
me->GetMotionMaster()->MoveFall();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*who*/)
|
||||
|
||||
@@ -288,7 +288,7 @@ public:
|
||||
me->Dismount();
|
||||
if (Creature* pGrauf = me->SummonCreature(CREATURE_GRAUF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3*IN_MILLISECONDS))
|
||||
{
|
||||
pGrauf->GetMotionMaster()->MoveFall(0);
|
||||
pGrauf->GetMotionMaster()->MoveFall();
|
||||
pGrauf->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
|
||||
}
|
||||
me->GetMotionMaster()->MoveJump(Location[4].GetPositionX(), Location[4].GetPositionY(), Location[4].GetPositionZ(), 5.0f, 10.0f);
|
||||
|
||||
@@ -249,22 +249,16 @@ public:
|
||||
if (Phase == SACRIFICING)
|
||||
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
|
||||
|
||||
me->GetPosition(x, y, z);
|
||||
z = me->GetMap()->GetHeight(x, y, z, true, 50);
|
||||
damage = 0;
|
||||
Phase = SVALADEAD;
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->RemoveAllAuras();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetHealth(1);
|
||||
|
||||
if (me->GetPositionZ() > z)
|
||||
{
|
||||
damage = 0;
|
||||
Phase = SVALADEAD;
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->RemoveAllAuras();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetHealth(1);
|
||||
|
||||
SetCombatMovement(false);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
|
||||
me->GetMotionMaster()->MoveFall(z, 1);
|
||||
}
|
||||
SetCombatMovement(false);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
|
||||
me->GetMotionMaster()->MoveFall();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,10 +268,7 @@ public:
|
||||
return;
|
||||
|
||||
if (pointId == 1)
|
||||
{
|
||||
me->Relocate(x, y, z, me->GetOrientation());
|
||||
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
|
||||
Reference in New Issue
Block a user