mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-10-31 04:32:06 +00:00 
			
		
		
		
	Update treasure behavior
This commit is contained in:
		| @@ -35,6 +35,9 @@ | ||||
| #include "eGameMasterLevel.h" | ||||
| #include "eMissionState.h" | ||||
|  | ||||
| #define START_BITMASK_SWITCH(x) \ | ||||
|     for (uint32_t bit = 1; x >= bit; bit *= 2) if (x & bit) switch (bit) | ||||
|  | ||||
| std::unordered_map<LOT, PetComponent::PetPuzzleData> PetComponent::buildCache{}; | ||||
| std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::currentActivities{}; | ||||
| std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::activePets{}; | ||||
| @@ -86,7 +89,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare | ||||
| 	m_TimerAway = 0; | ||||
| 	m_TimerBounce = 0; | ||||
| 	m_DatabaseId = LWOOBJID_EMPTY; | ||||
| 	m_Flags = PetFlag::TAMEABLE; // Tameable | ||||
| 	m_Flags = PetFlag::SPAWNING; // Tameable | ||||
| 	m_Ability = ePetAbilityType::Invalid; | ||||
| 	m_StartPosition = m_Parent->GetPosition(); //NiPoint3::ZERO; | ||||
| 	m_MovementAI = nullptr; | ||||
| @@ -104,16 +107,11 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare | ||||
| 	 | ||||
| 	// Load database values | ||||
| 	m_FollowRadius = Game::zoneManager->GetPetFollowRadius(); | ||||
| 	if (!LoadPetInfo(componentId, m_PetInfo)) LOG("Failed to load PetComponent (id: %d) information from CDClient!", componentId); | ||||
| } | ||||
|  | ||||
| bool PetComponent::LoadPetInfo(uint32_t petId, CDPetComponent& result) { | ||||
| 	CDPetComponentTable* petTable; | ||||
| 	try { | ||||
| 		petTable = CDClientManager::Instance().GetTable<CDPetComponentTable>(); | ||||
| 	} catch(...) { | ||||
| 		return false; | ||||
| 	} | ||||
| 	petTable = CDClientManager::Instance().GetTable<CDPetComponentTable>(); | ||||
| 	 | ||||
| 	const auto pet = petTable->GetByID(petId); | ||||
| 	if (!pet) return false; | ||||
| @@ -375,12 +373,31 @@ void PetComponent::Update(float deltaTime) { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Handle pet AI states | ||||
| 	switch (m_State) { | ||||
| 	case PetAiState::spawn: | ||||
| 	/*START_BITMASK_SWITCH(m_Flags) { | ||||
| 	case TAMEABLE: | ||||
| 		break; | ||||
|  | ||||
| 	case SPAWNING: | ||||
| 		LOG_DEBUG("Has SPAWNING flag!"); | ||||
| 		OnSpawn(); | ||||
| 		break; | ||||
|  | ||||
| 	case NOT_WAITING: | ||||
| 		LOG_DEBUG("Has NOT_WAITING flag!"); | ||||
| 		break; | ||||
|  | ||||
| 	case UNKNOWN1: | ||||
| 		LOG_DEBUG("Has UNKNOWN1 flag!"); | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		LOG_DEBUG("Triggered default case!"); | ||||
| 	}*/ | ||||
|  | ||||
| 	//if (HasFlag(SPAWNING)) OnSpawn(); | ||||
|  | ||||
| 	// Handle pet AI states | ||||
| 	switch (m_State) { | ||||
| 	case PetAiState::idle: | ||||
| 		Wander(); | ||||
| 		break; | ||||
| @@ -405,6 +422,7 @@ void PetComponent::Update(float deltaTime) { | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		LOG_DEBUG("Unknown state: %d!", m_Flags); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| @@ -825,6 +843,9 @@ void PetComponent::Wander() { | ||||
| } | ||||
|  | ||||
| void PetComponent::OnSpawn() { | ||||
| 	if (!LoadPetInfo(m_ComponentId, m_PetInfo)) { | ||||
| 		LOG("Failed to load PetComponent (id: %d) information from CDClient!", m_ComponentId); | ||||
| 	} | ||||
| 	m_MovementAI = m_Parent->GetComponent<MovementAIComponent>(); | ||||
|  | ||||
| 	if (m_StartPosition == NiPoint3::ZERO) { | ||||
| @@ -835,12 +856,17 @@ void PetComponent::OnSpawn() { | ||||
| 		m_Parent->SetOwnerOverride(m_Owner); | ||||
| 		m_MovementAI->SetMaxSpeed(m_PetInfo.sprintSpeed); | ||||
| 		m_MovementAI->SetHaltDistance(m_FollowRadius); | ||||
| 		SetOnlyFlag(UNKNOWN1); //SetStatus(PetFlag::NONE); | ||||
| 		//SetOnlyFlag(UNKNOWN1); //SetStatus(PetFlag::NONE); | ||||
| 		SetPetAiState(PetAiState::follow); | ||||
| 	} | ||||
| 	else { | ||||
| 		SetFlag(TAMEABLE); | ||||
| 		SetPetAiState(PetAiState::idle); | ||||
| 	} | ||||
| 	 | ||||
| 	SetFlag(UNKNOWN1); //IDLE? | ||||
| 	UnsetFlag(SPAWNING); | ||||
| 	Game::entityManager->SerializeEntity(m_Parent); | ||||
| } | ||||
|  | ||||
| void PetComponent::OnFollow() { | ||||
| @@ -869,10 +895,9 @@ void PetComponent::OnFollow() { | ||||
| 	const bool nonDragonForBone = closestTreasure->GetLOT() == 12192 && m_Parent->GetLOT() != 13067; | ||||
| 	if (!nonDragonForBone && closestTreasure != nullptr && digUnlocked) { | ||||
| 		const NiPoint3 treasurePos = closestTreasure->GetPosition(); | ||||
| 		const LWOOBJID treasureID = closestTreasure->GetObjectID(); | ||||
| 		const float distance = Vector3::DistanceSquared(ownerPos, treasurePos); | ||||
| 		if (distance < 16 * 16) { | ||||
| 			StartInteract(treasurePos, PetInteractType::treasure, treasureID); | ||||
| 			StartInteract(treasurePos, PetInteractType::treasure, m_Owner); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| @@ -940,6 +965,7 @@ void PetComponent::StartInteract(const NiPoint3 position, const PetInteractType | ||||
| void PetComponent::StopInteract() { | ||||
| 	Entity* owner = GetOwner(); | ||||
| 	if (!owner) return; | ||||
|  | ||||
| 	const auto petAbility = ePetAbilityType::Invalid; | ||||
|  | ||||
| 	SetInteraction(LWOOBJID_EMPTY); | ||||
| @@ -977,6 +1003,7 @@ void PetComponent::SetupInteractTreasureDig() { | ||||
|  | ||||
| 	SetAbility(petAbility); | ||||
| 	SetFlag(NOT_WAITING); //SetStatus(PetFlag::NOT_WAITING); // TODO: Double-check this is the right flag being set | ||||
| 	LOG_DEBUG("m_Flags = %d", m_Flags); | ||||
| 	Game::entityManager->SerializeEntity(m_Parent); // TODO: Double-check pet packet captures | ||||
|  | ||||
| 	const auto sysAddr = owner->GetSystemAddress(); | ||||
| @@ -1016,14 +1043,16 @@ void PetComponent::StartInteractTreasureDig() { | ||||
| void PetComponent::HandleInteractTreasureDig() { | ||||
| 	if (IsHandlingInteraction()) { | ||||
| 		auto* owner = GetOwner(); | ||||
| 		auto* treasure = Game::entityManager->GetEntity(GetInteraction()); | ||||
| 		if (!treasure || !owner) return; | ||||
| 		if (!owner) return; | ||||
| 		 | ||||
| 		auto* treasure = PetDigServer::GetClosestTresure(m_MovementAI->GetDestination()); // TODO: Find a better way to do this | ||||
| 		treasure->Smash(m_Parent->GetObjectID()); | ||||
|  | ||||
| 		LOG_DEBUG("Pet dig completed!"); | ||||
| 		GameMessages::SendHelp(m_Owner, eHelpType::PR_DIG_TUTORIAL_03, owner->GetSystemAddress()); | ||||
|  | ||||
| 		LOG_DEBUG("Pet dig completed!"); | ||||
| 		StopInteract(); //TODO: This may not be totally consistent with live behavior, where the pet seems to stay near the dig and not immediately follow | ||||
| 		//m_Timer = 1.5f; | ||||
|  | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
|   | ||||
| @@ -36,13 +36,20 @@ enum PetInteractType : uint8_t { | ||||
| enum PetFlag : uint32_t { | ||||
| 	NONE, | ||||
| 	UNKNOWN1 = 1 << 0,		//0x01 - Seems to be "idle," which the game doesn't differentiate from "follow" | ||||
| 	UNKNOWN4 = 1 << 2,		//0x04, | ||||
| 	UNKNOWN4 = 1 << 2,		//0x04 - FOLLOWING(?) | ||||
| 	BEING_TAMED = 1 << 4, 	//0x10, | ||||
| 	NOT_WAITING = 1 << 5, 	//0x20, | ||||
| 	STOP_MOVING = 1 << 6,	//0x40 - Seems to be the "stop moving" flag - called when taming begins and stays active until a name is submitted | ||||
| 	SPAWNING = 1 << 7,		//0x80 | ||||
| 	UNKNOWN256 = 1 << 8, 	//0x100 | ||||
| 	UNKNOWN1024 = 1 << 10,	//0x400 | ||||
| 	TAMEABLE = 1 << 26		//0x4000000 | ||||
| }; | ||||
|  | ||||
| /* | ||||
| 132 = 128 + 4 | ||||
| */ | ||||
|  | ||||
| /** | ||||
|  * The pet emote animation ids that can used in PetComponent::Command() | ||||
| */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jadebenn
					jadebenn