Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Моды (http://mangos.ytdb.ru/forumdisplay.php?f=8)
-   -   [mod/dev] EffectJump (http://mangos.ytdb.ru/showthread.php?t=1442)

alien 11.06.2010 15:24

[mod/dev] EffectJump
 
Код:

diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index c43ce0f..96baee6 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -305,6 +305,27 @@ MotionMaster::MovePoint(uint32 id, float x, float y, float z)
    else
        Mutate(new PointMovementGenerator<Creature>(id,x,y,z));
 }
+void
+MotionMaster::MoveJump(float x, float y, float z, float speedZ)
+{
+    uint32 moveFlag = SPLINEFLAG_TRAJECTORY | SPLINEFLAG_WALKMODE;
+    uint32 time = 521;
+
+    i_owner->addUnitState(UNIT_STAT_FLEEING_MOVE | UNIT_STAT_JUMPING);
+    if (i_owner->GetTypeId() == TYPEID_PLAYER)
+    {
+        DEBUG_LOG("Player (GUID: %u) jump to point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z);
+        Mutate(new PointMovementGenerator<Player>(0,x,y,z));
+    }
+    else
+    {
+        DEBUG_LOG("Creature (Entry: %u GUID: %u) jump to point (X: %f Y: %f Z: %f)",
+            i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z);
+        Mutate(new PointMovementGenerator<Creature>(0,x,y,z));
+    }
+
+    i_owner->SendMonsterMove(x, y, z,SPLINETYPE_NORMAL, (SplineFlags)moveFlag, time,NULL, speedZ);
+}
 
 void
 MotionMaster::MoveSeekAssistance(float x, float y, float z)
diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h
index 139387a..097e4f8 100644
--- a/src/game/MotionMaster.h
+++ b/src/game/MotionMaster.h
@@ -115,6 +115,8 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
        void UpdateFinalDistanceToTarget(float fDistance);
 
        bool GetDestination(float &x, float &y, float &z);
+
+                void MoveJump(float x, float y, float z, float speedZ);
    private:
        void Mutate(MovementGenerator *m);                  // use Move* functions instead
 
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 109e9b3..b491d15 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -2772,7 +2789,15 @@ void Spell::EffectJump(SpellEffectIndex eff_idx)
        return;
    }
 
-    m_caster->NearTeleportTo(x, y, z, o, true);
+  // m_caster->NearTeleportTo(x, y, z, o, true);
+            float speedZ;
+    if (m_spellInfo->EffectMiscValue[eff_idx])
+        speedZ = float(m_spellInfo->EffectMiscValue[eff_idx])/7.8f;
+    else if (m_spellInfo->EffectMiscValueB[eff_idx])
+        speedZ = float(m_spellInfo->EffectMiscValueB[eff_idx])/7.8f;
+    else
+        speedZ = 10.0f;
+    m_caster->GetMotionMaster()->MoveJump(x, y, z, speedZ);
 }
 
 void Spell::EffectTeleportUnits(SpellEffectIndex eff_idx)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e35ab4f..1c1e59a 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -387,8 +387,16 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineTy
    // enable me if things goes wrong or looks ugly, it is however an old hack
    // if(flags & SPLINEFLAG_WALKMODE)
        // moveTime *= 1.05f;
-
-    data << uint32(moveTime);                              // Time in between points
+               
+            if (flags & SPLINEFLAG_TRAJECTORY)
+    {
+        data << uint32(moveTime); 
+        data << float(va_arg(vargs,double));
+        data << uint32(0); // walk time after jump
+    }
+    else
+        data << uint32(moveTime);                              // Time in between points
+               
    data << uint32(1);                                      // 1 single waypoint
    data << NewPosX << NewPosY << NewPosZ;                  // the single waypoint Point B
 
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 9f5440f..fb5e033 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -435,7 +435,7 @@ enum UnitState
    UNIT_STAT_FOLLOW_MOVE    = 0x00008000,
    UNIT_STAT_FLEEING        = 0x00010000,                    // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
    UNIT_STAT_FLEEING_MOVE    = 0x00020000,
-
+        UNIT_STAT_JUMPING                  = 0x00040000,
    // masks (only for check)
 
    // can't move currently

