diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 2322d3f..9d29291 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -863,10 +863,10 @@ void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entry if (!sEmotesStore.LookupEntry(addon->emote)) sLog.outErrorDb("Creature (%s %u) have invalid emote (%u) defined in `%s`.", entryName, addon->guidOrEntry, addon->emote, creatureaddons.GetTableName()); - if (addon->move_flags & (MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4)) + if (addon->move_flags & (MONSTER_MOVE_JUMP|MONSTER_MOVE_UNK4)) { - sLog.outErrorDb("Creature (%s %u) movement flags mask defined in `%s` include forbidden flags (" I32FMT ") that can crash client, cleanup at load.", entryName, addon->guidOrEntry, creatureaddons.GetTableName(), (MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4)); - const_cast(addon)->move_flags &= ~(MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4); + sLog.outErrorDb("Creature (%s %u) movement flags mask defined in `%s` include forbidden flags (" I32FMT ") that can crash client, cleanup at load.", entryName, addon->guidOrEntry, creatureaddons.GetTableName(), (MONSTER_MOVE_JUMP|MONSTER_MOVE_UNK4)); + const_cast(addon)->move_flags &= ~(MONSTER_MOVE_JUMP|MONSTER_MOVE_UNK4); } ConvertCreatureAddonAuras(const_cast(addon), creatureaddons.GetTableName(), entryName); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index cdfdef2..ae48e4e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -288,6 +288,48 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 ty moveTime *= 1.05f; data << uint32(moveTime); // Time in between points + + if(flags & MONSTER_MOVE_JUMP) + { + data << float(0); + data << uint32(0); + } + + data << uint32(1); // 1 single waypoint + data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B + + if(player) + player->GetSession()->SendPacket(&data); + else + SendMessageToSet( &data, true ); +} + +void Unit::SendMonsterMoveJump(float NewPosX, float NewPosY, float NewPosZ, float vert_speed, uint32 flags, uint32 Time, Player* player) +{ + float moveTime = Time; + flags |= MONSTER_MOVE_JUMP; + + WorldPacket data( SMSG_MONSTER_MOVE, (49 + GetPackGUID().size()) ); + data.append(GetPackGUID()); + data << uint8(0); // new in 3.1 + data << GetPositionX() << GetPositionY() << GetPositionZ(); + data << uint32(getMSTime()); + + data << uint8(0); // unknown + + data << uint32(flags); + + if(flags & MONSTER_MOVE_WALK) + moveTime *= 1.05f; + + data << uint32(moveTime); // Time in between points + + if(flags & MONSTER_MOVE_JUMP) + { + data << float(vert_speed); + data << uint32(0); + } + data << uint32(1); // 1 single waypoint data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B @@ -12986,7 +13028,7 @@ void Unit::SetPvP( bool state ) totem->SetPvP(state); } -void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpeed) +void Unit::KnockBackFrom(Unit* target, float horizontalSpeed, float verticalSpeed) { float angle = this == target ? GetOrientation() + M_PI : target->GetAngle(this); float vsin = sin(angle); @@ -13000,14 +13042,17 @@ void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpee data << uint32(0); // Sequence data << float(vcos); // x direction data << float(vsin); // y direction - data << float(horizintalSpeed); // Horizontal speed + data << float(horizontalSpeed); // Horizontal speed data << float(-verticalSpeed); // Z Movement speed (vertical) ((Player*)this)->GetSession()->SendPacket(&data); } else { - float dis = horizintalSpeed; + float g = 19.23f;// seems that physic constant g(earth's gravity) in world of warcraft is about 2 times larger than real + float dh = verticalSpeed*verticalSpeed / (2*g); // maximum parabola height + float time = sqrtf(dh/(0.124976 * verticalSpeed)); //full move time in seconds // should be time = 2*Vert_speed/g, but.. + float dis = time * horizontalSpeed; float ox, oy, oz; GetPosition(ox, oy, oz); @@ -13024,9 +13069,8 @@ void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpee UpdateGroundPositionZ(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); + GetMap()->CreatureRelocation((Creature*)this, fx, fy, fz, GetOrientation());//it's a hack, need motion master support + SendMonsterMoveJump(fx, fy, fz, verticalSpeed, MONSTER_MOVE_WALK, uint32(time * 1000.0f)); } } diff --git a/src/game/Unit.h b/src/game/Unit.h index 51b19be..aeb38ba 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -586,7 +586,7 @@ enum MonsterMovementFlags MONSTER_MOVE_TELEPORT = 0x00000100, MONSTER_MOVE_TELEPORT2 = 0x00000200, MONSTER_MOVE_LEVITATING = 0x00000400, - MONSTER_MOVE_UNK1 = 0x00000800, // float+uint32 + MONSTER_MOVE_JUMP = 0x00000800, // float+uint32 MONSTER_MOVE_WALK = 0x00001000, // run2? MONSTER_MOVE_SPLINE = 0x00002000, // spline n*(float x,y,z) // 0x4000, 0x8000, 0x10000, 0x20000 run @@ -1162,6 +1162,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false); void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, MonsterMovementFlags flags, uint32 Time, Player* player = NULL); + void SendMonsterMoveJump(float NewPosX, float NewPosY, float NewPosZ, float vert_speed, uint32 flags, uint32 Time, Player* player = NULL); void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, MonsterMovementFlags flags); void SendHighestThreatUpdate(HostileReference* pHostileReference);