Proper Rocket Holding

Sanity checks on Prop and LUP launchpads to not open if no valid rocket
Add serialization for sending item configs
so that rockets show for other players
This commit is contained in:
Aaron Kimbre
2022-05-08 19:57:36 -05:00
parent 24745c2e7a
commit ec207838d4
10 changed files with 156 additions and 132 deletions

View File

@@ -13,6 +13,7 @@
#include "ChatPackets.h"
#include "MissionComponent.h"
#include "PropertyEntranceComponent.h"
#include "RocketLaunchLupComponent.h"
#include "dServer.h"
#include "dMessageIdentifiers.h"
#include "PacketUtils.h"
@@ -40,19 +41,7 @@ RocketLaunchpadControlComponent::~RocketLaunchpadControlComponent() {
delete m_AltPrecondition;
}
void RocketLaunchpadControlComponent::RocketEquip(Entity* entity, LWOOBJID rocketID) {
if (m_PlayersInRadius.find(entity->GetObjectID()) != m_PlayersInRadius.end()) {
Launch(entity, rocketID);
//Go ahead and save the player
//This causes a double-save, but it should prevent players from not being saved
//before the next world server starts loading their data.
if (entity->GetCharacter())
entity->GetCharacter()->SaveXMLToDatabase();
}
}
void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID optionalRocketID, LWOMAPID mapId, LWOCLONEID cloneId) {
void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId, LWOCLONEID cloneId) {
auto zone = mapId == LWOMAPID_INVALID ? m_TargetZone : mapId;
if (zone == 0)
@@ -60,53 +49,22 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID option
return;
}
TellMasterToPrepZone(zone);
// This also gets triggered by a proximity monitor + item equip, I will set that up when havok is ready
auto* inventoryComponent = originator->GetComponent<InventoryComponent>();
auto* characterComponent = originator->GetComponent<CharacterComponent>();
auto* character = originator->GetCharacter();
if (inventoryComponent == nullptr || characterComponent == nullptr || character == nullptr) {
if (!characterComponent || !character) return;
auto* rocket = characterComponent->GetRocket(originator);
if (!rocket) {
Game::logger->Log("RocketLaunchpadControlComponent", "Unable to find rocket!\n");
return;
}
// Select the rocket
Item* rocket = nullptr;
if (optionalRocketID != LWOOBJID_EMPTY)
{
rocket = inventoryComponent->FindItemById(optionalRocketID);
}
if (rocket == nullptr)
{
rocket = inventoryComponent->FindItemById(characterComponent->GetLastRocketItemID());
}
if (rocket == nullptr)
{
rocket = inventoryComponent->FindItemByLot(6416);
}
if (rocket == nullptr)
{
Game::logger->Log("RocketLaunchpadControlComponent", "Unable to find rocket (%llu)!\n", optionalRocketID);
return;
}
if (rocket->GetConfig().empty()) // Sanity check
{
rocket->SetCount(0, false, false);
return;
}
// we have the ability to launch, so now we prep the zone
TellMasterToPrepZone(zone);
// Achievement unlocked: "All zones unlocked"
if (!m_AltLandingScene.empty() && m_AltPrecondition->Check(originator)) {
character->SetTargetScene(m_AltLandingScene);
}
@@ -114,27 +72,6 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID option
character->SetTargetScene(m_TargetScene);
}
if (characterComponent) {
for (LDFBaseData* data : rocket->GetConfig()) {
if (data->GetKey() == u"assemblyPartLOTs") {
std::string newRocketStr;
for (char character : data->GetValueAsString()) {
if (character == '+') {
newRocketStr.push_back(';');
}
else {
newRocketStr.push_back(character);
}
}
newRocketStr.push_back(';');
characterComponent->SetLastRocketConfig(GeneralUtils::ASCIIToUTF16(newRocketStr));
}
}
}
// Store the last used rocket item's ID
characterComponent->SetLastRocketItemID(rocket->GetId());
characterComponent->UpdatePlayerStatistic(RocketsUsed);
character->SaveXMLToDatabase();
@@ -143,23 +80,31 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOOBJID option
GameMessages::SendFireEventClientSide(m_Parent->GetObjectID(), originator->GetSystemAddress(), u"RocketEquipped", rocket->GetId(), cloneId, -1, originator->GetObjectID());
rocket->Equip(true);
GameMessages::SendChangeObjectWorldState(rocket->GetId(), WORLDSTATE_ATTACHED, UNASSIGNED_SYSTEM_ADDRESS);
EntityManager::Instance()->SerializeEntity(originator);
}
void RocketLaunchpadControlComponent::OnUse(Entity* originator) {
// If we are have the property or the LUP component, we don't want to immediately launch
// instead we let their OnUse handlers do their things
// which components of an Object have their OnUse called when using them
// so we don't need to call it here
auto* propertyEntrance = m_Parent->GetComponent<PropertyEntranceComponent>();
if (propertyEntrance != nullptr)
{
propertyEntrance->OnUse(originator);
if (propertyEntrance) {
return;
}
auto* rocketLaunchLUP = m_Parent->GetComponent<RocketLaunchLupComponent>();
if (rocketLaunchLUP) {
return;
}
// No rocket no launch
auto* rocket = originator->GetComponent<CharacterComponent>()->RocketEquip(originator);
if (!rocket) {
return;
}
Launch(originator);
}