Skip to content

Commit

Permalink
[core] Fix nation zone/login issues.
Browse files Browse the repository at this point in the history
* Checks for destination region when zoning, to avoid issues with latent effects not triggering
* Fixes log spam for players in these non conquest but still latent applying regions
  • Loading branch information
Radegast-FFXIV authored and xkoredev committed Oct 20, 2023
1 parent b61c149 commit 61b6b36
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
38 changes: 26 additions & 12 deletions src/map/latent_effect_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,13 @@ bool CLatentEffectContainer::ProcessLatentEffect(CLatentEffect& latentEffect)
auto expression = false;
auto latentFound = true;

// this gets the current zone ID or destination zone ID if zoning
uint16 playerZoneID = m_POwner->getZone();
if (m_POwner == nullptr || playerZoneID == 0)
{
return false;
}

// find the latent type from the enum and find the expression to tests againts
switch (latentEffect.GetConditionsID())
{
Expand Down Expand Up @@ -1040,52 +1047,59 @@ bool CLatentEffectContainer::ProcessLatentEffect(CLatentEffect& latentEffect)
case LATENT::NATION_CONTROL:
{
// player is logging in/zoning
if (m_POwner->loc.zone == nullptr)
// checking the state of the user's current zone and
// the destination zone in tandem seems to work.
if (m_POwner->loc.zone == nullptr && static_cast<uint16_t>(m_POwner->loc.destination) == 0)
{
break;
}

auto region = m_POwner->loc.zone->GetRegionID();
// Grab the user's destination if they're zoning.
// Otherwise, grab their current zone.
auto region = m_POwner->loc.zone == nullptr ? zoneutils::GetCurrentRegion(m_POwner->loc.destination) : zoneutils::GetCurrentRegion(playerZoneID);
auto hasSignet = m_POwner->StatusEffectContainer->HasStatusEffect(EFFECT_SIGNET);
auto hasSanction = m_POwner->StatusEffectContainer->HasStatusEffect(EFFECT_SANCTION);
auto hasSigil = m_POwner->StatusEffectContainer->HasStatusEffect(EFFECT_SIGIL);

auto regionAlwaysOutOfControl = zoneutils::IsAlwaysOutOfNationControl(region);
switch (latentEffect.GetConditionsValue())
{
case 0:
// under own nation's control
expression = region < REGION_TYPE::WEST_AHT_URHGAN && conquest::GetRegionOwner(region) == m_POwner->profile.nation &&
expression = region < REGION_TYPE::WEST_AHT_URHGAN && (!regionAlwaysOutOfControl || conquest::GetRegionOwner(region) == m_POwner->profile.nation) &&
(hasSignet || hasSanction || hasSigil);
break;
case 1:
// outside of own nation's control
expression = region < REGION_TYPE::WEST_AHT_URHGAN && m_POwner->profile.nation != conquest::GetRegionOwner(region) &&
expression = region < REGION_TYPE::WEST_AHT_URHGAN && (regionAlwaysOutOfControl || m_POwner->profile.nation != conquest::GetRegionOwner(region)) &&
(hasSignet || hasSanction || hasSigil);
break;
}
break;
}
case LATENT::ZONE_HOME_NATION:
{

// player is logging in/zoning
if (m_POwner->loc.zone == nullptr)
// checking the state of the user's current zone and
// the destination zone in tandem seems to work.
if (m_POwner->loc.zone == nullptr && static_cast<uint16_t>(m_POwner->loc.destination) == 0)
{
break;
}

auto* PZone = m_POwner->loc.zone;
auto region = static_cast<REGION_TYPE>(latentEffect.GetConditionsValue());
auto nationRegion = static_cast<REGION_TYPE>(latentEffect.GetConditionsValue());
auto region = m_POwner->loc.zone == nullptr ? zoneutils::GetCurrentRegion(m_POwner->loc.destination) : zoneutils::GetCurrentRegion(playerZoneID);

switch (region)
switch (nationRegion)
{
case REGION_TYPE::SANDORIA:
expression = m_POwner->profile.nation == 0 && PZone->GetRegionID() == region;
expression = m_POwner->profile.nation == 0 && region == nationRegion;
break;
case REGION_TYPE::BASTOK:
expression = m_POwner->profile.nation == 1 && PZone->GetRegionID() == region;
expression = m_POwner->profile.nation == 1 && region == nationRegion;
break;
case REGION_TYPE::WINDURST:
expression = m_POwner->profile.nation == 2 && PZone->GetRegionID() == region;
expression = m_POwner->profile.nation == 2 && region == nationRegion;
break;
default:
break;
Expand Down
5 changes: 5 additions & 0 deletions src/map/utils/zoneutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1212,4 +1212,9 @@ namespace zoneutils
luautils::AfterZoneIn(PChar);
}

bool IsAlwaysOutOfNationControl(REGION_TYPE region)
{
return region >= REGION_TYPE::SANDORIA && region <= REGION_TYPE::LIMBUS;
}

}; // namespace zoneutils
5 changes: 3 additions & 2 deletions src/map/utils/zoneutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ namespace zoneutils
CCharEntity* GetChar(uint32 id); // returns pointer to character by id
CCharEntity* GetCharToUpdate(uint32 primary, uint32 ternary); // returns pointer to preferred char to update for party changes
void ForEachZone(const std::function<void(CZone*)>& func);
uint64 GetZoneIPP(uint16 zoneid); // returns IPP for zone ID
bool IsResidentialArea(CCharEntity*); // returns whether or not the area is a residential zone
uint64 GetZoneIPP(uint16 zoneid); // returns IPP for zone ID
bool IsResidentialArea(CCharEntity*); // returns whether or not the area is a residential zone
bool IsAlwaysOutOfNationControl(REGION_TYPE region); // returns true if a region should never trigger "in areas outside own nation's control" latent effect; false otherwise.

void AfterZoneIn(CBaseEntity* PEntity); // triggers after a player has finished zoning in

Expand Down

0 comments on commit 61b6b36

Please sign in to comment.