mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
[9596] Use area trigger zone check for inn leave case.
This is still have false cases but will more correct for specific area triggers. Also let cleanup code and store less data for Player.
This commit is contained in:
parent
56c08e2ef9
commit
db51c29235
6 changed files with 91 additions and 108 deletions
|
|
@ -837,6 +837,51 @@ uint32 const* GetTalentTabPages(uint32 cls)
|
|||
return sTalentTabPages[cls];
|
||||
}
|
||||
|
||||
bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta)
|
||||
{
|
||||
if (mapid != atEntry->mapid)
|
||||
return false;
|
||||
|
||||
if (atEntry->radius > 0)
|
||||
{
|
||||
// if we have radius check it
|
||||
float dist2 = (x-atEntry->x)*(x-atEntry->x) + (y-atEntry->y)*(y-atEntry->y) + (z-atEntry->z)*(z-atEntry->z);
|
||||
if(dist2 > (atEntry->radius + delta)*(atEntry->radius + delta))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have only extent
|
||||
|
||||
// rotate the players position instead of rotating the whole cube, that way we can make a simplified
|
||||
// is-in-cube check and we have to calculate only one point instead of 4
|
||||
|
||||
// 2PI = 360°, keep in mind that ingame orientation is counter-clockwise
|
||||
double rotation = 2*M_PI-atEntry->box_orientation;
|
||||
double sinVal = sin(rotation);
|
||||
double cosVal = cos(rotation);
|
||||
|
||||
float playerBoxDistX = x - atEntry->x;
|
||||
float playerBoxDistY = y - atEntry->y;
|
||||
|
||||
float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY*sinVal);
|
||||
float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX*sinVal);
|
||||
|
||||
// box edges are parallel to coordiante axis, so we can treat every dimension independently :D
|
||||
float dz = z - atEntry->z;
|
||||
float dx = rotPlayerX - atEntry->x;
|
||||
float dy = rotPlayerY - atEntry->y;
|
||||
if( (fabs(dx) > atEntry->box_x/2 + delta) ||
|
||||
(fabs(dy) > atEntry->box_y/2 + delta) ||
|
||||
(fabs(dz) > atEntry->box_z/2 + delta) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// script support functions
|
||||
MANGOS_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; }
|
||||
MANGOS_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore() { return &sSpellStore; }
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
|
|||
|
||||
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
|
||||
|
||||
bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta = 0.0f);
|
||||
|
||||
PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
|
||||
PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id);
|
||||
|
||||
|
|
|
|||
|
|
@ -695,92 +695,43 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
|||
return;
|
||||
}
|
||||
|
||||
if (GetPlayer()->GetMapId() != atEntry->mapid)
|
||||
{
|
||||
sLog.outDebug("Player '%s' (GUID: %u) too far (trigger map: %u player map: %u), ignore Area Trigger ID: %u", GetPlayer()->GetName(), atEntry->mapid, GetPlayer()->GetMapId(), GetPlayer()->GetGUIDLow(), Trigger_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
// delta is safe radius
|
||||
const float delta = 5.0f;
|
||||
// check if player in the range of areatrigger
|
||||
Player* pl = GetPlayer();
|
||||
|
||||
if (atEntry->radius > 0)
|
||||
if (!IsPointInAreaTriggerZone(atEntry, pl->GetMapId(), pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), delta))
|
||||
{
|
||||
// if we have radius check it
|
||||
float dist = pl->GetDistance(atEntry->x, atEntry->y, atEntry->z);
|
||||
if(dist > atEntry->radius + delta)
|
||||
{
|
||||
sLog.outDebug("Player '%s' (GUID: %u) too far (radius: %f distance: %f), ignore Area Trigger ID: %u",
|
||||
pl->GetName(), pl->GetGUIDLow(), atEntry->radius, dist, Trigger_ID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have only extent
|
||||
|
||||
// rotate the players position instead of rotating the whole cube, that way we can make a simplified
|
||||
// is-in-cube check and we have to calculate only one point instead of 4
|
||||
|
||||
// 2PI = 360°, keep in mind that ingame orientation is counter-clockwise
|
||||
double rotation = 2*M_PI-atEntry->box_orientation;
|
||||
double sinVal = sin(rotation);
|
||||
double cosVal = cos(rotation);
|
||||
|
||||
float playerBoxDistX = pl->GetPositionX() - atEntry->x;
|
||||
float playerBoxDistY = pl->GetPositionY() - atEntry->y;
|
||||
|
||||
float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY*sinVal);
|
||||
float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX*sinVal);
|
||||
|
||||
// box edges are parallel to coordiante axis, so we can treat every dimension independently :D
|
||||
float dz = pl->GetPositionZ() - atEntry->z;
|
||||
float dx = rotPlayerX - atEntry->x;
|
||||
float dy = rotPlayerY - atEntry->y;
|
||||
if( (fabs(dx) > atEntry->box_x/2 + delta) ||
|
||||
(fabs(dy) > atEntry->box_y/2 + delta) ||
|
||||
(fabs(dz) > atEntry->box_z/2 + delta) )
|
||||
{
|
||||
sLog.outDebug("Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %f 1/2 box Z: %f rotatedPlayerX: %f rotatedPlayerY: %f dZ:%f), ignore Area Trigger ID: %u",
|
||||
pl->GetName(), pl->GetGUIDLow(), atEntry->box_x/2, atEntry->box_y/2, atEntry->box_z/2, rotPlayerX, rotPlayerY, dz, Trigger_ID);
|
||||
return;
|
||||
}
|
||||
sLog.outDebug("Player '%s' (GUID: %u) too far, ignore Area Trigger ID: %u", pl->GetName(), pl->GetGUIDLow(), Trigger_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Script->scriptAreaTrigger(GetPlayer(), atEntry))
|
||||
if(Script->scriptAreaTrigger(pl, atEntry))
|
||||
return;
|
||||
|
||||
uint32 quest_id = sObjectMgr.GetQuestForAreaTrigger( Trigger_ID );
|
||||
if( quest_id && GetPlayer()->isAlive() && GetPlayer()->IsActiveQuest(quest_id) )
|
||||
if( quest_id && pl->isAlive() && pl->IsActiveQuest(quest_id) )
|
||||
{
|
||||
Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id);
|
||||
if( pQuest )
|
||||
{
|
||||
if(GetPlayer()->GetQuestStatus(quest_id) == QUEST_STATUS_INCOMPLETE)
|
||||
GetPlayer()->AreaExploredOrEventHappens( quest_id );
|
||||
if(pl->GetQuestStatus(quest_id) == QUEST_STATUS_INCOMPLETE)
|
||||
pl->AreaExploredOrEventHappens( quest_id );
|
||||
}
|
||||
}
|
||||
|
||||
if(sObjectMgr.IsTavernAreaTrigger(Trigger_ID))
|
||||
// enter to tavern, not overwrite city rest
|
||||
if(sObjectMgr.IsTavernAreaTrigger(Trigger_ID) && pl->GetRestType() != REST_TYPE_IN_CITY)
|
||||
{
|
||||
// set resting flag we are in the inn
|
||||
GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
GetPlayer()->InnEnter(time(NULL), atEntry->mapid, atEntry->x, atEntry->y, atEntry->z);
|
||||
GetPlayer()->SetRestType(REST_TYPE_IN_TAVERN);
|
||||
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
GetPlayer()->SetFFAPvP(false);
|
||||
|
||||
pl->SetRestType(REST_TYPE_IN_TAVERN, Trigger_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
if(GetPlayer()->InBattleGround())
|
||||
if(pl->InBattleGround())
|
||||
{
|
||||
BattleGround* bg = GetPlayer()->GetBattleGround();
|
||||
if(bg)
|
||||
bg->HandleAreaTrigger(GetPlayer(), Trigger_ID);
|
||||
if (BattleGround* bg = pl->GetBattleGround())
|
||||
bg->HandleAreaTrigger(pl, Trigger_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -431,10 +431,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
|||
|
||||
////////////////////Rest System/////////////////////
|
||||
time_inn_enter=0;
|
||||
inn_pos_mapid=0;
|
||||
inn_pos_x=0;
|
||||
inn_pos_y=0;
|
||||
inn_pos_z=0;
|
||||
inn_trigger_id=0;
|
||||
m_rest_bonus=0;
|
||||
rest_type=REST_TYPE_NO;
|
||||
////////////////////Rest System/////////////////////
|
||||
|
|
@ -1246,7 +1243,7 @@ void Player::Update( uint32 p_time )
|
|||
if (time_inn >= 10) //freeze update
|
||||
{
|
||||
float bubble = 0.125f*sWorld.getConfig(CONFIG_FLOAT_RATE_REST_INGAME);
|
||||
//speed collect rest bonus (section/in hour)
|
||||
//speed collect rest bonus (section/in hour)
|
||||
SetRestBonus( float(GetRestBonus()+ time_inn*(GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble ));
|
||||
UpdateInnerTime(time(NULL));
|
||||
}
|
||||
|
|
@ -6473,38 +6470,19 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
|||
}
|
||||
|
||||
if(zone->flags & AREA_FLAG_CAPITAL) // in capital city
|
||||
{
|
||||
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
SetRestType(REST_TYPE_IN_CITY);
|
||||
InnEnter(time(0),GetMapId(),0,0,0);
|
||||
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
SetFFAPvP(false);
|
||||
}
|
||||
else // anywhere else
|
||||
{
|
||||
if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) // but resting (walk from city or maybe in tavern or leave tavern recently)
|
||||
{
|
||||
if (GetRestType()==REST_TYPE_IN_TAVERN) // has been in tavern. Is still in?
|
||||
{
|
||||
if (GetMapId()!=GetInnPosMapId() || ((GetPositionX()-GetInnPosX())*(GetPositionX()-GetInnPosX())+(GetPositionY()-GetInnPosY())*(GetPositionY()-GetInnPosY())+(GetPositionZ()-GetInnPosZ())*(GetPositionZ()-GetInnPosZ())) > 30*30)
|
||||
{
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(inn_trigger_id);
|
||||
if (!at || !IsPointInAreaTriggerZone(at, GetMapId(), GetPositionX(), GetPositionY(), GetPositionY()))
|
||||
SetRestType(REST_TYPE_NO);
|
||||
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
SetFFAPvP(true);
|
||||
}
|
||||
}
|
||||
else // not in tavern (leave city then)
|
||||
{
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
SetRestType(REST_TYPE_NO);
|
||||
|
||||
// Set player to FFA PVP when not in rested environment.
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
SetFFAPvP(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -21721,3 +21699,27 @@ Object* Player::GetObjectByTypeMask(ObjectGuid guid, TypeMask typemask)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Player::SetRestType( RestType n_r_type, uint32 areaTriggerId /*= 0*/)
|
||||
{
|
||||
rest_type = n_r_type;
|
||||
|
||||
if (rest_type == REST_TYPE_NO)
|
||||
{
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
|
||||
// Set player to FFA PVP when not in rested environment.
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
SetFFAPvP(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
|
||||
inn_trigger_id = areaTriggerId;
|
||||
time_inn_enter = time(NULL);
|
||||
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
SetFFAPvP(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1099,25 +1099,11 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
void setDeathState(DeathState s); // overwrite Unit::setDeathState
|
||||
|
||||
void InnEnter (time_t time, uint32 mapid, float x, float y, float z)
|
||||
{
|
||||
inn_pos_mapid = mapid;
|
||||
inn_pos_x = x;
|
||||
inn_pos_y = y;
|
||||
inn_pos_z = z;
|
||||
time_inn_enter = time;
|
||||
}
|
||||
|
||||
float GetRestBonus() const { return m_rest_bonus; }
|
||||
void SetRestBonus(float rest_bonus_new);
|
||||
|
||||
RestType GetRestType() const { return rest_type; }
|
||||
void SetRestType(RestType n_r_type) { rest_type = n_r_type; }
|
||||
|
||||
uint32 GetInnPosMapId() const { return inn_pos_mapid; }
|
||||
float GetInnPosX() const { return inn_pos_x; }
|
||||
float GetInnPosY() const { return inn_pos_y; }
|
||||
float GetInnPosZ() const { return inn_pos_z; }
|
||||
void SetRestType(RestType n_r_type, uint32 areaTriggerId = 0);
|
||||
|
||||
time_t GetTimeInnEnter() const { return time_inn_enter; }
|
||||
void UpdateInnerTime (time_t time) { time_inn_enter = time; }
|
||||
|
|
@ -2472,10 +2458,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
////////////////////Rest System/////////////////////
|
||||
time_t time_inn_enter;
|
||||
uint32 inn_pos_mapid;
|
||||
float inn_pos_x;
|
||||
float inn_pos_y;
|
||||
float inn_pos_z;
|
||||
uint32 inn_trigger_id;
|
||||
float m_rest_bonus;
|
||||
RestType rest_type;
|
||||
////////////////////Rest System/////////////////////
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9595"
|
||||
#define REVISION_NR "9596"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue