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,
|
`version` varchar(120) default NULL,
|
||||||
`creature_ai_version` varchar(120) default NULL,
|
`creature_ai_version` varchar(120) default NULL,
|
||||||
`cache_id` int(10) default '0',
|
`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';
|
) 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 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 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 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.'),
|
('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.'),
|
('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'),
|
('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 "BattleGroundAV.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
|
#include <G3D/Quat.h>
|
||||||
|
|
||||||
GameObject::GameObject() : WorldObject(),
|
GameObject::GameObject() : WorldObject(),
|
||||||
m_goInfo(NULL),
|
m_goInfo(NULL),
|
||||||
|
|
@ -128,10 +129,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
|
||||||
|
|
||||||
SetObjectScale(goinfo->size);
|
SetObjectScale(goinfo->size);
|
||||||
|
|
||||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0);
|
SetRotationQuat(rotation0,rotation1,rotation2,rotation3);
|
||||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1);
|
|
||||||
|
|
||||||
UpdateRotationFields(rotation2,rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_PARENTROTATION+2/3
|
|
||||||
|
|
||||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||||
|
|
@ -1632,34 +1630,60 @@ const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const
|
||||||
return GetName();
|
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);
|
enum{
|
||||||
double f_rot2 = cos(GetOrientation() / 2.0f);
|
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));
|
void Set(const Quat& quat)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
rotation2 = (float)f_rot1;
|
int8 w_sign = (quat.w >= 0 ? 1 : -1);
|
||||||
rotation3 = (float)f_rot2;
|
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);
|
Quat Unpack() const
|
||||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
|
{
|
||||||
|
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
|
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
|
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
|
// overwrite WorldObject function for proper name localization
|
||||||
const char* GetNameForLocaleIdx(int32 locale_idx) const;
|
const char* GetNameForLocaleIdx(int32 locale_idx) const;
|
||||||
|
|
@ -721,7 +723,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
||||||
|
|
||||||
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
|
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
|
||||||
|
|
||||||
uint64 GetRotation() const { return m_rotation; }
|
|
||||||
protected:
|
protected:
|
||||||
uint32 m_spellId;
|
uint32 m_spellId;
|
||||||
time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()),
|
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;
|
GameObjectInfo const* m_goInfo;
|
||||||
GameObjectDisplayInfoEntry const* m_displayInfo;
|
GameObjectDisplayInfoEntry const* m_displayInfo;
|
||||||
uint64 m_rotation;
|
int64 m_rotation;
|
||||||
private:
|
private:
|
||||||
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
||||||
|
void SetRotationQuat(float qx, float qy, float qz, float qw);
|
||||||
|
|
||||||
GridReference<GameObject> m_gridRef;
|
GridReference<GameObject> m_gridRef;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -958,23 +958,13 @@ bool ChatHandler::HandleGameObjectTurnCommand(char* args)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float o;
|
float z_rot, y_rot, x_rot;
|
||||||
if (!ExtractOptFloat(&args, o, m_session->GetPlayer()->GetOrientation()))
|
if (!ExtractFloat(&args, z_rot) || !ExtractOptFloat(&args, y_rot, 0) || !ExtractOptFloat(&args, x_rot, 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Map* map = obj->GetMap();
|
|
||||||
map->Remove(obj,false);
|
|
||||||
|
|
||||||
obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
|
|
||||||
obj->UpdateRotationFields();
|
|
||||||
|
|
||||||
map->Add(obj);
|
|
||||||
|
|
||||||
|
obj->SetRotationAngles(z_rot, y_rot, x_rot);
|
||||||
obj->SaveToDB();
|
obj->SaveToDB();
|
||||||
obj->Refresh();
|
|
||||||
|
|
||||||
PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());
|
PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -511,7 +511,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags) const
|
||||||
// 0x200
|
// 0x200
|
||||||
if(updateFlags & UPDATEFLAG_ROTATION)
|
if(updateFlags & UPDATEFLAG_ROTATION)
|
||||||
{
|
{
|
||||||
*data << uint64(((GameObject*)this)->GetRotation());
|
*data << int64(((GameObject*)this)->GetRotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11528"
|
#define REVISION_NR "11529"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __REVISION_SQL_H__
|
#ifndef __REVISION_SQL_H__
|
||||||
#define __REVISION_SQL_H__
|
#define __REVISION_SQL_H__
|
||||||
#define REVISION_DB_CHARACTERS "required_11436_01_characters_character_queststatus"
|
#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"
|
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||||
#endif // __REVISION_SQL_H__
|
#endif // __REVISION_SQL_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue