From 1b8f10fcfb89d2353838247cb2c9a1fd7ec10d2b Mon Sep 17 00:00:00 2001 From: jadebenn Date: Thu, 14 Dec 2023 01:33:49 -0600 Subject: [PATCH] added treasure dig menu prompts and help messages --- dCommon/dEnums/eHelpType.h | 6 +- dCommon/dEnums/ePetAbilityType.h | 10 ++ dGame/dComponents/BaseCombatAIComponent.h | 5 +- dGame/dComponents/PetComponent.cpp | 120 ++++++++++++------ dGame/dComponents/PetComponent.h | 40 +++--- dGame/dGameMessages/GameMessages.cpp | 17 ++- dGame/dGameMessages/GameMessages.h | 10 +- .../02_server/Map/General/PetDigServer.cpp | 14 +- dZoneManager/dZoneManager.cpp | 4 + dZoneManager/dZoneManager.h | 1 + 10 files changed, 145 insertions(+), 82 deletions(-) create mode 100644 dCommon/dEnums/ePetAbilityType.h diff --git a/dCommon/dEnums/eHelpType.h b/dCommon/dEnums/eHelpType.h index d1838cc6..94f584e6 100644 --- a/dCommon/dEnums/eHelpType.h +++ b/dCommon/dEnums/eHelpType.h @@ -1,6 +1,4 @@ - -#ifndef __EHELPTYPE__H__ -#define __EHELPTYPE__H__ +#pragma once #include @@ -37,5 +35,3 @@ enum class eHelpType : int32_t { PET_DESPAWN_TAMING_NEW_PET = 70, UI_INVENTORY_FULL_CANNOT_PICKUP_ITEM = 86 }; - -#endif //!__EHELPTYPE__H__ diff --git a/dCommon/dEnums/ePetAbilityType.h b/dCommon/dEnums/ePetAbilityType.h new file mode 100644 index 00000000..70cf75c6 --- /dev/null +++ b/dCommon/dEnums/ePetAbilityType.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +enum class ePetAbilityType : int32_t { + Invalid, + GoToObject, + JumpOnObject, + DigAtPosition +}; diff --git a/dGame/dComponents/BaseCombatAIComponent.h b/dGame/dComponents/BaseCombatAIComponent.h index a08b008e..f85fa70f 100644 --- a/dGame/dComponents/BaseCombatAIComponent.h +++ b/dGame/dComponents/BaseCombatAIComponent.h @@ -1,5 +1,4 @@ -#ifndef BASECOMBATAICOMPONENT_H -#define BASECOMBATAICOMPONENT_H +#pragma once #include "RakNetTypes.h" #include "dCommonVars.h" @@ -388,5 +387,3 @@ private: */ bool IsMech(); }; - -#endif // BASECOMBATAICOMPONENT_H diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index f3ba71d9..f504da6f 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -17,12 +17,15 @@ #include "eUnequippableActiveType.h" #include "eTerminateType.h" #include "ePetTamingNotifyType.h" +#include "ePetAbilityType.h" #include "eUseItemResponse.h" #include "ePlayerFlag.h" +#include "eHelpType.h" #include "Game.h" #include "dConfig.h" #include "dChatFilter.h" +#include "dZoneManager.h" #include "Database.h" #include "EntityInfo.h" #include "eMissionTaskType.h" @@ -34,6 +37,7 @@ std::unordered_map PetComponent::buildCache{}; std::unordered_map PetComponent::currentActivities{}; std::unordered_map PetComponent::activePets{}; +float PetComponent::m_FollowRadius{}; /** * Maps all the pet lots to a flag indicating that the player has caught it. All basic pets have been guessed by ObjID @@ -83,14 +87,15 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare m_TimerBounce = 0; m_DatabaseId = LWOOBJID_EMPTY; m_Status = PetStatus::TAMEABLE; // Tameable - m_Ability = PetAbilityType::Invalid; + m_Ability = ePetAbilityType::Invalid; m_StartPosition = m_Parent->GetPosition(); //NiPoint3::ZERO; m_MovementAI = nullptr; m_Preconditions = nullptr; m_ReadyToInteract = false; SetPetAiState(PetAiState::spawn); - //m_FollowRadius = 8.0f; + m_FollowRadius = Game::zoneManager->GetPetFollowRadius(); + SetIsHandlingInteraction(false); std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parent->GetVar(u"CheckPrecondition")); @@ -121,7 +126,7 @@ void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpd outBitStream->Write1(); // Always serialize as dirty for now outBitStream->Write(static_cast(m_Status)); - outBitStream->Write(static_cast(tamed ? m_Ability : PetAbilityType::Invalid)); // Something with the overhead icon? + outBitStream->Write(static_cast(tamed ? m_Ability : ePetAbilityType::Invalid)); // Something with the overhead icon? const bool interacting = m_Interaction != LWOOBJID_EMPTY; @@ -164,6 +169,23 @@ void PetComponent::SetPetAiState(PetAiState newState) { void PetComponent::OnUse(Entity* originator) { LOG("PET USE!"); + if (IsReadyToInteract()) { + switch (GetAbility()) { + case ePetAbilityType::DigAtPosition: // Treasure dig TODO: FIX ICON + StartInteractTreasureDig(); + break; + + case ePetAbilityType::JumpOnObject: // Bouncer + //StartInteractBouncer(); + break; + + default: + break; + } + } + + // TODO: Rewrite everything below this comment + if (m_Owner != LWOOBJID_EMPTY) return; if (m_Tamer != LWOOBJID_EMPTY) { @@ -526,10 +548,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { GameMessages::SendPetResponse(m_Tamer, m_Parent->GetObjectID(), 0, 10, 0, tamer->GetSystemAddress()); auto* inventoryComponent = tamer->GetComponent(); - - if (inventoryComponent == nullptr) { - return; - } + if (!inventoryComponent) return; LWOOBJID petSubKey = ObjectIDManager::Instance()->GenerateRandomObjectID(); @@ -548,11 +567,9 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { GameMessages::SendRegisterPetDBID(m_Tamer, petSubKey, tamer->GetSystemAddress()); inventoryComponent->AddItem(m_Parent->GetLOT(), 1, eLootSourceType::ACTIVITY, eInventoryType::MODELS, {}, LWOOBJID_EMPTY, true, false, petSubKey); + auto* item = inventoryComponent->FindItemBySubKey(petSubKey, MODELS); - - if (item == nullptr) { - return; - } + if (!item) return; DatabasePet databasePet{}; @@ -626,10 +643,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { LOG("Got set pet name (%s)", GeneralUtils::UTF16ToWTF8(name).c_str()); auto* inventoryComponent = tamer->GetComponent(); - - if (inventoryComponent == nullptr) { - return; - } + if (!inventoryComponent) return; m_ModerationStatus = 1; // Pending m_Name = ""; @@ -769,9 +783,7 @@ void PetComponent::ClientFailTamingMinigame() { } void PetComponent::Wander() { - //m_MovementAI = m_Parent->GetComponent(); - - if (/*m_MovementAI == nullptr ||*/ !m_MovementAI->AtFinalWaypoint()) return; + if (!m_MovementAI->AtFinalWaypoint()) return; m_MovementAI->SetHaltDistance(0); @@ -916,7 +928,7 @@ void PetComponent::OnInteract() { void PetComponent::StartInteract(const NiPoint3 position, const PetInteractType interactType, const LWOOBJID interactID) { SetInteraction(interactID); // TODO: Check if this should be serialized for goToObj SetInteractType(interactType); - SetAbility(PetAbilityType::GoToObject); + SetAbility(ePetAbilityType::GoToObject); SetPetAiState(PetAiState::goToObj); m_MovementAI->SetMaxSpeed(m_RunSpeed); m_MovementAI->SetHaltDistance(0.0f); @@ -926,21 +938,28 @@ void PetComponent::StartInteract(const NiPoint3 position, const PetInteractType } void PetComponent::StopInteract() { + Entity* owner = GetOwner(); + if (!owner) return; + const auto petAbility = ePetAbilityType::Invalid; + SetInteraction(LWOOBJID_EMPTY); SetInteractType(PetInteractType::none); - SetAbility(PetAbilityType::Invalid); + SetAbility(petAbility); SetPetAiState(PetAiState::follow); SetStatus(PetStatus::NONE); SetIsReadyToInteract(false); + SetIsHandlingInteraction(false); // Needed? m_MovementAI->SetMaxSpeed(m_SprintSpeed); m_MovementAI->SetHaltDistance(m_FollowRadius); LOG_DEBUG("Stopping interaction!"); + Game::entityManager->SerializeEntity(m_Parent); + GameMessages::SendShowPetActionButton(m_Owner, petAbility, false, owner->GetSystemAddress()); // Needed? } void PetComponent::SetupInteractBouncer() { // THIS IS ALL BAD, BAD, BAD! FIX IT, ME! >:( - /*SetAbility(PetAbilityType::JumpOnObject); + /*SetAbility(ePetAbilityType::JumpOnObject); NiPoint3 destination = m_MovementAI->GetDestination(); SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(destination); m_Interaction = closestSwitch->GetParentEntity()->GetObjectID(); @@ -949,37 +968,63 @@ void PetComponent::SetupInteractBouncer() { } void PetComponent::SetupInteractTreasureDig() { + auto* owner = GetOwner(); + if (!owner) return; + LOG_DEBUG("Setting up dig interaction!"); - Entity* closestTreasure = Game::entityManager->GetEntity(GetInteraction()); - if (!closestTreasure) return; - SetIsReadyToInteract(true); + auto petAbility = ePetAbilityType::DigAtPosition; - SetAbility(PetAbilityType::JumpOnObject); + SetAbility(petAbility); SetStatus(PetStatus::IS_NOT_WAITING); // TODO: Double-check this is the right flag being set Game::entityManager->SerializeEntity(m_Parent); // TODO: Double-check pet packet captures + + const auto sysAddr = owner->GetSystemAddress(); + GameMessages::SendHelp(m_Owner, eHelpType::PR_DIG_TUTORIAL_01, sysAddr); + GameMessages::SendShowPetActionButton(m_Owner, petAbility, true, sysAddr); m_Timer += 0.5f; } void PetComponent::StartInteractTreasureDig() { - SetAbility(PetAbilityType::DigAtPosition); + Entity* user = GetOwner(); + if (IsHandlingInteraction() || !user) return; + + auto* destroyableComponent = user->GetComponent(); + if (!destroyableComponent) return; + + auto imagination = destroyableComponent->GetImagination(); + int32_t imaginationCost = 1; // TODO: Get rid of this magic number - make static variable from lookup + if (imagination < imaginationCost) { + //GameMessages::SendHelp(user->GetObjectID(), eHelpType::PR_NEED_IMAGINATION, user->GetSystemAddress()); // Check if right message! + return; + } + + GameMessages::SendShowPetActionButton(m_Owner, ePetAbilityType::Invalid, false, user->GetSystemAddress()); + + imagination -= imaginationCost; + destroyableComponent->SetImagination(imagination); + Game::entityManager->SerializeEntity(user); + + SetIsHandlingInteraction(true); + auto newStatus = GeneralUtils::ClearBit(GetStatus(), 6); + SetStatus(newStatus); // TODO: FIND THE CORRECT STATUS TO USE HERE Game::entityManager->SerializeEntity(m_Parent); Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::DigTreasure, true); // Plays 'dig' animation - m_Timer = 1.5f; + m_Timer = 2.0f; } void PetComponent::HandleInteractTreasureDig() { - if (GetAbility() == PetAbilityType::DigAtPosition) { + if (IsHandlingInteraction()) { auto* owner = GetOwner(); - auto* treasure = Game::entityManager->GetEntity(GetInteraction()); - if (!treasure) return; + if (!treasure || !owner) return; treasure->Smash(m_Parent->GetObjectID()); LOG_DEBUG("Pet dig completed!"); + GameMessages::SendHelp(m_Owner, eHelpType::PR_DIG_TUTORIAL_03, owner->GetSystemAddress()); StopInteract(); //TODO: This may not be totally consistent with live behavior, where the pet seems to stay near the dig and not immediately follow - m_Timer = 1.5f; + //m_Timer = 1.5f; return; } @@ -991,7 +1036,7 @@ void PetComponent::HandleInteractTreasureDig() { m_Timer += 0.5f; } -void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { +void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { // TODO: Offset spawn position so it's not on top of player char AddDrainImaginationTimer(item, fromTaming); m_ItemId = item->GetId(); @@ -1041,8 +1086,6 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { activePets[m_Owner] = m_Parent->GetObjectID(); - //m_Timer = 3; - Game::entityManager->SerializeEntity(m_Parent); owner->GetCharacter()->SetPlayerFlag(ePlayerFlag::FIRST_MANUAL_PET_HIBERNATE, true); @@ -1054,8 +1097,6 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { GameMessages::SendRegisterPetDBID(m_Owner, m_DatabaseId, owner->GetSystemAddress()); } - - GameMessages::SendShowPetActionButton(m_Owner, 3, true, owner->GetSystemAddress()); } void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) { @@ -1115,7 +1156,7 @@ void PetComponent::Deactivate() { GameMessages::SendRegisterPetDBID(m_Owner, LWOOBJID_EMPTY, owner->GetSystemAddress()); - GameMessages::SendShowPetActionButton(m_Owner, 0, false, owner->GetSystemAddress()); + GameMessages::SendShowPetActionButton(m_Owner, ePetAbilityType::Invalid, false, owner->GetSystemAddress()); } void PetComponent::Release() { @@ -1182,7 +1223,7 @@ uint32_t PetComponent::GetStatus() const { return m_Status; } -PetAbilityType PetComponent::GetAbility() const { +ePetAbilityType PetComponent::GetAbility() const { return m_Ability; } @@ -1192,9 +1233,10 @@ void PetComponent::SetInteraction(LWOOBJID value) { void PetComponent::SetStatus(uint32_t value) { m_Status = value; + LOG_DEBUG("Pet status set to: %x", m_Status); } -void PetComponent::SetAbility(PetAbilityType value) { +void PetComponent::SetAbility(ePetAbilityType value) { m_Ability = value; } diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index dcad34c1..12f8813b 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -5,6 +5,7 @@ #include "Component.h" #include "Preconditions.h" #include "eReplicaComponentType.h" +#include "ePetAbilityType.h" /* * The current state of the pet AI @@ -45,13 +46,6 @@ enum PetEmote : int32_t { Bounce }; -enum class PetAbilityType { - Invalid, - GoToObject, - JumpOnObject, - DigAtPosition -}; - /** * Represents an entity that is a pet. This pet can be tamed and consequently follows the tamer around, allowing it * to dig for treasure and activate pet bouncers. @@ -249,13 +243,13 @@ public: * Returns an ability the pet may perform, currently unused * @return an ability the pet may perform */ - PetAbilityType GetAbility() const; + ePetAbilityType GetAbility() const; /** * Sets the ability of the pet, currently unused * @param value the ability to set */ - void SetAbility(PetAbilityType value); + void SetAbility(ePetAbilityType value); /** * Sets preconditions for the pet that need to be met before it can be tamed @@ -274,6 +268,17 @@ public: */ bool IsReadyToInteract() { return m_ReadyToInteract; }; + /** + * Sets if the pet is currently handling an interaction with an object + * @param isHandlingInteraction whether the pet is currently handling an interaction with an object + */ + void SetIsHandlingInteraction(bool isHandlingInteraction) { m_IsHandlingInteraction = isHandlingInteraction; }; + + /** + * @return is pet currently handling an interaction with an object + */ + bool IsHandlingInteraction() { return m_IsHandlingInteraction; }; + /** * Set up the pet bouncer interaction */ @@ -387,6 +392,11 @@ private: */ static std::map petFlags; + /** + * The halting radius of the pet while following a player + */ + static float m_FollowRadius; + /** * The ID of the component in the pet component table */ @@ -455,7 +465,7 @@ private: /** * A currently active ability, mostly unused */ - PetAbilityType m_Ability; + ePetAbilityType m_Ability; /** * The time an entity has left to complete the minigame @@ -477,16 +487,16 @@ private: */ bool m_ReadyToInteract; + /** + * Boolean that sets if a pet is currently handling an interaction with an object + */ + bool m_IsHandlingInteraction; + /** * The position that this pet was spawned at */ NiPoint3 m_StartPosition; - /** - * The halting radius of the pet while following a player - */ - const float m_FollowRadius = 8.0f; - /** * The movement AI component that is related to this pet, required to move it around */ diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index fd174a2b..821f9b6f 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -44,6 +44,8 @@ #include "eStateChangeType.h" #include "eConnectionType.h" #include "ePlayerFlag.h" +#include "eHelpType.h" +#include "ePetAbilityType.h" #include #include @@ -505,6 +507,17 @@ void GameMessages::SendNotifyClientFlagChange(const LWOOBJID& objectID, uint32_t SEND_PACKET; } +void GameMessages::SendHelp(const LWOOBJID& objectID, const eHelpType help, const SystemAddress& sysAddr) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectID); + bitStream.Write(eGameMessageType::HELP); + bitStream.Write(help); + + SEND_PACKET; +} + void GameMessages::SendChangeObjectWorldState(const LWOOBJID& objectID, eObjectWorldState state, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3508,14 +3521,14 @@ void GameMessages::SendClientExitTamingMinigame(LWOOBJID objectId, bool bVolunta SEND_PACKET; } -void GameMessages::SendShowPetActionButton(LWOOBJID objectId, int32_t buttonLabel, bool bShow, const SystemAddress& sysAddr) { +void GameMessages::SendShowPetActionButton(const LWOOBJID& objectId, const ePetAbilityType petAbility, bool bShow, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectId); bitStream.Write(eGameMessageType::SHOW_PET_ACTION_BUTTON); - bitStream.Write(buttonLabel); + bitStream.Write(petAbility); bitStream.Write(bShow); if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 5199a72a..641f4b9a 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -1,5 +1,4 @@ -#ifndef GAMEMESSAGES_H -#define GAMEMESSAGES_H +#pragma once #include "dCommonVars.h" #include @@ -10,6 +9,8 @@ #include "eEndBehavior.h" #include "eCyclingMode.h" #include "eLootSourceType.h" +#include "eHelpType.h" +#include "ePetAbilityType.h" #include "Brick.h" class AMFBaseValue; @@ -81,6 +82,7 @@ namespace GameMessages { void SendAddItemToInventoryClientSync(Entity* entity, const SystemAddress& sysAddr, Item* item, const LWOOBJID& objectID, bool showFlyingLoot, int itemCount, LWOOBJID subKey = LWOOBJID_EMPTY, eLootSourceType lootSourceType = eLootSourceType::NONE); void SendNotifyClientFlagChange(const LWOOBJID& objectID, uint32_t iFlagID, bool bFlag, const SystemAddress& sysAddr); + void SendHelp(const LWOOBJID& objectID, const eHelpType help, const SystemAddress& sysAddr); void SendChangeObjectWorldState(const LWOOBJID& objectID, eObjectWorldState state, const SystemAddress& sysAddr); void SendOfferMission(const LWOOBJID& entity, const SystemAddress& sysAddr, int32_t missionID, const LWOOBJID& offererID); @@ -385,7 +387,7 @@ namespace GameMessages { void SendClientExitTamingMinigame(LWOOBJID objectId, bool bVoluntaryExit, const SystemAddress& sysAddr); - void SendShowPetActionButton(LWOOBJID objectId, int32_t buttonLabel, bool bShow, const SystemAddress& sysAddr); + void SendShowPetActionButton(const LWOOBJID& objectId, const ePetAbilityType petAbility, bool bShow, const SystemAddress& sysAddr); void SendPlayEmote(LWOOBJID objectId, int32_t emoteID, LWOOBJID target, const SystemAddress& sysAddr); @@ -659,5 +661,3 @@ namespace GameMessages { void HandleConfirmDonationOnPlayer(RakNet::BitStream* inStream, Entity* entity); void HandleCancelDonationOnPlayer(RakNet::BitStream* inStream, Entity* entity); }; - -#endif // GAMEMESSAGES_H diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index ffd23cdc..43c00f7f 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -103,23 +103,13 @@ void PetDigServer::OnDie(Entity* self, Entity* killer) { } void PetDigServer::OnUse(Entity* self, Entity* user) { - LOG("Treasure used!"); + LOG_DEBUG("Treasure used! LWOOBJID: %d", self->GetObjectID()); auto* petComponent = PetComponent::GetActivePet(user->GetObjectID()); if (!petComponent) return; - if(petComponent->IsReadyToInteract()) { // TODO: Add handling of the "first time" dig message - auto* destroyableComponent = user->GetComponent(); - if (!destroyableComponent) return; - - auto imagination = destroyableComponent->GetImagination(); - if (imagination == 0) return; // TODO: Check if there was special behavior for this in the live game (PR_NEED_IMAGINATION) - + if(petComponent->IsReadyToInteract()) { petComponent->StartInteractTreasureDig(); - - imagination -= 1; // TODO: Get rid of this magic number - destroyableComponent->SetImagination(imagination); - Game::entityManager->SerializeEntity(user); } } diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 137a9cab..76a8b1fc 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -226,6 +226,10 @@ std::vector dZoneManager::GetSpawnersInGroup(std::string group) { return spawnersInGroup; } +float dZoneManager::GetPetFollowRadius() { + return GetWorldConfig()->petFollowRadius; +} + uint32_t dZoneManager::GetUniqueMissionIdStartingValue() { if (m_UniqueMissionIdStart == 0) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Missions WHERE isMission = 0 GROUP BY isMission;"); diff --git a/dZoneManager/dZoneManager.h b/dZoneManager/dZoneManager.h index b5db3f6e..21ef013a 100644 --- a/dZoneManager/dZoneManager.h +++ b/dZoneManager/dZoneManager.h @@ -44,6 +44,7 @@ public: bool GetDisableSaveLocation() { return m_DisableSaveLocation; } bool GetMountsAllowed() { return m_MountsAllowed; } bool GetPetsAllowed() { return m_PetsAllowed; } + float GetPetFollowRadius(); uint32_t GetUniqueMissionIdStartingValue(); bool CheckIfAccessibleZone(LWOMAPID zoneID);