diff --git a/sql/mangos.sql b/sql/mangos.sql index a3b6c1ac5..82d8dd550 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_11733_01_mangos_spell_proc_event` bit(1) default NULL + `required_11754_mangos_mangos_string` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -3589,6 +3589,7 @@ INSERT INTO `mangos_string` VALUES (535,' Home movement to (X:%f Y:%f Z:%f)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (536,' Home movement used for player?!?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (537,' Taxi flight',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1192,' Effect movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (538,' Unknown movement generator (%u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (539,'Player selected: %s.\nFaction: %u.\nnpcFlags: %u.\nEntry: %u.\nDisplayID: %u (Native: %u).',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (540,'Level: %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), diff --git a/sql/updates/11754_mangos_mangos_string.sql b/sql/updates/11754_mangos_mangos_string.sql new file mode 100644 index 000000000..3f9da4609 --- /dev/null +++ b/sql/updates/11754_mangos_mangos_string.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_11733_01_mangos_spell_proc_event required_11754_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry IN (1192); + +INSERT INTO mangos_string VALUES (1192,'Effect movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/src/game/Language.h b/src/game/Language.h index 1d593294e..4ee1877de 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -937,7 +937,8 @@ enum MangosStrings LANG_AHBOT_QUALITY_YELLOW = 1189, LANG_AHBOT_ITEMS_AMOUNT = 1190, LANG_AHBOT_ITEMS_RATIO = 1191, - // Room for more level 3 1192-1199 not used + LANG_MOVEGENS_EFFECT = 1192, + // Room for more level 3 1193-1199 not used // Debug commands LANG_CINEMATIC_NOT_EXIST = 1200, diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 5e5a7dfd2..38429e74a 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -6178,6 +6178,7 @@ bool ChatHandler::HandleMovegensCommand(char* /*args*/) } case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break; case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break; + case EFFECT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_EFFECT); break; default: PSendSysMessage(LANG_MOVEGENS_UNKNOWN,(*itr)->GetMovementGeneratorType()); break; diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index 2d87c8f16..dc1de957b 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -28,6 +28,7 @@ #include "WaypointMovementGenerator.h" #include "RandomMovementGenerator.h" #include "movement/MoveSpline.h" +#include "movement/MoveSplineInit.h" #include @@ -415,6 +416,7 @@ void MotionMaster::Mutate(MovementGenerator *m) case HOME_MOTION_TYPE: // DistractMovement interrupted by any other movement case DISTRACT_MOTION_TYPE: + case EFFECT_MOTION_TYPE: MovementExpired(false); default: break; @@ -462,3 +464,35 @@ void MotionMaster::UpdateFinalDistanceToTarget(float fDistance) if (!empty()) top()->UpdateFinalDistance(fDistance); } + +// Does almost nothing - just doesn't allows previous movegen interrupt current effect. Can be reused for charge effect +class EffectMovementGenerator : public MovementGenerator +{ +public: + void Initialize(Unit &) {} + void Finalize(Unit &unit) + { + // Since we have no proper states system need restore previous movement. + if (unit.GetTypeId() != TYPEID_PLAYER && unit.isAlive() && !unit.hasUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_FLEEING)) + { + if (Unit * victim = unit.getVictim()) + unit.GetMotionMaster()->MoveChase(victim); + else + unit.GetMotionMaster()->Initialize(); + } + } + void Interrupt(Unit &) {} + void Reset(Unit &) {} + bool Update(Unit &u, const uint32 &) { return !u.movespline->Finalized(); } + MovementGeneratorType GetMovementGeneratorType() const { return EFFECT_MOTION_TYPE; } +}; + +void MotionMaster::MoveJump(float x, float y, float z, float horizontalSpeed, float max_height) +{ + Movement::MoveSplineInit init(*m_owner); + init.MoveTo(x,y,z); + init.SetParabolic(max_height,0,false); + init.SetVelocity(horizontalSpeed); + init.Launch(); + Mutate(new EffectMovementGenerator()); +} diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h index 217c8815f..cb08d4e03 100644 --- a/src/game/MotionMaster.h +++ b/src/game/MotionMaster.h @@ -48,6 +48,7 @@ enum MovementGeneratorType ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance) TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance) FOLLOW_MOTION_TYPE = 14, // TargetedMovementGenerator.h + EFFECT_MOTION_TYPE = 15, }; enum MMCleanFlag @@ -107,6 +108,7 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack void MoveWaypoint(); void MoveTaxiFlight(uint32 path, uint32 pathnode); void MoveDistract(uint32 timeLimit); + void MoveJump(float x, float y, float z, float horizontalSpeed, float max_height); MovementGeneratorType GetCurrentMovementGeneratorType() const; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b0ab4de44..5eae5d15e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10496,10 +10496,9 @@ void Unit::KnockBackFrom(Unit* target, float horizontalSpeed, float verticalSpee float vsin = sin(angle); float vcos = cos(angle); - // Effect properly implemented only for players - if(GetTypeId()==TYPEID_PLAYER) + if (GetTypeId() == TYPEID_PLAYER) { - WorldPacket data(SMSG_MOVE_KNOCK_BACK, 8+4+4+4+4+4); + WorldPacket data(SMSG_MOVE_KNOCK_BACK, 9+4+4+4+4+4); data << GetPackGUID(); data << uint32(0); // Sequence data << float(vcos); // x direction @@ -10510,15 +10509,15 @@ void Unit::KnockBackFrom(Unit* target, float horizontalSpeed, float verticalSpee } else { - float dis = horizontalSpeed; + float moveTimeHalf = verticalSpeed / Movement::gravity; + float max_height = -Movement::computeFallElevation(moveTimeHalf,false,-verticalSpeed); + float dis = 2 * moveTimeHalf * horizontalSpeed; float ox, oy, oz; GetPosition(ox, oy, oz); - float fx = ox + dis * vcos; float fy = oy + dis * vsin; float fz = oz; - float fx2, fy2, fz2; // getObjectHitPos overwrite last args in any result case if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), ox,oy,oz+0.5f, fx,fy,oz+0.5f,fx2,fy2,fz2, -0.5f)) { @@ -10526,12 +10525,8 @@ void Unit::KnockBackFrom(Unit* target, float horizontalSpeed, float verticalSpee fy = fy2; fz = fz2; } - UpdateAllowedPositionZ(fx, fy, fz); - - //FIXME: this mostly hack, must exist some packet for proper creature move at client side - // with CreatureRelocation at server side - NearTeleportTo(fx, fy, fz, GetOrientation(), this == target); + GetMotionMaster()->MoveJump(fx,fy,fz,horizontalSpeed,max_height); } } diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index bc6ed8b8a..54fac4412 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -312,7 +312,7 @@ void FlightPathMovementGenerator::Reset(Player & player) bool FlightPathMovementGenerator::Update(Player &player, const uint32 &diff) { - int32 pointId = player.movespline->currentPathIdx(); + uint32 pointId = (uint32)player.movespline->currentPathIdx(); // currentPathIdx returns lastIdx + 1 at arrive while (i_currentNode < pointId) { diff --git a/src/game/movement/MoveSplineInit.h b/src/game/movement/MoveSplineInit.h index ed7ddc6d4..266e6f9ac 100644 --- a/src/game/movement/MoveSplineInit.h +++ b/src/game/movement/MoveSplineInit.h @@ -102,15 +102,6 @@ namespace Movement MoveSplineInitArgs args; Unit& unit; }; - - inline void MoveJumpInit(Unit& st, const Vector3& dest, float velocity, float parabolic_heigth = 0.5f) - { - MoveSplineInit init(st); - init.MoveTo(dest); - init.SetParabolic(parabolic_heigth,0,false); - init.SetVelocity(velocity); - init.Launch(); - } inline void MoveSplineInit::SetFly() { args.flags.EnableFlying();} inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable;} diff --git a/src/game/movement/typedefs.h b/src/game/movement/typedefs.h index 5178bdec9..0aa9d0c88 100644 --- a/src/game/movement/typedefs.h +++ b/src/game/movement/typedefs.h @@ -73,6 +73,9 @@ namespace Movement }; typedef counter UInt32Counter; + + extern double gravity; + extern float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity); } #endif // MANGOSSERVER_TYPEDEFS_H diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7403f107c..147a638ce 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11753" + #define REVISION_NR "11754" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 1928a7e92..4ef500fe9 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_11716_10_characters_mail" - #define REVISION_DB_MANGOS "required_11733_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_11754_mangos_mangos_string" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__