[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:
VladimirMangos 2010-03-17 01:38:26 +03:00
parent 56c08e2ef9
commit db51c29235
6 changed files with 91 additions and 108 deletions

View file

@ -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;
}