mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-05 18:24:12 +00:00
Mounts v2 (#726)
* Mounts -v2 * fix stun state and make comments a bit nicer * remove extra serilization * update the char position a bit more correctly * make vehicles face thr player's direction * address feedback * fix compiling for real this time * removed uneeded check
This commit is contained in:
@@ -167,18 +167,6 @@ public:
|
||||
*/
|
||||
void SetLastRocketItemID(LWOOBJID lastRocketItemID) { m_LastRocketItemID = lastRocketItemID; }
|
||||
|
||||
/**
|
||||
* Gets the object ID of the mount item that is being used
|
||||
* @return the object ID of the mount item that is being used
|
||||
*/
|
||||
LWOOBJID GetMountItemID() const { return m_MountItemID; }
|
||||
|
||||
/**
|
||||
* Sets the object ID of the mount item that is being used
|
||||
* @param m_MountItemID the object ID of the mount item that is being used
|
||||
*/
|
||||
void SetMountItemID(LWOOBJID mountItemID) { m_MountItemID = mountItemID; }
|
||||
|
||||
/**
|
||||
* Gets the name of this character
|
||||
* @return the name of this character
|
||||
@@ -569,11 +557,6 @@ private:
|
||||
* ID of the last rocket used
|
||||
*/
|
||||
LWOOBJID m_LastRocketItemID = LWOOBJID_EMPTY;
|
||||
|
||||
/**
|
||||
* Mount Item ID
|
||||
*/
|
||||
LWOOBJID m_MountItemID = LWOOBJID_EMPTY;
|
||||
};
|
||||
|
||||
#endif // CHARACTERCOMPONENT_H
|
||||
|
@@ -32,6 +32,7 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Com
|
||||
m_IgnoreMultipliers = false;
|
||||
m_PickupRadius = 0.0f;
|
||||
m_DirtyPickupRadiusScale = true;
|
||||
m_IsTeleporting = false;
|
||||
|
||||
if (entity->GetLOT() != 1) // Other physics entities we care about will be added by BaseCombatAI
|
||||
return;
|
||||
@@ -128,7 +129,10 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bo
|
||||
outBitStream->Write0();
|
||||
}
|
||||
|
||||
if (!bIsInitialUpdate) outBitStream->Write0();
|
||||
if (!bIsInitialUpdate) {
|
||||
outBitStream->Write(m_IsTeleporting);
|
||||
m_IsTeleporting = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
|
||||
|
@@ -220,6 +220,18 @@ public:
|
||||
*/
|
||||
bool GetStatic() const { return m_Static; }
|
||||
|
||||
/**
|
||||
* Sets if the entity is Teleporting,
|
||||
* @param value whether or not the entity is Is Teleporting
|
||||
*/
|
||||
void SetIsTeleporting(const bool value) { m_IsTeleporting = value; }
|
||||
|
||||
/**
|
||||
* Returns whether or not this entity is currently is teleporting
|
||||
* @return whether or not this entity is currently is teleporting
|
||||
*/
|
||||
bool GetIsTeleporting() const { return m_IsTeleporting; }
|
||||
|
||||
/**
|
||||
* Returns the Physics entity for the component
|
||||
* @return Physics entity for the component
|
||||
@@ -355,6 +367,11 @@ private:
|
||||
* The active pickup radius for this entity
|
||||
*/
|
||||
float m_PickupRadius;
|
||||
|
||||
/**
|
||||
* If the entity is teleporting
|
||||
*/
|
||||
bool m_IsTeleporting;
|
||||
};
|
||||
|
||||
#endif // CONTROLLABLEPHYSICSCOMPONENT_H
|
||||
|
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "MissionComponent.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "PossessableComponent.h"
|
||||
#include "PossessorComponent.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
|
||||
@@ -608,6 +610,24 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
SetHealth(health);
|
||||
SetIsShielded(absorb > 0);
|
||||
|
||||
// Dismount on the possessable hit
|
||||
auto possessable = m_Parent->GetComponent<PossessableComponent>();
|
||||
if (possessable && possessable->GetDepossessOnHit()) {
|
||||
possessable->Dismount();
|
||||
}
|
||||
|
||||
// Dismount on the possessor hit
|
||||
auto possessor = m_Parent->GetComponent<PossessorComponent>();
|
||||
if (possessor) {
|
||||
auto possessableId = possessor->GetPossessable();
|
||||
if (possessableId != LWOOBJID_EMPTY) {
|
||||
auto possessable = EntityManager::Instance()->GetEntity(possessableId);
|
||||
if (possessable) {
|
||||
possessor->Dismount(possessable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Parent->GetLOT() != 1) {
|
||||
echo = true;
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "DestroyableComponent.h"
|
||||
#include "dConfig.h"
|
||||
#include "eItemType.h"
|
||||
#include "eUnequippableActiveType.h"
|
||||
|
||||
InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) {
|
||||
this->m_Dirty = true;
|
||||
@@ -62,23 +63,23 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do
|
||||
const auto& info = Inventory::FindItemComponent(item.itemid);
|
||||
|
||||
UpdateSlot(info.equipLocation, { id, static_cast<LOT>(item.itemid), item.count, slot++ });
|
||||
|
||||
|
||||
// Equip this items proxies.
|
||||
auto subItems = info.subItems;
|
||||
|
||||
|
||||
subItems.erase(std::remove_if(subItems.begin(), subItems.end(), ::isspace), subItems.end());
|
||||
|
||||
|
||||
if (!subItems.empty()) {
|
||||
const auto subItemsSplit = GeneralUtils::SplitString(subItems, ',');
|
||||
|
||||
|
||||
for (auto proxyLotAsString : subItemsSplit) {
|
||||
const auto proxyLOT = static_cast<LOT>(std::stoi(proxyLotAsString));
|
||||
|
||||
|
||||
const auto& proxyInfo = Inventory::FindItemComponent(proxyLOT);
|
||||
const LWOOBJID proxyId = ObjectIDManager::Instance()->GenerateObjectID();
|
||||
|
||||
|
||||
// Use item.count since we equip item.count number of the item this is a requested proxy of
|
||||
UpdateSlot(proxyInfo.equipLocation, { proxyId, proxyLOT, item.count, slot++ } );
|
||||
UpdateSlot(proxyInfo.equipLocation, { proxyId, proxyLOT, item.count, slot++ });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -795,9 +796,7 @@ void InventoryComponent::RemoveSlot(const std::string& location) {
|
||||
}
|
||||
|
||||
void InventoryComponent::EquipItem(Item* item, const bool skipChecks) {
|
||||
if (!Inventory::IsValidItem(item->GetLot())) {
|
||||
return;
|
||||
}
|
||||
if (!Inventory::IsValidItem(item->GetLot())) return;
|
||||
|
||||
// Temp items should be equippable but other transfer items shouldn't be (for example the instruments in RB)
|
||||
if (item->IsEquipped()
|
||||
@@ -820,9 +819,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) {
|
||||
|
||||
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
|
||||
|
||||
if (characterComponent != nullptr) {
|
||||
characterComponent->SetLastRocketItemID(item->GetId());
|
||||
}
|
||||
if (characterComponent != nullptr) characterComponent->SetLastRocketItemID(item->GetId());
|
||||
|
||||
lauchPad->OnUse(m_Parent);
|
||||
|
||||
@@ -836,94 +833,8 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) {
|
||||
|
||||
const auto type = static_cast<eItemType>(item->GetInfo().itemType);
|
||||
|
||||
if (item->GetLot() == 8092 && m_Parent->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR && hasCarEquipped == false) {
|
||||
auto startPosition = m_Parent->GetPosition();
|
||||
|
||||
auto startRotation = NiQuaternion::LookAt(startPosition, startPosition + NiPoint3::UNIT_X);
|
||||
auto angles = startRotation.GetEulerAngles();
|
||||
angles.y -= PI;
|
||||
startRotation = NiQuaternion::FromEulerAngles(angles);
|
||||
|
||||
GameMessages::SendTeleport(m_Parent->GetObjectID(), startPosition, startRotation, m_Parent->GetSystemAddress(), true, true);
|
||||
|
||||
EntityInfo info{};
|
||||
info.lot = 8092;
|
||||
info.pos = startPosition;
|
||||
info.rot = startRotation;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
|
||||
auto* carEntity = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent);
|
||||
m_Parent->AddChild(carEntity);
|
||||
|
||||
auto* destroyableComponent = carEntity->GetComponent<DestroyableComponent>();
|
||||
|
||||
// Setup the vehicle stats.
|
||||
if (destroyableComponent != nullptr) {
|
||||
destroyableComponent->SetIsSmashable(false);
|
||||
destroyableComponent->SetIsImmune(true);
|
||||
}
|
||||
// #108
|
||||
auto* possessableComponent = carEntity->GetComponent<PossessableComponent>();
|
||||
|
||||
if (possessableComponent != nullptr) {
|
||||
previousPossessableID = possessableComponent->GetPossessor();
|
||||
possessableComponent->SetPossessor(m_Parent->GetObjectID());
|
||||
}
|
||||
|
||||
auto* moduleAssemblyComponent = carEntity->GetComponent<ModuleAssemblyComponent>();
|
||||
|
||||
if (moduleAssemblyComponent != nullptr) {
|
||||
moduleAssemblyComponent->SetSubKey(item->GetSubKey());
|
||||
moduleAssemblyComponent->SetUseOptionalParts(false);
|
||||
|
||||
for (auto* config : item->GetConfig()) {
|
||||
if (config->GetKey() == u"assemblyPartLOTs") {
|
||||
moduleAssemblyComponent->SetAssemblyPartsLOTs(GeneralUtils::ASCIIToUTF16(config->GetValueAsString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// #107
|
||||
auto* possessorComponent = m_Parent->GetComponent<PossessorComponent>();
|
||||
|
||||
if (possessorComponent) possessorComponent->SetPossessable(carEntity->GetObjectID());
|
||||
|
||||
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
|
||||
|
||||
if (characterComponent) characterComponent->SetIsRacing(true);
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(carEntity);
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
GameMessages::SendSetJetPackMode(m_Parent, false);
|
||||
|
||||
GameMessages::SendNotifyVehicleOfRacingObject(carEntity->GetObjectID(), m_Parent->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendRacingPlayerLoaded(LWOOBJID_EMPTY, m_Parent->GetObjectID(), carEntity->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendVehicleUnlockInput(carEntity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendTeleport(m_Parent->GetObjectID(), startPosition, startRotation, m_Parent->GetSystemAddress(), true, true);
|
||||
GameMessages::SendTeleport(carEntity->GetObjectID(), startPosition, startRotation, m_Parent->GetSystemAddress(), true, true);
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
|
||||
hasCarEquipped = true;
|
||||
equippedCarEntity = carEntity;
|
||||
return;
|
||||
} else if (item->GetLot() == 8092 && m_Parent->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR && hasCarEquipped == true) {
|
||||
GameMessages::SendNotifyRacingClient(LWOOBJID_EMPTY, 3, 0, LWOOBJID_EMPTY, u"", m_Parent->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
auto player = dynamic_cast<Player*>(m_Parent);
|
||||
player->SendToZone(player->GetCharacter()->GetZoneID());
|
||||
equippedCarEntity->Kill();
|
||||
hasCarEquipped = false;
|
||||
equippedCarEntity = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!building) {
|
||||
if (item->GetLot() == 6086) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == eItemType::ITEM_TYPE_LOOT_MODEL || type == eItemType::ITEM_TYPE_VEHICLE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!building && (item->GetLot() == 6086 || type == eItemType::ITEM_TYPE_LOOT_MODEL || type == eItemType::ITEM_TYPE_VEHICLE)) return;
|
||||
|
||||
if (type != eItemType::ITEM_TYPE_LOOT_MODEL && type != eItemType::ITEM_TYPE_MODEL) {
|
||||
if (!item->GetBound() && !item->GetPreconditionExpression()->Check(m_Parent)) {
|
||||
@@ -940,9 +851,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) {
|
||||
set->OnEquip(lot);
|
||||
}
|
||||
|
||||
if (item->GetInfo().isBOE) {
|
||||
item->SetBound(true);
|
||||
}
|
||||
if (item->GetInfo().isBOE) item->SetBound(true);
|
||||
|
||||
GenerateProxies(item);
|
||||
|
||||
@@ -989,6 +898,85 @@ void InventoryComponent::UnEquipItem(Item* item) {
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::HandlePossession(Item* item) {
|
||||
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
|
||||
if (!characterComponent) return;
|
||||
|
||||
auto* possessorComponent = m_Parent->GetComponent<PossessorComponent>();
|
||||
if (!possessorComponent) return;
|
||||
|
||||
// Don't do anything if we are busy dismounting
|
||||
if (possessorComponent->GetIsDismounting()) return;
|
||||
|
||||
// Check to see if we are already mounting something
|
||||
auto* currentlyPossessedEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
|
||||
auto currentlyPossessedItem = possessorComponent->GetMountItemID();
|
||||
|
||||
if (currentlyPossessedItem) {
|
||||
if (currentlyPossessedEntity) possessorComponent->Dismount(currentlyPossessedEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStunState::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true);
|
||||
|
||||
// Set the mount Item ID so that we know what were handling
|
||||
possessorComponent->SetMountItemID(item->GetId());
|
||||
GameMessages::SendSetMountInventoryID(m_Parent, item->GetId(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
// Create entity to mount
|
||||
auto startRotation = m_Parent->GetRotation();
|
||||
|
||||
EntityInfo info{};
|
||||
info.lot = item->GetLot();
|
||||
info.pos = m_Parent->GetPosition();
|
||||
info.rot = startRotation;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
|
||||
auto* mount = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent);
|
||||
|
||||
// Check to see if the mount is a vehicle, if so, flip it
|
||||
auto* vehicleComponent = mount->GetComponent<VehiclePhysicsComponent>();
|
||||
if (vehicleComponent) {
|
||||
auto angles = startRotation.GetEulerAngles();
|
||||
// Make it right side up
|
||||
angles.x -= PI;
|
||||
// Make it going in the direction of the player
|
||||
angles.y -= PI;
|
||||
startRotation = NiQuaternion::FromEulerAngles(angles);
|
||||
mount->SetRotation(startRotation);
|
||||
// We're pod racing now
|
||||
characterComponent->SetIsRacing(true);
|
||||
}
|
||||
|
||||
// Setup the destroyable stats
|
||||
auto* destroyableComponent = mount->GetComponent<DestroyableComponent>();
|
||||
if (destroyableComponent) {
|
||||
destroyableComponent->SetIsSmashable(false);
|
||||
destroyableComponent->SetIsImmune(true);
|
||||
}
|
||||
|
||||
// Mount it
|
||||
auto* possessableComponent = mount->GetComponent<PossessableComponent>();
|
||||
if (possessableComponent) {
|
||||
possessableComponent->SetIsItemSpawned(true);
|
||||
possessableComponent->SetPossessor(m_Parent->GetObjectID());
|
||||
// Possess it
|
||||
possessorComponent->SetPossessable(mount->GetObjectID());
|
||||
possessorComponent->SetPossessableType(possessableComponent->GetPossessionType());
|
||||
}
|
||||
|
||||
GameMessages::SendSetJetPackMode(m_Parent, false);
|
||||
|
||||
// Make it go to the client
|
||||
EntityManager::Instance()->ConstructEntity(mount);
|
||||
// Update the possessor
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
|
||||
// have to unlock the input so it vehicle can be driven
|
||||
if (vehicleComponent) GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress());
|
||||
GameMessages::SendMarkInventoryItemAsActive(m_Parent->GetObjectID(), true, eUnequippableActiveType::MOUNT, item->GetId(), m_Parent->GetSystemAddress());
|
||||
}
|
||||
|
||||
void InventoryComponent::ApplyBuff(Item* item) const {
|
||||
const auto buffs = FindBuffs(item, true);
|
||||
|
||||
|
@@ -198,6 +198,13 @@ public:
|
||||
*/
|
||||
void UnEquipItem(Item* item);
|
||||
|
||||
/**
|
||||
* Unequips an Item from the inventory
|
||||
* @param item the Item to unequip
|
||||
* @return if we were successful
|
||||
*/
|
||||
void HandlePossession(Item* item);
|
||||
|
||||
/**
|
||||
* Adds a buff related to equipping a lot to the entity
|
||||
* @param item the item to find buffs for
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "dpWorld.h"
|
||||
#include "PetDigServer.h"
|
||||
#include "../dWorldServer/ObjectIDManager.h"
|
||||
#include "eUnequippableActiveType.h"
|
||||
|
||||
#include "Game.h"
|
||||
#include "dConfig.h"
|
||||
@@ -883,7 +884,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
|
||||
GameMessages::SendSetPetNameModerated(m_Owner, m_DatabaseId, m_ModerationStatus, owner->GetSystemAddress());
|
||||
}
|
||||
|
||||
GameMessages::SendMarkInventoryItemAsActive(m_Owner, true, 0, m_ItemId, GetOwner()->GetSystemAddress());
|
||||
GameMessages::SendMarkInventoryItemAsActive(m_Owner, true, eUnequippableActiveType::PET, m_ItemId, GetOwner()->GetSystemAddress());
|
||||
|
||||
activePets[m_Owner] = m_Parent->GetObjectID();
|
||||
|
||||
@@ -945,7 +946,7 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
|
||||
void PetComponent::Deactivate() {
|
||||
GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), -1, u"despawn", "", LWOOBJID_EMPTY, 1, 1, true);
|
||||
|
||||
GameMessages::SendMarkInventoryItemAsActive(m_Owner, false, 0, m_ItemId, GetOwner()->GetSystemAddress());
|
||||
GameMessages::SendMarkInventoryItemAsActive(m_Owner, false, eUnequippableActiveType::PET, m_ItemId, GetOwner()->GetSystemAddress());
|
||||
|
||||
activePets.erase(m_Owner);
|
||||
|
||||
|
@@ -18,7 +18,7 @@ PossessableComponent::PossessableComponent(Entity* parent, uint32_t componentId)
|
||||
|
||||
// Should a result not exist for this default to attached visible
|
||||
if (!result.eof()) {
|
||||
m_PossessionType = static_cast<ePossessionType>(result.getIntField(0, 0));
|
||||
m_PossessionType = static_cast<ePossessionType>(result.getIntField(0, 1)); // Default to Attached Visible
|
||||
m_DepossessOnHit = static_cast<bool>(result.getIntField(1, 0));
|
||||
} else {
|
||||
m_PossessionType = ePossessionType::ATTACHED_VISIBLE;
|
||||
@@ -30,7 +30,7 @@ PossessableComponent::PossessableComponent(Entity* parent, uint32_t componentId)
|
||||
void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
|
||||
outBitStream->Write(m_DirtyPossessable || bIsInitialUpdate);
|
||||
if (m_DirtyPossessable || bIsInitialUpdate) {
|
||||
m_DirtyPossessable = false;
|
||||
m_DirtyPossessable = false; // reset flag
|
||||
outBitStream->Write(m_Possessor != LWOOBJID_EMPTY);
|
||||
if (m_Possessor != LWOOBJID_EMPTY) outBitStream->Write(m_Possessor);
|
||||
|
||||
@@ -38,9 +38,18 @@ void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn
|
||||
if (m_AnimationFlag != eAnimationFlags::IDLE_INVALID) outBitStream->Write(m_AnimationFlag);
|
||||
|
||||
outBitStream->Write(m_ImmediatelyDepossess);
|
||||
m_ImmediatelyDepossess = false; // reset flag
|
||||
}
|
||||
}
|
||||
|
||||
void PossessableComponent::OnUse(Entity* originator) {
|
||||
// TODO: Implement this
|
||||
void PossessableComponent::Dismount() {
|
||||
SetPossessor(LWOOBJID_EMPTY);
|
||||
if (m_ItemSpawned) m_Parent->ScheduleKillAfterUpdate();
|
||||
}
|
||||
|
||||
void PossessableComponent::OnUse(Entity* originator) {
|
||||
auto* possessor = originator->GetComponent<PossessorComponent>();
|
||||
if (possessor) {
|
||||
possessor->Mount(m_Parent);
|
||||
}
|
||||
}
|
||||
|
@@ -20,14 +20,24 @@ public:
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
|
||||
|
||||
/**
|
||||
* Sets the possessor of this entity
|
||||
* @brief mounts the Entity
|
||||
*/
|
||||
void Mount();
|
||||
|
||||
/**
|
||||
* @brief dismounts the Entity
|
||||
*/
|
||||
void Dismount();
|
||||
|
||||
/**
|
||||
* Sets the possessor of this Entity
|
||||
* @param value the ID of the possessor to set
|
||||
*/
|
||||
void SetPossessor(LWOOBJID value) { m_Possessor = value; m_DirtyPossessable = true; };
|
||||
|
||||
/**
|
||||
* Returns the possessor of this entity
|
||||
* @return the possessor of this entity
|
||||
* Returns the possessor of this Entity
|
||||
* @return the possessor of this Entity
|
||||
*/
|
||||
LWOOBJID GetPossessor() const { return m_Possessor; };
|
||||
|
||||
@@ -38,19 +48,19 @@ public:
|
||||
void SetAnimationFlag(eAnimationFlags value) { m_AnimationFlag = value; m_DirtyPossessable = true; };
|
||||
|
||||
/**
|
||||
* Returns the possession type of this entity
|
||||
* @return the possession type of this entity
|
||||
* Returns the possession type of this Entity
|
||||
* @return the possession type of this Entity
|
||||
*/
|
||||
ePossessionType GetPossessionType() const { return m_PossessionType; };
|
||||
|
||||
/**
|
||||
* Returns if the entity should deposses on hit
|
||||
* @return if the entity should deposses on hit
|
||||
* Returns if the Entity should deposses on hit
|
||||
* @return if the Entity should deposses on hit
|
||||
*/
|
||||
bool GetDepossessOnHit() const { return m_DepossessOnHit; };
|
||||
|
||||
/**
|
||||
* Forcibly depossess the entity
|
||||
* Forcibly depossess the Entity
|
||||
*/
|
||||
void ForceDepossess() { m_ImmediatelyDepossess = true; m_DirtyPossessable = true; };
|
||||
|
||||
@@ -58,13 +68,13 @@ public:
|
||||
* Set if the parent entity was spawned from an item
|
||||
* @param value if the parent entity was spawned from an item
|
||||
*/
|
||||
void SetItemSpawned(bool value) { m_ItemSpawned = value; };
|
||||
void SetIsItemSpawned(bool value) { m_ItemSpawned = value; };
|
||||
|
||||
/**
|
||||
* Returns if the parent entity was spawned from an item
|
||||
* @return if the parent entity was spawned from an item
|
||||
*/
|
||||
LWOOBJID GetItemSpawned() const { return m_ItemSpawned; };
|
||||
LWOOBJID GetIsItemSpawned() const { return m_ItemSpawned; };
|
||||
|
||||
/**
|
||||
* Handles an OnUsed event by some other entity, if said entity has a Possessor it becomes the possessor
|
||||
|
@@ -1,12 +1,28 @@
|
||||
#include "PossessorComponent.h"
|
||||
#include "PossessableComponent.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
#include "eUnequippableActiveType.h"
|
||||
|
||||
PossessorComponent::PossessorComponent(Entity* parent) : Component(parent) {
|
||||
m_Possessable = LWOOBJID_EMPTY;
|
||||
}
|
||||
|
||||
PossessorComponent::~PossessorComponent() {}
|
||||
|
||||
|
||||
PossessorComponent::~PossessorComponent() {
|
||||
if (m_Possessable != LWOOBJID_EMPTY) {
|
||||
auto* mount = EntityManager::Instance()->GetEntity(m_Possessable);
|
||||
if (mount) {
|
||||
auto* possessable = mount->GetComponent<PossessableComponent>();
|
||||
if (possessable) {
|
||||
if (possessable->GetIsItemSpawned()) {
|
||||
GameMessages::SendMarkInventoryItemAsActive(m_Parent->GetObjectID(), false, eUnequippableActiveType::MOUNT, GetMountItemID(), m_Parent->GetSystemAddress());
|
||||
}
|
||||
possessable->Dismount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PossessorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
|
||||
outBitStream->Write(m_DirtyPossesor || bIsInitialUpdate);
|
||||
@@ -19,3 +35,48 @@ void PossessorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInit
|
||||
outBitStream->Write(m_PossessableType);
|
||||
}
|
||||
}
|
||||
|
||||
void PossessorComponent::Mount(Entity* mount) {
|
||||
// Don't do anything if we are busy dismounting
|
||||
if (GetIsDismounting() || !mount) return;
|
||||
|
||||
GameMessages::SendSetMountInventoryID(m_Parent, mount->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
auto* possessableComponent = mount->GetComponent<PossessableComponent>();
|
||||
if (possessableComponent) {
|
||||
possessableComponent->SetPossessor(m_Parent->GetObjectID());
|
||||
SetPossessable(mount->GetObjectID());
|
||||
SetPossessableType(possessableComponent->GetPossessionType());
|
||||
}
|
||||
|
||||
auto characterComponent = m_Parent->GetComponent<CharacterComponent>();
|
||||
if (characterComponent) characterComponent->SetIsRacing(true);
|
||||
|
||||
// GM's to send
|
||||
GameMessages::SendSetJetPackMode(m_Parent, false);
|
||||
GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress());
|
||||
GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStunState::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true);
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
EntityManager::Instance()->SerializeEntity(mount);
|
||||
}
|
||||
|
||||
void PossessorComponent::Dismount(Entity* mount, bool forceDismount) {
|
||||
// Don't do anything if we are busy dismounting
|
||||
if (GetIsDismounting() || !mount) return;
|
||||
SetIsDismounting(true);
|
||||
|
||||
if (mount) {
|
||||
auto* possessableComponent = mount->GetComponent<PossessableComponent>();
|
||||
if (possessableComponent) {
|
||||
possessableComponent->SetPossessor(LWOOBJID_EMPTY);
|
||||
if (forceDismount) possessableComponent->ForceDepossess();
|
||||
}
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
EntityManager::Instance()->SerializeEntity(mount);
|
||||
|
||||
auto characterComponent = m_Parent->GetComponent<CharacterComponent>();
|
||||
if (characterComponent) characterComponent->SetIsRacing(false);
|
||||
}
|
||||
// Make sure we don't have wacky controls
|
||||
GameMessages::SendSetPlayerControlScheme(m_Parent, eControlSceme::SCHEME_A);
|
||||
}
|
||||
|
@@ -25,35 +25,63 @@ public:
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
|
||||
|
||||
/**
|
||||
* Sets the entity that this entity is possessing
|
||||
* @param value the ID of the entity this ID should posess
|
||||
* @brief Mounts the entity
|
||||
*
|
||||
* @param mount Entity to be mounted
|
||||
*/
|
||||
void Mount(Entity* mount);
|
||||
|
||||
/**
|
||||
* @brief Dismounts the entity
|
||||
*
|
||||
* @param mount Entity to be dismounted
|
||||
* @param forceDismount Should we forcibly dismount the entity
|
||||
*/
|
||||
void Dismount(Entity* mount, bool forceDismount = false);
|
||||
|
||||
/**
|
||||
* Sets the ID that this entity is possessing
|
||||
* @param value The ID that this entity is possessing
|
||||
*/
|
||||
void SetPossessable(LWOOBJID value) { m_Possessable = value; m_DirtyPossesor = true; }
|
||||
|
||||
/**
|
||||
* Returns the entity that this entity is currently posessing
|
||||
* @return the entity that this entity is currently posessing
|
||||
* @return The entity that this entity is currently posessing
|
||||
*/
|
||||
LWOOBJID GetPossessable() const { return m_Possessable; }
|
||||
|
||||
/**
|
||||
* Sets if we are busy mounting or dismounting
|
||||
* @param value if we are busy mounting or dismounting
|
||||
* Sets if we are busy dismounting
|
||||
* @param value If we are busy dismounting
|
||||
*/
|
||||
void SetIsBusy(bool value) { m_IsBusy = value; }
|
||||
void SetIsDismounting(bool value) { m_IsDismounting = value; }
|
||||
|
||||
/**
|
||||
* Returns if we are busy mounting or dismounting
|
||||
* @return if we are busy mounting or dismounting
|
||||
* Returns if we are busy dismounting
|
||||
* @return If we are busy dismounting
|
||||
*/
|
||||
bool GetIsBusy() const { return m_IsBusy; }
|
||||
bool GetIsDismounting() const { return m_IsDismounting; }
|
||||
|
||||
/**
|
||||
* Sets the possesible type that's currently used, merely used by the shooting gallery if it's 0
|
||||
* @param value the possesible type to set
|
||||
* @param value The possesible type to set
|
||||
*/
|
||||
void SetPossessableType(ePossessionType value) { m_PossessableType = value; m_DirtyPossesor = true; }
|
||||
|
||||
|
||||
/**
|
||||
* Gets the object ID of the mount item that is being used
|
||||
* @return The object ID of the mount item that is being used
|
||||
*/
|
||||
LWOOBJID GetMountItemID() const { return m_MountItemID; }
|
||||
|
||||
/**
|
||||
* Sets the object ID of the mount item that is being used
|
||||
* @param m_MountItemID The object ID of the mount item that is being used
|
||||
*/
|
||||
void SetMountItemID(LWOOBJID mountItemID) { m_MountItemID = mountItemID; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -68,14 +96,19 @@ private:
|
||||
ePossessionType m_PossessableType = ePossessionType::NO_POSSESSION;
|
||||
|
||||
/**
|
||||
* @brief if the possessor is dirty
|
||||
* @brief If the possessor is dirty
|
||||
*
|
||||
*/
|
||||
bool m_DirtyPossesor = false;
|
||||
|
||||
/**
|
||||
* @brief if the possessor is busy mounting or dismounting
|
||||
* @brief If the possessor is busy dismounting
|
||||
*
|
||||
*/
|
||||
bool m_IsBusy = false;
|
||||
bool m_IsDismounting = false;
|
||||
|
||||
/**
|
||||
* Mount Item ID
|
||||
*/
|
||||
LWOOBJID m_MountItemID = LWOOBJID_EMPTY;
|
||||
};
|
||||
|
Reference in New Issue
Block a user