Собственно выдрано из Тринити и переработано.
Но остались некоторые вопросы.
1) как высчитать uint32 time = 521;
В тринити делают так uint32 time = speedZ * 100;
Но это неправильно.(так как при их расчетах получается число 1500 а должно 521, это напримере Десгрипа http://ru.wowhead.com/spell=49575).
2)И значение speedZ у них неверное. Должно быть в раене 19.2
При поможи speedZ = float(m_spellInfo->EffectMiscValueB[eff_idx])/7.8f;
получилось что-то близкое к 19.2, но тоже не уверен в правильности)

Не откажусь от советов и помощи в доработки.

alien 19.06.2010 18:03

Так в общем все эти размышления по поводу скорости были неверны.
Решил поснифать побольше данных с оффа.
Вот что получилось вот как изменяются параметры time и speedZ
в зависимости от расстояния.
Первый тест: расстояние - 10,931
Цитата:

Current Position: 5739,467 175,6612 181,5781
Time: 0x000000AF(175)
speedZ: float 130,6122
Dest position: 5735,85 185,9771 181,593
Второй тест: расстояние - 19,637
Цитата:

Current Position: 5737,253 188,6062 181,593
Time: 0x0000013B(315)
speedZ: float 40,31242
Dest position: 5726,408 204,9769 181,593
Третий тест: расстояние - 8,15411512
Цитата:

Current Position: 5727,32 163,5015 179,2827
Time: 0x00000083(131)
speedZ: float 233,0866
Dest position: 5724,258 156,6079 176,1856
Видно что чем Ближе тем speedZ Меньше и time тоже. Но вот как их рассчитать?
Все тесты проводились на http://ru.wowhead.com/spell=49576

rsa 19.06.2010 20:53

Судя по приведенному, используется приближенная физика расчета параболической траектории. При этом
time=v0*sin(a)/g
speedZ явно от приведенной к треугольнику траектории перемещения, тогда
speedZ = (v0**2*sin(a)**2/2g)*2/time

При этом угол a зависит от расстояния (видимо из-за лимита координаты Z, скорее всего из него и рассчитывается), начальная скорость v0 явно константа, а переменную гравитации g можно выкопать где-нибудь из физики мира ядра.
Могу подобрать и все коэффициенты, но это надо глубоко в код лезть...

Astellar 19.06.2010 21:31

Хм, а если на зависимость времени движения от расстояния глянуть, то она полностью линейная выходит, в пределах небольшой погрешности.

8,15411512 - 131
19,637 - T2
10,931 - T3
1 - T4

T2 = 19,637 * 131 / 8,15411512 = 315,48
T3 = 10,931 * 131 / 8,15411512 = 175,61
T4 = 1 * 131 / 8,15411512 = 16,0655

Откуда можно предположить, что на преодоление единицы пути тратится около 16 единиц времени.

rsa 20.06.2010 00:15

Ну при малом угле а (а при лимите координаты Z он не будет большим никогда, на малой дистанции его придется снижать) скорость перемещения по X действительно будет почти константой ;)

MaxXx2021 25.06.2010 08:29

Цитата:

Сообщение от alien (Сообщение 8395)
Код:

diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index c43ce0f..96baee6 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -305,6 +305,27 @@ MotionMaster::MovePoint(uint32 id, float x, float y, float z)
    else
        Mutate(new PointMovementGenerator<Creature>(id,x,y,z));
 }
+void
+MotionMaster::MoveJump(float x, float y, float z, float speedZ)
+{
+    uint32 moveFlag = SPLINEFLAG_TRAJECTORY | SPLINEFLAG_WALKMODE;
+    uint32 time = 521;
+
+    i_owner->addUnitState(UNIT_STAT_FLEEING_MOVE | UNIT_STAT_JUMPING);
+    if (i_owner->GetTypeId() == TYPEID_PLAYER)
+    {
+        DEBUG_LOG("Player (GUID: %u) jump to point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z);
+        Mutate(new PointMovementGenerator<Player>(0,x,y,z));
+    }
+    else
+    {
+        DEBUG_LOG("Creature (Entry: %u GUID: %u) jump to point (X: %f Y: %f Z: %f)",
+            i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z);
+        Mutate(new PointMovementGenerator<Creature>(0,x,y,z));
+    }
+
+    i_owner->SendMonsterMove(x, y, z,SPLINETYPE_NORMAL, (SplineFlags)moveFlag, time,NULL, speedZ);
+}
 
 void
 MotionMaster::MoveSeekAssistance(float x, float y, float z)
diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h
index 139387a..097e4f8 100644
--- a/src/game/MotionMaster.h
+++ b/src/game/MotionMaster.h
@@ -115,6 +115,8 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
        void UpdateFinalDistanceToTarget(float fDistance);
 
        bool GetDestination(float &x, float &y, float &z);
+
+                void MoveJump(float x, float y, float z, float speedZ);
    private:
        void Mutate(MovementGenerator *m);                  // use Move* functions instead
 
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 109e9b3..b491d15 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -2772,7 +2789,15 @@ void Spell::EffectJump(SpellEffectIndex eff_idx)
        return;
    }
 
