mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[11529] Pack and send to client all gameobject's quaternion components which allows place gameobjects cornerwise.
Update '.gobject turn' command, now you have to specify 3 rotations to turn gameobject: rotation angles around z, y and x axes. Note to DB devs: use QuaternionCompressed::Unpack to extract rotations from the data that came with UPDATEFLAG_ROTATION.
This commit is contained in:
parent
ab50a7d3e9
commit
7c86d3f477
8 changed files with 70 additions and 48 deletions
|
|
@ -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_11523_02_mangos_mangos_string` bit(1) default NULL
|
||||
`required_11529_01_mangos_command` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -587,7 +587,7 @@ INSERT INTO `command` VALUES
|
|||
('gobject move',2,'Syntax: .gobject move #goguid [#x #y #z]\r\n\r\nMove gameobject #goguid to character coordinates (or to (#x,#y,#z) coordinates if its provide).'),
|
||||
('gobject near',2,'Syntax: .gobject near [#distance]\r\n\r\nOutput gameobjects at distance #distance from player. Output gameobject guids and coordinates sorted by distance from character. If #distance not provided use 10 as default value.'),
|
||||
('gobject setphase',2,'Syntax: .gobject setphase #guid #phasemask\r\n\r\nGameobject with DB guid #guid phasemask changed to #phasemask with related world vision update for players. Gameobject state saved to DB and persistent.'),
|
||||
('gobject turn',2,'Syntax: .gobject turn #goguid \r\n\r\nSet for gameobject #goguid orientation same as current character orientation.'),
|
||||
('gobject turn',2,'Syntax: .gobject turn #goguid [#z_angle]\r\n\r\nChanges gameobject #goguid orientation (rotates gameobject around z axis). Optional parameters are (#y_angle,#x_angle) values that represents rotation angles around y and x axes.'),
|
||||
('gobject target',2,'Syntax: .gobject target [#go_id|#go_name_part]\r\n\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'),
|
||||
('goname',1,'Syntax: .goname [$charactername]\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group. Character can be offline.'),
|
||||
('gps',1,'Syntax: .gps [$name|$shift-link]\r\n\r\nDisplay the position information for a selected character or creature (also if player name $name provided then for named player, or if creature/gameobject shift-link provided then pointed creature/gameobject if it loaded). Position information includes X, Y, Z, and orientation, map Id and zone Id'),
|
||||
|
|
|
|||
6
sql/updates/11529_01_mangos_command.sql
Normal file
6
sql/updates/11529_01_mangos_command.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_11523_02_mangos_mangos_string required_11529_01_mangos_command bit;
|
||||
|
||||
DELETE FROM command WHERE name = 'gobject turn';
|
||||
|
||||
INSERT INTO command (name, security, help) VALUES
|
||||
('gobject turn',2,'Syntax: .gobject turn #goguid [#z_angle]\r\n\r\nChanges gameobject #goguid orientation (rotates gameobject around z axis). Optional parameters are (#y_angle,#x_angle) values that represents rotation angles around y and x axes.');
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
#include "BattleGroundAV.h"
|
||||
#include "Util.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include <G3D/Quat.h>
|
||||
|
||||
GameObject::GameObject() : WorldObject(),
|
||||
m_goInfo(NULL),
|
||||
|
|
@ -128,10 +129,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
|
|||
|
||||
SetObjectScale(goinfo->size);
|
||||
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1);
|
||||
|
||||
UpdateRotationFields(rotation2,rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_PARENTROTATION+2/3
|
||||
SetRotationQuat(rotation0,rotation1,rotation2,rotation3);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
|
|
@ -1632,34 +1630,60 @@ const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const
|
|||
return GetName();
|
||||
}
|
||||
|
||||
void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3 /*=0.0f*/)
|
||||
using G3D::Quat;
|
||||
struct QuaternionCompressed
|
||||
{
|
||||
static double const atan_pow = atan(pow(2.0f, -20.0f));
|
||||
QuaternionCompressed() : m_raw(0) {}
|
||||
QuaternionCompressed(int64 val) : m_raw(val) {}
|
||||
QuaternionCompressed(const Quat& quat) { Set(quat); }
|
||||
|
||||
double f_rot1 = sin(GetOrientation() / 2.0f);
|
||||
double f_rot2 = cos(GetOrientation() / 2.0f);
|
||||
enum{
|
||||
PACK_COEFF_YZ = 1 << 20,
|
||||
PACK_COEFF_X = 1 << 21,
|
||||
};
|
||||
|
||||
int64 i_rot1 = int64(f_rot1 / atan_pow *(f_rot2 >= 0 ? 1.0f : -1.0f));
|
||||
int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;
|
||||
|
||||
//float f_rot2 = sin(0.0f / 2.0f);
|
||||
//int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f));
|
||||
//rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000;
|
||||
|
||||
//float f_rot3 = sin(0.0f / 2.0f);
|
||||
//int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f));
|
||||
//rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000;
|
||||
|
||||
m_rotation = rotation;
|
||||
|
||||
if(rotation2==0.0f && rotation3==0.0f)
|
||||
void Set(const Quat& quat)
|
||||
{
|
||||
rotation2 = (float)f_rot1;
|
||||
rotation3 = (float)f_rot2;
|
||||
int8 w_sign = (quat.w >= 0 ? 1 : -1);
|
||||
int64 X = int32(quat.x * PACK_COEFF_X) * w_sign & ((1 << 22) - 1);
|
||||
int64 Y = int32(quat.y * PACK_COEFF_YZ) * w_sign & ((1 << 21) - 1);
|
||||
int64 Z = int32(quat.z * PACK_COEFF_YZ) * w_sign & ((1 << 21) - 1);
|
||||
m_raw = Z | (Y << 21) | (X << 42);
|
||||
}
|
||||
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
|
||||
Quat Unpack() const
|
||||
{
|
||||
double x = (double)(m_raw >> 42) / (double)PACK_COEFF_X;
|
||||
double y = (double)(m_raw << 22 >> 43) / (double)PACK_COEFF_YZ;
|
||||
double z = (double)(m_raw << 43 >> 43) / (double)PACK_COEFF_YZ;
|
||||
double w = 1 - (x * x + y * y + z * z);
|
||||
MANGOS_ASSERT(w >= 0);
|
||||
w = sqrt(w);
|
||||
|
||||
return Quat(x,y,z,w);
|
||||
}
|
||||
|
||||
int64 m_raw;
|
||||
};
|
||||
|
||||
void GameObject::SetRotationQuat(float qx, float qy, float qz, float qw)
|
||||
{
|
||||
Quat quat(qx, qy, qz, qw);
|
||||
// Temporary solution for gameobjects that has no rotation data in DB:
|
||||
if (qz == 0 && qw == 0)
|
||||
quat = Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), GetOrientation());
|
||||
|
||||
m_rotation = QuaternionCompressed(quat).m_raw;
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+0, quat.x);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+1, quat.y);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+2, quat.z);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, quat.w);
|
||||
}
|
||||
|
||||
void GameObject::SetRotationAngles(float z_rot, float y_rot, float x_rot)
|
||||
{
|
||||
Quat quat( G3D::Matrix3::fromEulerAnglesZYX(z_rot, y_rot, x_rot) );
|
||||
SetRotationQuat(quat.x, quat.y, quat.z, quat.w);
|
||||
}
|
||||
|
||||
bool GameObject::IsHostileTo(Unit const* unit) const
|
||||
|
|
|
|||
|
|
@ -606,7 +606,9 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
|||
|
||||
bool HasStaticDBSpawnData() const; // listed in `gameobject` table and have fixed in DB guid
|
||||
|
||||
void UpdateRotationFields(float rotation2 = 0.0f, float rotation3 = 0.0f);
|
||||
// z_rot, y_rot, x_rot - rotation angles around z, y and x axes
|
||||
void SetRotationAngles(float z_rot, float y_rot, float x_rot);
|
||||
int64 GetRotation() const { return m_rotation; }
|
||||
|
||||
// overwrite WorldObject function for proper name localization
|
||||
const char* GetNameForLocaleIdx(int32 locale_idx) const;
|
||||
|
|
@ -721,7 +723,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
|||
|
||||
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
|
||||
|
||||
uint64 GetRotation() const { return m_rotation; }
|
||||
protected:
|
||||
uint32 m_spellId;
|
||||
time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()),
|
||||
|
|
@ -743,9 +744,10 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
|||
|
||||
GameObjectInfo const* m_goInfo;
|
||||
GameObjectDisplayInfoEntry const* m_displayInfo;
|
||||
uint64 m_rotation;
|
||||
int64 m_rotation;
|
||||
private:
|
||||
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
||||
void SetRotationQuat(float qx, float qy, float qz, float qw);
|
||||
|
||||
GridReference<GameObject> m_gridRef;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -958,23 +958,13 @@ bool ChatHandler::HandleGameObjectTurnCommand(char* args)
|
|||
return false;
|
||||
}
|
||||
|
||||
float o;
|
||||
if (!ExtractOptFloat(&args, o, m_session->GetPlayer()->GetOrientation()))
|
||||
return false;
|
||||
|
||||
Map* map = obj->GetMap();
|
||||
map->Remove(obj,false);
|
||||
|
||||
obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
|
||||
obj->UpdateRotationFields();
|
||||
|
||||
map->Add(obj);
|
||||
float z_rot, y_rot, x_rot;
|
||||
if (!ExtractFloat(&args, z_rot) || !ExtractOptFloat(&args, y_rot, 0) || !ExtractOptFloat(&args, x_rot, 0))
|
||||
return false;
|
||||
|
||||
obj->SetRotationAngles(z_rot, y_rot, x_rot);
|
||||
obj->SaveToDB();
|
||||
obj->Refresh();
|
||||
|
||||
PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -511,7 +511,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
|
|||
// 0x200
|
||||
if(updateFlags & UPDATEFLAG_ROTATION)
|
||||
{
|
||||
*data << uint64(((GameObject*)this)->GetRotation());
|
||||
*data << int64(((GameObject*)this)->GetRotation());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11528"
|
||||
#define REVISION_NR "11529"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_11436_01_characters_character_queststatus"
|
||||
#define REVISION_DB_MANGOS "required_11523_02_mangos_mangos_string"
|
||||
#define REVISION_DB_MANGOS "required_11529_01_mangos_command"
|
||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue