mirror of
https://github.com/mangosfour/server.git
synced 2025-12-23 16:37:03 +00:00
[12195] Improve AreaTrigger teleport requirement checks
Implement AreaLockStatus concept by rsa Also drop basicly unneeded `areatrigger_teleport`.required_failed_text field. This concept is still in testing phase, please feedback results of some glitches that might exist! TODO: Use Player::GetAreaLockStatus or GetAreaTriggerLockStatus for other "CanEnter" checks as well. Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
parent
7901613472
commit
9022705faf
22 changed files with 304 additions and 162 deletions
|
|
@ -16774,7 +16774,7 @@ void Player::_LoadBoundInstances(QueryResult* result)
|
|||
continue;
|
||||
}
|
||||
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(mapId, Difficulty(difficulty));
|
||||
MapDifficultyEntry const* mapDiff = GetMapDifficultyData(mapId, Difficulty(difficulty));
|
||||
if (!mapDiff)
|
||||
{
|
||||
sLog.outError("_LoadBoundInstances: player %s(%d) has bind to nonexistent difficulty %d instance for map %u", GetName(), GetGUIDLow(), difficulty, mapId);
|
||||
|
|
@ -16803,7 +16803,7 @@ void Player::_LoadBoundInstances(QueryResult* result)
|
|||
InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, Difficulty difficulty)
|
||||
{
|
||||
// some instances only have one difficulty
|
||||
MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty);
|
||||
MapDifficultyEntry const* mapDiff = GetMapDifficultyData(mapid, difficulty);
|
||||
if (!mapDiff)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -23611,3 +23611,123 @@ void Player::SendRatedBGStats()
|
|||
|
||||
SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
AreaLockStatus Player::GetAreaTriggerLockStatus(AreaTrigger const* at, Difficulty difficulty, uint32& miscRequirement)
|
||||
{
|
||||
miscRequirement = 0;
|
||||
|
||||
if (!at)
|
||||
return AREA_LOCKSTATUS_UNKNOWN_ERROR;
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(at->target_mapId);
|
||||
if (!mapEntry)
|
||||
return AREA_LOCKSTATUS_UNKNOWN_ERROR;
|
||||
|
||||
bool isRegularTargetMap = !mapEntry->IsDungeon() || GetDifficulty(mapEntry->IsRaid()) == REGULAR_DIFFICULTY;
|
||||
|
||||
MapDifficultyEntry const* mapDiff = GetMapDifficultyData(at->target_mapId, difficulty);
|
||||
if (mapEntry->IsDungeon() && !mapDiff)
|
||||
return AREA_LOCKSTATUS_MISSING_DIFFICULTY;
|
||||
|
||||
// Expansion requirement
|
||||
if (GetSession()->Expansion() < mapEntry->Expansion())
|
||||
{
|
||||
miscRequirement = mapEntry->Expansion();
|
||||
return AREA_LOCKSTATUS_INSUFFICIENT_EXPANSION;
|
||||
}
|
||||
|
||||
// Gamemaster can always enter
|
||||
if (isGameMaster())
|
||||
return AREA_LOCKSTATUS_OK;
|
||||
|
||||
// Level Requirements
|
||||
if (getLevel() < at->requiredLevel && !sWorld.getConfig(CONFIG_BOOL_INSTANCE_IGNORE_LEVEL))
|
||||
{
|
||||
miscRequirement = at->requiredLevel;
|
||||
return AREA_LOCKSTATUS_TOO_LOW_LEVEL;
|
||||
}
|
||||
if (!isRegularTargetMap && !sWorld.getConfig(CONFIG_BOOL_INSTANCE_IGNORE_LEVEL) && getLevel() < uint32(maxLevelForExpansion[mapEntry->Expansion()]))
|
||||
{
|
||||
miscRequirement = maxLevelForExpansion[mapEntry->Expansion()];
|
||||
return AREA_LOCKSTATUS_TOO_LOW_LEVEL;
|
||||
}
|
||||
|
||||
// Raid Requirements
|
||||
if (mapEntry->IsRaid() && !sWorld.getConfig(CONFIG_BOOL_INSTANCE_IGNORE_RAID))
|
||||
if (!GetGroup() || !GetGroup()->isRaidGroup())
|
||||
return AREA_LOCKSTATUS_RAID_LOCKED;
|
||||
|
||||
// Item Requirements: must have requiredItem OR requiredItem2, report the first one that's missing
|
||||
if (at->requiredItem)
|
||||
{
|
||||
if (!HasItemCount(at->requiredItem, 1) &&
|
||||
(!at->requiredItem2 || !HasItemCount(at->requiredItem2, 1)))
|
||||
{
|
||||
miscRequirement = at->requiredItem;
|
||||
return AREA_LOCKSTATUS_MISSING_ITEM;
|
||||
}
|
||||
}
|
||||
else if (at->requiredItem2 && !HasItemCount(at->requiredItem2, 1))
|
||||
{
|
||||
miscRequirement = at->requiredItem2;
|
||||
return AREA_LOCKSTATUS_MISSING_ITEM;
|
||||
}
|
||||
// Heroic item requirements
|
||||
if (!isRegularTargetMap && at->heroicKey)
|
||||
{
|
||||
if (!HasItemCount(at->heroicKey, 1) && (!at->heroicKey2 || !HasItemCount(at->heroicKey2, 1)))
|
||||
{
|
||||
miscRequirement = at->heroicKey;
|
||||
return AREA_LOCKSTATUS_MISSING_ITEM;
|
||||
}
|
||||
}
|
||||
else if (!isRegularTargetMap && at->heroicKey2 && !HasItemCount(at->heroicKey2, 1))
|
||||
{
|
||||
miscRequirement = at->heroicKey2;
|
||||
return AREA_LOCKSTATUS_MISSING_ITEM;
|
||||
}
|
||||
|
||||
// Quest Requirements
|
||||
if (isRegularTargetMap && at->requiredQuest && !GetQuestRewardStatus(at->requiredQuest))
|
||||
{
|
||||
miscRequirement = at->requiredQuest;
|
||||
return AREA_LOCKSTATUS_QUEST_NOT_COMPLETED;
|
||||
}
|
||||
if (!isRegularTargetMap && at->requiredQuestHeroic && !GetQuestRewardStatus(at->requiredQuestHeroic))
|
||||
{
|
||||
miscRequirement = at->requiredQuestHeroic;
|
||||
return AREA_LOCKSTATUS_QUEST_NOT_COMPLETED;
|
||||
}
|
||||
|
||||
// If the map is not created, assume it is possible to enter it.
|
||||
DungeonPersistentState* state = GetBoundInstanceSaveForSelfOrGroup(at->target_mapId);
|
||||
Map* map = sMapMgr.FindMap(at->target_mapId, state ? state->GetInstanceId() : 0);
|
||||
|
||||
// ToDo add achievement check
|
||||
|
||||
// Map's state check
|
||||
if (map && map->IsDungeon())
|
||||
{
|
||||
// cannot enter if the instance is full (player cap), GMs don't count
|
||||
if (((DungeonMap*)map)->GetPlayersCountExceptGMs() >= ((DungeonMap*)map)->GetMaxPlayers())
|
||||
return AREA_LOCKSTATUS_INSTANCE_IS_FULL;
|
||||
|
||||
// In Combat check
|
||||
if (map && map->GetInstanceData() && map->GetInstanceData()->IsEncounterInProgress())
|
||||
return AREA_LOCKSTATUS_ZONE_IN_COMBAT;
|
||||
|
||||
// Bind Checks
|
||||
InstancePlayerBind* pBind = GetBoundInstance(at->target_mapId, GetDifficulty(mapEntry->IsRaid()));
|
||||
if (pBind && pBind->perm && pBind->state != state)
|
||||
return AREA_LOCKSTATUS_HAS_BIND;
|
||||
if (pBind && pBind->perm && pBind->state != map->GetPersistentState())
|
||||
return AREA_LOCKSTATUS_HAS_BIND;
|
||||
}
|
||||
|
||||
return AREA_LOCKSTATUS_OK;
|
||||
};
|
||||
|
||||
AreaLockStatus Player::GetAreaLockStatus(uint32 mapId, Difficulty difficulty, uint32& miscRequirement)
|
||||
{
|
||||
return GetAreaTriggerLockStatus(sObjectMgr.GetMapEntranceTrigger(mapId), difficulty, miscRequirement);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue