mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-24 22:47:25 +00:00
f0b6ad89d9
* 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
237 lines
7.7 KiB
C++
237 lines
7.7 KiB
C++
#include "dZoneManager.h"
|
|
#include "PetDigServer.h"
|
|
#include "MissionComponent.h"
|
|
#include "EntityManager.h"
|
|
#include "Character.h"
|
|
#include "PetComponent.h"
|
|
#include "User.h"
|
|
#include "eMissionState.h"
|
|
|
|
std::vector<LWOOBJID> PetDigServer::treasures{};
|
|
|
|
const DigInfo PetDigServer::defaultDigInfo = DigInfo{ 3495, -1, -1, false, false, false, false };
|
|
|
|
/**
|
|
* Summary of all the special treasure behaviors, indexed by their lot
|
|
*/
|
|
const std::map<LOT, DigInfo> PetDigServer::digInfoMap{
|
|
// Regular treasures
|
|
{3495, defaultDigInfo},
|
|
|
|
// Pet cove treasure
|
|
{7612, DigInfo { 7612, -1, -1, false, false, false, false }},
|
|
|
|
// Gnarled Forest flag treasure
|
|
{7410, DigInfo { 7410, -1, -1, false, true, false, false }},
|
|
|
|
// Gnarled Forest crab treasure
|
|
{9308, DigInfo { 9308, 7694, -1, false, false, false, false }},
|
|
|
|
// Avant Gardens mission treasure
|
|
{9307, DigInfo { 9307, -1, -1, false, true, false, true }},
|
|
|
|
// Avant Gardens bouncer treasure
|
|
{7559, DigInfo { 7559, -1, -1, false, false, true, false }},
|
|
|
|
// Crux Prime dragon treasure
|
|
{13098, DigInfo { 13098, 13067, 1298, false, false, false, false }},
|
|
|
|
// Bone treasure (can only be digged using the dragon)
|
|
{12192, DigInfo { 12192, -1, -1, true, false, false, false }},
|
|
};
|
|
|
|
void PetDigServer::OnStartup(Entity* self) {
|
|
treasures.push_back(self->GetObjectID());
|
|
const auto digInfoIterator = digInfoMap.find(self->GetLOT());
|
|
const auto digInfo = digInfoIterator != digInfoMap.end() ? digInfoIterator->second : defaultDigInfo;
|
|
|
|
// Reset any bouncers that might've been created by the previous dig
|
|
if (digInfo.bouncer) {
|
|
auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"BouncerNumber"));
|
|
auto bouncerSpawners = Game::zoneManager->GetSpawnersByName("PetBouncer" + bounceNumber);
|
|
auto switchSpawners = Game::zoneManager->GetSpawnersByName("PetBouncerSwitch" + bounceNumber);
|
|
|
|
for (auto* bouncerSpawner : bouncerSpawners) {
|
|
for (auto* bouncer : bouncerSpawner->m_Info.nodes)
|
|
bouncerSpawner->Deactivate();
|
|
bouncerSpawner->Reset();
|
|
}
|
|
|
|
for (auto* switchSpawner : switchSpawners) {
|
|
switchSpawner->Deactivate();
|
|
switchSpawner->Reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
void PetDigServer::OnDie(Entity* self, Entity* killer) {
|
|
const auto iterator = std::find(treasures.begin(), treasures.end(), self->GetObjectID());
|
|
if (iterator != treasures.end()) {
|
|
treasures.erase(iterator);
|
|
}
|
|
|
|
auto* owner = killer->GetOwner();
|
|
const auto digInfoIterator = digInfoMap.find(self->GetLOT());
|
|
const auto digInfo = digInfoIterator != digInfoMap.end() ? digInfoIterator->second : defaultDigInfo;
|
|
|
|
if (digInfo.spawnLot >= 0) {
|
|
PetDigServer::SpawnPet(self, owner, digInfo);
|
|
} else if (digInfo.builderOnly) {
|
|
|
|
// Some treasures may only be retrieved by the player that built the diggable
|
|
auto builder = self->GetVar<LWOOBJID>(u"builder"); // Set by the pet dig build script
|
|
if (builder != owner->GetObjectID())
|
|
return;
|
|
} else if (digInfo.xBuild) {
|
|
PetDigServer::HandleXBuildDig(self, owner, killer);
|
|
return;
|
|
} else if (digInfo.bouncer) {
|
|
PetDigServer::HandleBouncerDig(self, owner);
|
|
}
|
|
|
|
PetDigServer::ProgressPetDigMissions(owner, self);
|
|
|
|
self->SetNetworkVar<bool>(u"treasure_dug", true);
|
|
// TODO: Reset other pets
|
|
|
|
// Handles smashing leftovers (edge case for the AG X)
|
|
auto* xObject = Game::entityManager->GetEntity(self->GetVar<LWOOBJID>(u"X"));
|
|
if (xObject != nullptr) {
|
|
xObject->Smash(xObject->GetObjectID(), eKillType::VIOLENT);
|
|
}
|
|
}
|
|
|
|
void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pet) {
|
|
auto playerID = self->GetVar<LWOOBJID>(u"builder");
|
|
if (playerID == LWOOBJID_EMPTY || playerID != owner->GetObjectID())
|
|
return;
|
|
|
|
auto* playerEntity = Game::entityManager->GetEntity(playerID);
|
|
if (!playerEntity || !playerEntity->GetCharacter())
|
|
return;
|
|
|
|
auto* player = playerEntity->GetCharacter();
|
|
const auto groupID = self->GetVar<std::u16string>(u"groupID");
|
|
int32_t playerFlag = 0;
|
|
|
|
// The flag that the player dug up
|
|
if (groupID == u"Flag1") {
|
|
playerFlag = 61;
|
|
} else if (groupID == u"Flag2") {
|
|
playerFlag = 62;
|
|
} else if (groupID == u"Flag3") {
|
|
playerFlag = 63;
|
|
}
|
|
|
|
// If the player doesn't have the flag yet
|
|
if (playerFlag != 0 && !player->GetPlayerFlag(playerFlag)) {
|
|
auto* petComponent = pet->GetComponent<PetComponent>();
|
|
if (petComponent != nullptr) {
|
|
// TODO: Pet state = 9 ??
|
|
}
|
|
|
|
// Shows the flag object to the player
|
|
player->SetPlayerFlag(playerFlag, true);
|
|
}
|
|
|
|
auto* xObject = Game::entityManager->GetEntity(self->GetVar<LWOOBJID>(u"X"));
|
|
if (xObject != nullptr) {
|
|
xObject->Smash(xObject->GetObjectID(), eKillType::VIOLENT);
|
|
}
|
|
}
|
|
|
|
void PetDigServer::HandleBouncerDig(const Entity* self, const Entity* owner) {
|
|
auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"BouncerNumber"));
|
|
auto bouncerSpawners = Game::zoneManager->GetSpawnersByName("PetBouncer" + bounceNumber);
|
|
auto switchSpawners = Game::zoneManager->GetSpawnersByName("PetBouncerSwitch" + bounceNumber);
|
|
|
|
for (auto* bouncerSpawner : bouncerSpawners) {
|
|
bouncerSpawner->Activate();
|
|
}
|
|
|
|
for (auto* switchSpawner : switchSpawners) {
|
|
switchSpawner->Activate();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Progresses the Can You Dig It mission and the Pet Excavator Achievement if the player has never completed it yet
|
|
* \param owner the owner that just made a pet dig something up
|
|
*/
|
|
void PetDigServer::ProgressPetDigMissions(const Entity* owner, const Entity* chest) {
|
|
auto* missionComponent = owner->GetComponent<MissionComponent>();
|
|
|
|
if (missionComponent != nullptr) {
|
|
// Can You Dig It progress
|
|
const auto digMissionState = missionComponent->GetMissionState(843);
|
|
if (digMissionState == eMissionState::ACTIVE) {
|
|
missionComponent->ForceProgress(843, 1216, 1);
|
|
}
|
|
|
|
// Pet Excavator progress
|
|
const auto excavatorMissionState = missionComponent->GetMissionState(505);
|
|
if (excavatorMissionState == eMissionState::ACTIVE) {
|
|
if (chest->HasVar(u"PetDig")) {
|
|
int32_t playerFlag = 1260 + chest->GetVarAs<int32_t>(u"PetDig");
|
|
Character* player = owner->GetCharacter();
|
|
|
|
// check if player flag is set
|
|
if (!player->GetPlayerFlag(playerFlag)) {
|
|
missionComponent->ForceProgress(505, 767, 1);
|
|
player->SetPlayerFlag(playerFlag, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Some treasures spawn special pets, this handles that case
|
|
* \param owner the owner that just made a pet dig something up
|
|
* \param digInfo information regarding the treasure, will also contain info about the pet to spawn
|
|
*/
|
|
void PetDigServer::SpawnPet(Entity* self, const Entity* owner, const DigInfo digInfo) {
|
|
// Some treasures require a mission to be active
|
|
if (digInfo.requiredMission >= 0) {
|
|
auto* missionComponent = owner->GetComponent<MissionComponent>();
|
|
if (missionComponent != nullptr && missionComponent->GetMissionState(digInfo.requiredMission) < eMissionState::ACTIVE) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
EntityInfo info{};
|
|
info.lot = digInfo.spawnLot;
|
|
info.pos = self->GetPosition();
|
|
info.rot = self->GetRotation();
|
|
info.spawnerID = self->GetSpawnerID();
|
|
info.settings = {
|
|
new LDFData<LWOOBJID>(u"tamer", owner->GetObjectID()),
|
|
new LDFData<std::string>(u"group", "pet" + std::to_string(owner->GetObjectID())),
|
|
new LDFData<std::string>(u"spawnAnim", "spawn-pet"),
|
|
new LDFData<float>(u"spawnTimer", 1.0)
|
|
};
|
|
|
|
auto* spawnedPet = Game::entityManager->CreateEntity(info);
|
|
Game::entityManager->ConstructEntity(spawnedPet);
|
|
}
|
|
|
|
Entity* PetDigServer::GetClosestTresure(NiPoint3 position) {
|
|
float closestDistance = 0;
|
|
Entity* closest = nullptr;
|
|
|
|
for (const auto tresureId : treasures) {
|
|
auto* tresure = Game::entityManager->GetEntity(tresureId);
|
|
|
|
if (tresure == nullptr) continue;
|
|
|
|
float distance = Vector3::DistanceSquared(tresure->GetPosition(), position);
|
|
|
|
if (closest == nullptr || distance < closestDistance) {
|
|
closestDistance = distance;
|
|
closest = tresure;
|
|
}
|
|
}
|
|
|
|
return closest;
|
|
}
|