-    m_caster->NearTeleportTo(x, y, z, o, true);
+  // m_caster->NearTeleportTo(x, y, z, o, true);
+            float speedZ;
+    if (m_spellInfo->EffectMiscValue[eff_idx])
+        speedZ = float(m_spellInfo->EffectMiscValue[eff_idx])/7.8f;
+    else if (m_spellInfo->EffectMiscValueB[eff_idx])
+        speedZ = float(m_spellInfo->EffectMiscValueB[eff_idx])/7.8f;
+    else
+        speedZ = 10.0f;
+    m_caster->GetMotionMaster()->MoveJump(x, y, z, speedZ);
 }
 
 void Spell::EffectTeleportUnits(SpellEffectIndex eff_idx)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e35ab4f..1c1e59a 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -387,8 +387,16 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineTy
    // enable me if things goes wrong or looks ugly, it is however an old hack
    // if(flags & SPLINEFLAG_WALKMODE)
        // moveTime *= 1.05f;
-
-    data << uint32(moveTime);                              // Time in between points
+               
+            if (flags & SPLINEFLAG_TRAJECTORY)
+    {
+        data << uint32(moveTime); 
+        data << float(va_arg(vargs,double));
+        data << uint32(0); // walk time after jump
+    }
+    else
+        data << uint32(moveTime);                              // Time in between points
+               
    data << uint32(1);                                      // 1 single waypoint
    data << NewPosX << NewPosY << NewPosZ;                  // the single waypoint Point B
 
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 9f5440f..fb5e033 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -435,7 +435,7 @@ enum UnitState
    UNIT_STAT_FOLLOW_MOVE    = 0x00008000,
    UNIT_STAT_FLEEING        = 0x00010000,                    // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
    UNIT_STAT_FLEEING_MOVE    = 0x00020000,
-
+        UNIT_STAT_JUMPING                  = 0x00040000,
    // masks (only for check)
 
    // can't move currently

Собственно выдрано из Тринити и переработано.
Но остались некоторые вопросы.
1) как высчитать uint32 time = 521;
В тринити делают так uint32 time = speedZ * 100;
Но это неправильно.(так как при их расчетах получается число 1500 а должно 521, это напримере Десгрипа http://ru.wowhead.com/spell=49575).
2)И значение speedZ у них неверное. Должно быть в раене 19.2
При поможи speedZ = float(m_spellInfo->EffectMiscValueB[eff_idx])/7.8f;
получилось что-то близкое к 19.2, но тоже не уверен в правильности)

Не откажусь от советов и помощи в доработки.

SpeedZ это высота прыжка на тринити. Я давно уже этот патч выдерал. Нечего не менял работает норм.

alien 25.06.2010 11:34

ну там неправильно считаются time и speedZ
если сравнивать с оффом. Даже на глаз разница ощутима.

Null 25.06.2010 12:05

не замечал разницы, что то у вас глаз какой-то слишком точный.

alien 25.06.2010 12:36

Просто я запускал 2 клиента один на оффе другой на свой сервер и сравнивал.
Сравнивал десгрип и прыжок у кошки. Разница видна. На своем серве скорость полета ниже.
Да и достаточно сравнить сниффы с официала и пиратки чтобы увидеть что расчеты у тринити неверно делаются.

MaxXx2021 05.10.2010 08:21

Не забываем что мы работаем в 3 мерном пространстве, а трех мерное пространство это бяка. Нужно учитывать рельеф. Что если тот на кого ты прыгаешь находиться выше чем высота прыжка? Учитывайте разницу высот.

BLAZEROS 19.03.2011 15:25

Проверил мод - работает.
Но когда я притягиваю спеллом ДК к себе моба например и убью его - то после его убийства этот труп от меня с быстрой скоростью ползет на тоже место где стоял моб - вот этот визуальный баг мне непонятен.


Текущее время: 19:18. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS