DarkflameServer/dGame/dComponents/PropertyManagementComponent.cpp
David Markowitz f0b6ad89d9
chore: Player class removal (#1445)
* SystemAddress and destructor

* move respawn logic to character comp

Tested that respawn pos and rot can be set as per previously by crossing a respawn point and smashing to see if I would respawn at the new place.

* Move loot cheat checking

* Remove GetParentUser overload

Tested completing missions
control behaviors
collecting life crate
completing a bunch of missions using macros
loading into worlds
brick-by-brick
placing models
digging the x spot in gnarled forest
can still ban and mute players
cheat detection is still doing its thing
flags are still set (checked with flag 45)
claim codes still work (created new char, checked the lego club mail was there)

* Move player constructor logic

Its now at the bottom of Entity constructor.  Time to remove Player

* Remove Player class

Removes the Player class.  Tested that I can still login and see another player in Venture Explorer and logging out a few times still works as well as smashing enemies

* store ptr

* Update SlashCommandHandler.cpp
2024-02-04 06:29:05 -08:00

752 lines
22 KiB
C++

#include "PropertyManagementComponent.h"
#include <sstream>
#include "MissionComponent.h"
#include "EntityManager.h"
#include "PropertyDataMessage.h"
#include "UserManager.h"
#include "GameMessages.h"
#include "Character.h"
#include "CDClientDatabase.h"
#include "dZoneManager.h"
#include "Game.h"
#include "Item.h"
#include "Database.h"
#include "ObjectIDManager.h"
#include "RocketLaunchpadControlComponent.h"
#include "PropertyEntranceComponent.h"
#include "InventoryComponent.h"
#include "eMissionTaskType.h"
#include "eObjectBits.h"
#include "CharacterComponent.h"
#include "PlayerManager.h"
#include <vector>
#include "CppScripts.h"
PropertyManagementComponent* PropertyManagementComponent::instance = nullptr;
PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Component(parent) {
this->owner = LWOOBJID_EMPTY;
this->templateId = 0;
this->propertyId = LWOOBJID_EMPTY;
this->models = {};
this->propertyName = "";
this->propertyDescription = "";
this->privacyOption = PropertyPrivacyOption::Private;
this->originalPrivacyOption = PropertyPrivacyOption::Private;
instance = this;
const auto& worldId = Game::zoneManager->GetZone()->GetZoneID();
const auto zoneId = worldId.GetMapID();
const auto cloneId = worldId.GetCloneID();
auto query = CDClientDatabase::CreatePreppedStmt("SELECT id FROM PropertyTemplate WHERE mapID = ?;");
query.bind(1, static_cast<int32_t>(zoneId));
auto result = query.execQuery();
if (result.eof() || result.fieldIsNull(0)) {
return;
}
templateId = result.getIntField(0);
auto propertyInfo = Database::Get()->GetPropertyInfo(zoneId, cloneId);
if (propertyInfo) {
this->propertyId = propertyInfo->id;
this->owner = propertyInfo->ownerId;
GeneralUtils::SetBit(this->owner, eObjectBits::CHARACTER);
GeneralUtils::SetBit(this->owner, eObjectBits::PERSISTENT);
this->clone_Id = propertyInfo->cloneId;
this->propertyName = propertyInfo->name;
this->propertyDescription = propertyInfo->description;
this->privacyOption = static_cast<PropertyPrivacyOption>(propertyInfo->privacyOption);
this->rejectionReason = propertyInfo->rejectionReason;
this->moderatorRequested = propertyInfo->modApproved == 0 && rejectionReason == "" && privacyOption == PropertyPrivacyOption::Public;
this->LastUpdatedTime = propertyInfo->lastUpdatedTime;
this->claimedTime = propertyInfo->claimedTime;
this->reputation = propertyInfo->reputation;
Load();
}
}
LWOOBJID PropertyManagementComponent::GetOwnerId() const {
return owner;
}
Entity* PropertyManagementComponent::GetOwner() const {
return Game::entityManager->GetEntity(owner);
}
void PropertyManagementComponent::SetOwner(Entity* value) {
owner = value->GetObjectID();
}
std::vector<NiPoint3> PropertyManagementComponent::GetPaths() const {
const auto zoneId = Game::zoneManager->GetZone()->GetWorldID();
auto query = CDClientDatabase::CreatePreppedStmt(
"SELECT path FROM PropertyTemplate WHERE mapID = ?;");
query.bind(1, static_cast<int>(zoneId));
auto result = query.execQuery();
std::vector<NiPoint3> paths{};
if (result.eof()) {
return paths;
}
std::vector<float> points;
std::istringstream stream(result.getStringField(0));
std::string token;
while (std::getline(stream, token, ' ')) {
try {
auto value = std::stof(token);
points.push_back(value);
} catch (std::invalid_argument& exception) {
LOG("Failed to parse value (%s): (%s)!", token.c_str(), exception.what());
}
}
for (auto i = 0u; i < points.size(); i += 3) {
paths.emplace_back(points[i], points[i + 1], points[i + 2]);
}
return paths;
}
PropertyPrivacyOption PropertyManagementComponent::GetPrivacyOption() const {
return privacyOption;
}
void PropertyManagementComponent::SetPrivacyOption(PropertyPrivacyOption value) {
if (owner == LWOOBJID_EMPTY) return;
if (value == static_cast<PropertyPrivacyOption>(3)) // Client sends 3 for private for some reason, but expects 0 in return?
{
value = PropertyPrivacyOption::Private;
}
if (value == PropertyPrivacyOption::Public && privacyOption != PropertyPrivacyOption::Public) {
rejectionReason = "";
moderatorRequested = true;
}
privacyOption = value;
IProperty::Info info;
info.id = propertyId;
info.privacyOption = static_cast<uint32_t>(privacyOption);
info.rejectionReason = rejectionReason;
info.modApproved = 0;
Database::Get()->UpdatePropertyModerationInfo(info);
}
void PropertyManagementComponent::UpdatePropertyDetails(std::string name, std::string description) {
if (owner == LWOOBJID_EMPTY) return;
propertyName = name;
propertyDescription = description;
IProperty::Info info;
info.id = propertyId;
info.name = propertyName;
info.description = propertyDescription;
Database::Get()->UpdatePropertyDetails(info);
OnQueryPropertyData(GetOwner(), UNASSIGNED_SYSTEM_ADDRESS);
}
bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
if (owner != LWOOBJID_EMPTY) {
return false;
}
auto* entity = Game::entityManager->GetEntity(playerId);
auto character = entity->GetCharacter();
if (!character) return false;
auto* zone = Game::zoneManager->GetZone();
const auto& worldId = zone->GetZoneID();
const auto propertyZoneId = worldId.GetMapID();
const auto propertyCloneId = worldId.GetCloneID();
const auto playerCloneId = character->GetPropertyCloneID();
// If we are not on our clone do not allow us to claim the property
if (propertyCloneId != playerCloneId) return false;
std::string name = zone->GetZoneName();
std::string description = "";
auto prop_path = zone->GetPath(m_Parent->GetVarAsString(u"propertyName"));
if (prop_path){
if (!prop_path->property.displayName.empty()) name = prop_path->property.displayName;
description = prop_path->property.displayDesc;
}
SetOwnerId(playerId);
propertyId = ObjectIDManager::GenerateRandomObjectID();
IProperty::Info info;
info.id = propertyId;
info.ownerId = character->GetID();
info.cloneId = playerCloneId;
info.name = name;
info.description = description;
Database::Get()->InsertNewProperty(info, templateId, worldId);
auto* zoneControlObject = Game::zoneManager->GetZoneControlObject();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControlObject)) {
script->OnZonePropertyRented(zoneControlObject, entity);
}
return true;
}
void PropertyManagementComponent::OnStartBuilding() {
auto* ownerEntity = GetOwner();
if (ownerEntity == nullptr) return;
const auto players = PlayerManager::GetAllPlayers();
LWOMAPID zoneId = 1100;
const auto entrance = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE);
originalPrivacyOption = privacyOption;
SetPrivacyOption(PropertyPrivacyOption::Private); // Cant visit player which is building
if (!entrance.empty()) {
auto* rocketPad = entrance[0]->GetComponent<RocketLaunchpadControlComponent>();
if (rocketPad != nullptr) {
zoneId = rocketPad->GetDefaultZone();
}
}
for (auto* player : players) {
if (player == ownerEntity) continue;
auto* characterComponent = player->GetComponent<CharacterComponent>();
if (characterComponent) characterComponent->SendToZone(zoneId);
}
auto inventoryComponent = ownerEntity->GetComponent<InventoryComponent>();
// Push equipped items
if (inventoryComponent) inventoryComponent->PushEquippedItems();
}
void PropertyManagementComponent::OnFinishBuilding() {
auto* ownerEntity = GetOwner();
if (ownerEntity == nullptr) return;
SetPrivacyOption(originalPrivacyOption);
UpdateApprovedStatus(false);
Save();
}
void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const NiPoint3 position, NiQuaternion rotation) {
LOG("Placing model <%f, %f, %f>", position.x, position.y, position.z);
auto* entity = GetOwner();
if (entity == nullptr) {
return;
}
auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
if (inventoryComponent == nullptr) {
return;
}
auto* item = inventoryComponent->FindItemById(id);
if (item == nullptr) {
LOG("Failed to find item with id %d", id);
return;
}
NiQuaternion originalRotation = rotation;
const auto modelLOT = item->GetLot();
if (rotation != NiQuaternionConstant::IDENTITY) {
rotation = { rotation.w, rotation.z, rotation.y, rotation.x };
}
if (item->GetLot() == 6662) {
LWOOBJID spawnerID = item->GetSubKey();
EntityInfo info;
info.lot = 14;
info.pos = {};
info.rot = {};
info.spawner = nullptr;
info.spawnerID = spawnerID;
info.spawnerNodeID = 0;
for (auto* setting : item->GetConfig()) {
info.settings.push_back(setting->Copy());
}
Entity* newEntity = Game::entityManager->CreateEntity(info);
if (newEntity != nullptr) {
Game::entityManager->ConstructEntity(newEntity);
// Make sure the propMgmt doesn't delete our model after the server dies
// Trying to do this after the entity is constructed. Shouldn't really change anything but
// There was an issue with builds not appearing since it was placed above ConstructEntity.
PropertyManagementComponent::Instance()->AddModel(newEntity->GetObjectID(), spawnerID);
}
item->SetCount(item->GetCount() - 1);
return;
}
item->SetCount(item->GetCount() - 1);
auto* node = new SpawnerNode();
node->position = position;
node->rotation = rotation;
ObjectIDManager::RequestPersistentID([this, node, modelLOT, entity, position, rotation, originalRotation](uint32_t persistentId) {
SpawnerInfo info{};
info.templateID = modelLOT;
info.nodes = { node };
info.templateScale = 1.0f;
info.activeOnLoad = true;
info.amountMaintained = 1;
info.respawnTime = 10;
info.emulated = true;
info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID();
info.spawnerID = persistentId;
GeneralUtils::SetBit(info.spawnerID, eObjectBits::CLIENT);
const auto spawnerId = Game::zoneManager->MakeSpawner(info);
auto* spawner = Game::zoneManager->GetSpawner(spawnerId);
auto ldfModelBehavior = new LDFData<LWOOBJID>(u"modelBehaviors", 0);
auto userModelID = new LDFData<LWOOBJID>(u"userModelID", info.spawnerID);
auto modelType = new LDFData<int>(u"modelType", 2);
auto propertyObjectID = new LDFData<bool>(u"propertyObjectID", true);
auto componentWhitelist = new LDFData<int>(u"componentWhitelist", 1);
info.nodes[0]->config.push_back(componentWhitelist);
info.nodes[0]->config.push_back(ldfModelBehavior);
info.nodes[0]->config.push_back(modelType);
info.nodes[0]->config.push_back(propertyObjectID);
info.nodes[0]->config.push_back(userModelID);
auto* model = spawner->Spawn();
models.insert_or_assign(model->GetObjectID(), spawnerId);
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), position, m_Parent->GetObjectID(), 14, originalRotation);
GameMessages::SendUGCEquipPreCreateBasedOnEditMode(entity->GetObjectID(), entity->GetSystemAddress(), 0, spawnerId);
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity);
});
// Progress place model missions
auto missionComponent = entity->GetComponent<MissionComponent>();
if (missionComponent != nullptr) missionComponent->Progress(eMissionTaskType::PLACE_MODEL, 0);
}
void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int deleteReason) {
LOG("Delete model: (%llu) (%i)", id, deleteReason);
auto* entity = GetOwner();
if (entity == nullptr) {
return;
}
auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
if (inventoryComponent == nullptr) {
return;
}
auto* model = Game::entityManager->GetEntity(id);
if (model == nullptr) {
LOG("Failed to find model entity");
return;
}
if (model->GetLOT() == 14 && deleteReason == 0) {
LOG("User is trying to pick up a BBB model, but this is not implemented, so we return to prevent the user from losing the model");
GameMessages::SendUGCEquipPostDeleteBasedOnEditMode(entity->GetObjectID(), entity->GetSystemAddress(), LWOOBJID_EMPTY, 0);
// Need this to pop the user out of their current state
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), entity->GetPosition(), m_Parent->GetObjectID(), 14, entity->GetRotation());
return;
}
const auto index = models.find(id);
if (index == models.end()) {
LOG("Failed to find model");
return;
}
const auto spawnerId = index->second;
auto* spawner = Game::zoneManager->GetSpawner(spawnerId);
models.erase(id);
if (spawner == nullptr) {
LOG("Failed to find spawner");
}
Game::entityManager->DestructEntity(model);
LOG("Deleting model LOT %i", model->GetLOT());
if (model->GetLOT() == 14) {
//add it to the inv
std::vector<LDFBaseData*> settings;
//fill our settings with BBB gurbage
LDFBaseData* ldfBlueprintID = new LDFData<LWOOBJID>(u"blueprintid", model->GetVar<LWOOBJID>(u"blueprintid"));
LDFBaseData* userModelDesc = new LDFData<std::u16string>(u"userModelDesc", u"A cool model you made!");
LDFBaseData* userModelHasBhvr = new LDFData<bool>(u"userModelHasBhvr", false);
LDFBaseData* userModelID = new LDFData<LWOOBJID>(u"userModelID", model->GetVar<LWOOBJID>(u"userModelID"));
LDFBaseData* userModelMod = new LDFData<bool>(u"userModelMod", false);
LDFBaseData* userModelName = new LDFData<std::u16string>(u"userModelName", u"My Cool Model");
LDFBaseData* propertyObjectID = new LDFData<bool>(u"userModelOpt", true);
LDFBaseData* modelType = new LDFData<int>(u"userModelPhysicsType", 2);
settings.push_back(ldfBlueprintID);
settings.push_back(userModelDesc);
settings.push_back(userModelHasBhvr);
settings.push_back(userModelID);
settings.push_back(userModelMod);
settings.push_back(userModelName);
settings.push_back(propertyObjectID);
settings.push_back(modelType);
inventoryComponent->AddItem(6662, 1, eLootSourceType::DELETION, eInventoryType::MODELS_IN_BBB, settings, LWOOBJID_EMPTY, false, false, spawnerId);
auto* item = inventoryComponent->FindItemBySubKey(spawnerId);
if (item == nullptr) {
return;
}
if (deleteReason == 0) {
//item->Equip();
}
if (deleteReason == 0 || deleteReason == 2) {
GameMessages::SendUGCEquipPostDeleteBasedOnEditMode(entity->GetObjectID(), entity->GetSystemAddress(), item->GetId(), item->GetCount());
}
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, NiQuaternionConstant::IDENTITY);
if (spawner != nullptr) {
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);
} else {
model->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
}
item->SetCount(0, true, false, false);
return;
}
inventoryComponent->AddItem(model->GetLOT(), 1, eLootSourceType::DELETION, INVALID, {}, LWOOBJID_EMPTY, false);
auto* item = inventoryComponent->FindItemByLot(model->GetLOT());
if (item == nullptr) {
return;
}
switch (deleteReason) {
case 0: // Pickup
{
item->Equip();
GameMessages::SendUGCEquipPostDeleteBasedOnEditMode(entity->GetObjectID(), entity->GetSystemAddress(), item->GetId(), item->GetCount());
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPickedUp(entity);
break;
}
case 1: // Return to inv
{
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRemoved(entity);
break;
}
case 2: // Break apart
{
item->SetCount(item->GetCount() - 1);
LOG("DLU currently does not support breaking apart brick by brick models.");
break;
}
default:
{
LOG("Invalid delete reason");
}
}
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, NiQuaternionConstant::IDENTITY);
if (spawner != nullptr) {
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);
} else {
model->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
}
}
void PropertyManagementComponent::UpdateApprovedStatus(const bool value) {
if (owner == LWOOBJID_EMPTY) return;
IProperty::Info info;
info.id = propertyId;
info.modApproved = value;
info.privacyOption = static_cast<uint32_t>(privacyOption);
info.rejectionReason = "";
Database::Get()->UpdatePropertyModerationInfo(info);
}
void PropertyManagementComponent::Load() {
if (propertyId == LWOOBJID_EMPTY) {
return;
}
auto propertyModels = Database::Get()->GetPropertyModels(propertyId);
for (const auto& databaseModel : propertyModels) {
auto* node = new SpawnerNode();
node->position = databaseModel.position;
node->rotation = databaseModel.rotation;
SpawnerInfo info{};
info.templateID = databaseModel.lot;
info.nodes = { node };
info.templateScale = 1.0f;
info.activeOnLoad = true;
info.amountMaintained = 1;
info.respawnTime = 10;
//info.emulated = true;
//info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID();
info.spawnerID = databaseModel.id;
std::vector<LDFBaseData*> settings;
//BBB property models need to have extra stuff set for them:
if (databaseModel.lot == 14) {
LWOOBJID blueprintID = databaseModel.ugcId;
GeneralUtils::SetBit(blueprintID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT);
LDFBaseData* ldfBlueprintID = new LDFData<LWOOBJID>(u"blueprintid", blueprintID);
LDFBaseData* componentWhitelist = new LDFData<int>(u"componentWhitelist", 1);
LDFBaseData* modelType = new LDFData<int>(u"modelType", 2);
LDFBaseData* propertyObjectID = new LDFData<bool>(u"propertyObjectID", true);
LDFBaseData* userModelID = new LDFData<LWOOBJID>(u"userModelID", databaseModel.id);
settings.push_back(ldfBlueprintID);
settings.push_back(componentWhitelist);
settings.push_back(modelType);
settings.push_back(propertyObjectID);
settings.push_back(userModelID);
} else {
auto modelType = new LDFData<int>(u"modelType", 2);
auto userModelID = new LDFData<LWOOBJID>(u"userModelID", databaseModel.id);
auto ldfModelBehavior = new LDFData<LWOOBJID>(u"modelBehaviors", 0);
auto propertyObjectID = new LDFData<bool>(u"propertyObjectID", true);
auto componentWhitelist = new LDFData<int>(u"componentWhitelist", 1);
settings.push_back(componentWhitelist);
settings.push_back(ldfModelBehavior);
settings.push_back(modelType);
settings.push_back(propertyObjectID);
settings.push_back(userModelID);
}
node->config = settings;
const auto spawnerId = Game::zoneManager->MakeSpawner(info);
auto* spawner = Game::zoneManager->GetSpawner(spawnerId);
auto* model = spawner->Spawn();
models.insert_or_assign(model->GetObjectID(), spawnerId);
}
}
void PropertyManagementComponent::Save() {
if (propertyId == LWOOBJID_EMPTY) {
return;
}
auto present = Database::Get()->GetPropertyModels(propertyId);
std::vector<LWOOBJID> modelIds;
for (const auto& pair : models) {
const auto id = pair.second;
modelIds.push_back(id);
auto* entity = Game::entityManager->GetEntity(pair.first);
if (entity == nullptr) {
continue;
}
const auto position = entity->GetPosition();
const auto rotation = entity->GetRotation();
if (std::find(present.begin(), present.end(), id) == present.end()) {
IPropertyContents::Model model;
model.id = id;
model.lot = entity->GetLOT();
model.position = position;
model.rotation = rotation;
model.ugcId = 0;
Database::Get()->InsertNewPropertyModel(propertyId, model, "Objects_" + std::to_string(model.lot) + "_name");
} else {
Database::Get()->UpdateModelPositionRotation(id, position, rotation);
}
}
for (auto model : present) {
if (std::find(modelIds.begin(), modelIds.end(), model.id) != modelIds.end()) {
continue;
}
Database::Get()->RemoveModel(model.id);
}
}
void PropertyManagementComponent::AddModel(LWOOBJID modelId, LWOOBJID spawnerId) {
models[modelId] = spawnerId;
}
PropertyManagementComponent* PropertyManagementComponent::Instance() {
return instance;
}
void PropertyManagementComponent::OnQueryPropertyData(Entity* originator, const SystemAddress& sysAddr, LWOOBJID author) {
if (author == LWOOBJID_EMPTY) {
author = m_Parent->GetObjectID();
}
const auto& worldId = Game::zoneManager->GetZone()->GetZoneID();
const auto zoneId = worldId.GetMapID();
const auto cloneId = worldId.GetCloneID();
LOG("Getting property info for %d", zoneId);
GameMessages::PropertyDataMessage message = GameMessages::PropertyDataMessage(zoneId);
const auto isClaimed = GetOwnerId() != LWOOBJID_EMPTY;
LWOOBJID ownerId = GetOwnerId();
std::string ownerName;
auto charInfo = Database::Get()->GetCharacterInfo(ownerId);
if (charInfo) ownerName = charInfo->name;
std::string name = "";
std::string description = "";
uint64_t claimed = 0;
char privacy = 0;
if (isClaimed) {
name = propertyName;
description = propertyDescription;
claimed = claimedTime;
privacy = static_cast<char>(this->privacyOption);
if (moderatorRequested) {
auto moderationInfo = Database::Get()->GetPropertyInfo(zoneId, cloneId);
if (moderationInfo->rejectionReason != "") {
moderatorRequested = false;
rejectionReason = moderationInfo->rejectionReason;
} else if (moderationInfo->rejectionReason == "" && moderationInfo->modApproved == 1) {
moderatorRequested = false;
rejectionReason = "";
} else {
moderatorRequested = true;
rejectionReason = "";
}
}
}
message.moderatorRequested = moderatorRequested;
message.reputation = reputation;
message.LastUpdatedTime = LastUpdatedTime;
message.OwnerId = ownerId;
message.OwnerName = ownerName;
message.Name = name;
message.Description = description;
message.ClaimedTime = claimed;
message.PrivacyOption = privacy;
message.cloneId = clone_Id;
message.rejectionReason = rejectionReason;
message.Paths = GetPaths();
SendDownloadPropertyData(author, message, UNASSIGNED_SYSTEM_ADDRESS);
// send rejection here?
}
void PropertyManagementComponent::OnUse(Entity* originator) {
OnQueryPropertyData(originator, UNASSIGNED_SYSTEM_ADDRESS);
GameMessages::SendOpenPropertyManagment(m_Parent->GetObjectID(), originator->GetSystemAddress());
}
void PropertyManagementComponent::SetOwnerId(const LWOOBJID value) {
owner = value;
}
const std::map<LWOOBJID, LWOOBJID>& PropertyManagementComponent::GetModels() const {
return models;
}