[11754] Implement jump (parabolic movement) effect

Also correct destination calculation in Unit::KnockBackFrom - now spline knockback effect works similar to client's effect (same amplitude, speed etc)
This commit is contained in:
SilverIce 2011-07-26 13:56:06 +03:00
parent 28759f9ed4
commit a7610f79c7
12 changed files with 58 additions and 25 deletions

View file

@ -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),

View file

@ -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);

View file

@ -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,

View file

@ -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;

View file

@ -28,6 +28,7 @@
#include "WaypointMovementGenerator.h"
#include "RandomMovementGenerator.h"
#include "movement/MoveSpline.h"
#include "movement/MoveSplineInit.h"
#include <cassert>
@ -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());
}

View file

@ -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<MovementGenerator *>
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;

View file

@ -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);
}
}

View file

@ -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)
{

View file

@ -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;}

View file

@ -73,6 +73,9 @@ namespace Movement
};
typedef counter<uint32, 0xFFFFFFFF> UInt32Counter;
extern double gravity;
extern float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity);
}
#endif // MANGOSSERVER_TYPEDEFS_H

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11753"
#define REVISION_NR "11754"
#endif // __REVISION_NR_H__

View file

@ -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__