diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 6154967e2..0a8d0ee39 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -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 const* GetSoundEntriesStore() { return &sSoundEntriesStore; } MANGOS_DLL_SPEC DBCStorage const* GetSpellStore() { return &sSpellStore; } diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index b82d34382..e9cf95674 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -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); diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 59e53eeec..d9589305d 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -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; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index bffd85eff..2992f68e4 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -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); + } +} \ No newline at end of file diff --git a/src/game/Player.h b/src/game/Player.h index 159d8c591..e38136380 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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///////////////////// diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 20eec99ba..aba8755b6 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9595" + #define REVISION_NR "9596" #endif // __REVISION_NR_H__