fix: save_property_location saves the position on the property too

The zone was saved on a property but the position wasn't (the physics
component kept its own "not a property" check), so logging back in put the
character at their old main world coordinates on the property map, outside
it. Both now use Character::SavesLocationInThisZone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-28 11:53:48 -05:00
parent 5596f0fa2d
commit 92a87fa735
3 changed files with 14 additions and 7 deletions

View File

@@ -283,11 +283,8 @@ void Character::SaveXMLToDatabase() {
character->SetAttribute("cc", m_Coins);
auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID();
// Where the character logs back in. Not a property (a clone) unless save_property_location is 1: by default
// logging in from a property goes to the last world before it.
const bool savesHere = zoneInfo.GetCloneID() == 0 || (Game::config && Game::config->GetValue("save_property_location") == "1");
// lzid garbage, binary concat of zoneID, zoneInstance and zoneClone
if (zoneInfo.GetMapID() != 0 && savesHere && !Game::zoneManager->GetDisableSaveLocation()) {
if (SavesLocationInThisZone()) {
uint64_t lzidConcat = zoneInfo.GetCloneID();
lzidConcat = (lzidConcat << 16) | uint16_t(zoneInfo.GetInstanceID());
lzidConcat = (lzidConcat << 16) | uint16_t(zoneInfo.GetMapID());
@@ -657,3 +654,10 @@ void Character::SetBillboardVisible(bool visible) {
ownerBillboardState.target = m_OurEntity->GetObjectID();
ownerBillboardState.Send(m_OurEntity->GetSystemAddress());
}
bool Character::SavesLocationInThisZone() {
const auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID();
if (zoneInfo.GetMapID() == 0 || Game::zoneManager->GetDisableSaveLocation()) return false;
// By default logging in from a property goes to the last world before it
return zoneInfo.GetCloneID() == 0 || (Game::config && Game::config->GetValue("save_property_location") == "1");
}

View File

@@ -102,6 +102,11 @@ public:
*/
uint32_t GetPropertyCloneID() const { return m_PropertyCloneID; }
// Whether a character's location (zone and position) is saved in the zone this world runs, for logging back in
// there: not the character select world, nor where the zone says not to, nor a property (a clone) unless
// save_property_location is 1
static bool SavesLocationInThisZone();
/**
* Gets the last login of this character in MS
* @return the last login of this character

View File

@@ -191,9 +191,7 @@ void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
return;
}
auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID();
if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0 && !Game::zoneManager->GetDisableSaveLocation()) {
if (Character::SavesLocationInThisZone()) {
character->SetAttribute("lzx", m_Position.x);
character->SetAttribute("lzy", m_Position.y);
character->SetAttribute("lzz", m_Position.z);