mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-11-04 14:42:02 +00:00 
			
		
		
		
	Further redid pet update loop
This commit is contained in:
		@@ -34,7 +34,6 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id):
 | 
			
		||||
	m_MovementAI = nullptr;
 | 
			
		||||
	m_Disabled = false;
 | 
			
		||||
	m_SkillEntries = {};
 | 
			
		||||
	m_MovementAI = nullptr;
 | 
			
		||||
	m_SoftTimer = 5.0f;
 | 
			
		||||
 | 
			
		||||
	//Grab the aggro information from BaseCombatAI:
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
 | 
			
		||||
	m_ComponentId = componentId;
 | 
			
		||||
 | 
			
		||||
	m_Interaction = LWOOBJID_EMPTY;
 | 
			
		||||
	m_InteractType = PetInteractType::none;
 | 
			
		||||
	m_Owner = LWOOBJID_EMPTY;
 | 
			
		||||
	m_ModerationStatus = 0;
 | 
			
		||||
	m_Tamer = LWOOBJID_EMPTY;
 | 
			
		||||
@@ -89,6 +90,7 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
 | 
			
		||||
 | 
			
		||||
	m_ReadyToDig = false;
 | 
			
		||||
	SetPetAiState(PetAiState::spawn);
 | 
			
		||||
	m_FollowRadius = 5.0f;
 | 
			
		||||
 | 
			
		||||
	std::string checkPreconditions = GeneralUtils::UTF16ToWTF8(parent->GetVar<std::u16string>(u"CheckPrecondition"));
 | 
			
		||||
 | 
			
		||||
@@ -104,17 +106,10 @@ PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(pare
 | 
			
		||||
	auto result = query.execQuery();
 | 
			
		||||
 | 
			
		||||
	if (!result.eof()) {
 | 
			
		||||
		if (!result.fieldIsNull(0))
 | 
			
		||||
			m_walkSpeed = result.getFloatField(0);
 | 
			
		||||
 | 
			
		||||
		if (!result.fieldIsNull(1))
 | 
			
		||||
			m_RunSpeed = result.getFloatField(1);
 | 
			
		||||
 | 
			
		||||
		if (!result.fieldIsNull(2))
 | 
			
		||||
			m_SprintSpeed = result.getFloatField(2);
 | 
			
		||||
 | 
			
		||||
		if (!result.fieldIsNull(3))
 | 
			
		||||
			imaginationDrainRate = result.getFloatField(3);
 | 
			
		||||
		m_walkSpeed = result.getFloatField(0, 2.5f);
 | 
			
		||||
		m_RunSpeed = result.getFloatField(1, 5.0f);
 | 
			
		||||
		m_SprintSpeed = result.getFloatField(2, 10.0f);
 | 
			
		||||
		imaginationDrainRate = result.getFloatField(3, 60.0f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result.finalize();
 | 
			
		||||
@@ -176,22 +171,16 @@ void PetComponent::OnUse(Entity* originator) {
 | 
			
		||||
	if (m_Tamer != LWOOBJID_EMPTY) {
 | 
			
		||||
		auto* tamer = Game::entityManager->GetEntity(m_Tamer);
 | 
			
		||||
 | 
			
		||||
		if (tamer != nullptr) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if (tamer != nullptr) return;
 | 
			
		||||
 | 
			
		||||
		m_Tamer = LWOOBJID_EMPTY;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto* inventoryComponent = originator->GetComponent<InventoryComponent>();
 | 
			
		||||
 | 
			
		||||
	if (inventoryComponent == nullptr) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (inventoryComponent == nullptr) return;
 | 
			
		||||
 | 
			
		||||
	if (m_Preconditions != nullptr && !m_Preconditions->Check(originator, true)) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (m_Preconditions != nullptr && !m_Preconditions->Check(originator, true)) return;
 | 
			
		||||
 | 
			
		||||
	auto* movementAIComponent = m_Parent->GetComponent<MovementAIComponent>();
 | 
			
		||||
 | 
			
		||||
@@ -246,15 +235,11 @@ void PetComponent::OnUse(Entity* originator) {
 | 
			
		||||
 | 
			
		||||
	auto* destroyableComponent = originator->GetComponent<DestroyableComponent>();
 | 
			
		||||
 | 
			
		||||
	if (destroyableComponent == nullptr) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (destroyableComponent == nullptr) return;
 | 
			
		||||
 | 
			
		||||
	auto imagination = destroyableComponent->GetImagination();
 | 
			
		||||
 | 
			
		||||
	if (imagination < imaginationCost) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (imagination < imaginationCost) return;
 | 
			
		||||
 | 
			
		||||
	const auto& bricks = BrickDatabase::GetBricks(buildFile);
 | 
			
		||||
 | 
			
		||||
@@ -344,7 +329,7 @@ void PetComponent::OnUse(Entity* originator) {
 | 
			
		||||
 | 
			
		||||
void PetComponent::Update(float deltaTime) {
 | 
			
		||||
	// If pet does not have an owner, use the UpdateUnowned() loop
 | 
			
		||||
	if (m_Owner == LWOOBJID_EMPTY) {
 | 
			
		||||
	/*if (m_Owner == LWOOBJID_EMPTY) {
 | 
			
		||||
		UpdateUnowned(deltaTime);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -354,6 +339,10 @@ void PetComponent::Update(float deltaTime) {
 | 
			
		||||
	if (!owner) {
 | 
			
		||||
		m_Parent->Kill(); // Kill pet if no owner
 | 
			
		||||
		return;
 | 
			
		||||
	}*/
 | 
			
		||||
 | 
			
		||||
	if (m_StartPosition == NiPoint3::ZERO) {
 | 
			
		||||
		m_StartPosition = m_Parent->GetPosition();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update timer
 | 
			
		||||
@@ -362,138 +351,40 @@ void PetComponent::Update(float deltaTime) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Handle treasure timer
 | 
			
		||||
	if (m_TresureTime > 0.0f) { //TODO: Find better trigger?
 | 
			
		||||
		InteractDig(deltaTime);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Handle pet AI states
 | 
			
		||||
	switch (m_State) {
 | 
			
		||||
		// Handle idle state
 | 
			
		||||
		case PetAiState::idle: {
 | 
			
		||||
			LOG_DEBUG("Pet in idle state!");
 | 
			
		||||
			m_Timer = 1.0f;
 | 
			
		||||
			break;
 | 
			
		||||
	case PetAiState::spawn:
 | 
			
		||||
		LOG_DEBUG("Pet spawn beginning!");
 | 
			
		||||
		OnSpawn();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case PetAiState::idle:
 | 
			
		||||
		Wander();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case PetAiState::follow:
 | 
			
		||||
		OnFollow();
 | 
			
		||||
		break;
 | 
			
		||||
		
 | 
			
		||||
	case PetAiState::goToObj:
 | 
			
		||||
		LOG_DEBUG("Going to object!");
 | 
			
		||||
		if (m_MovementAI->AtFinalWaypoint()) {
 | 
			
		||||
			LOG_DEBUG("Reached object!");
 | 
			
		||||
			m_MovementAI->Stop();
 | 
			
		||||
			SetPetAiState(PetAiState::interact);
 | 
			
		||||
		}
 | 
			
		||||
		// Handle follow state
 | 
			
		||||
		case PetAiState::follow: {
 | 
			
		||||
			// Get movement AI component
 | 
			
		||||
			m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
 | 
			
		||||
			if (!m_MovementAI) return;
 | 
			
		||||
 | 
			
		||||
			// Get and set destination
 | 
			
		||||
			//auto position = m_MovementAI->GetParent()->GetPosition();
 | 
			
		||||
			auto ownerPos = owner->GetPosition();
 | 
			
		||||
			NiPoint3 destination = ownerPos;
 | 
			
		||||
			NiPoint3 interactPos = NiPoint3::ZERO;
 | 
			
		||||
 | 
			
		||||
			// Determine if the "Lost Tags" mission has been completed and digging has been unlocked
 | 
			
		||||
			auto* missionComponent = owner->GetComponent<MissionComponent>();
 | 
			
		||||
			if (!missionComponent) return;
 | 
			
		||||
			const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE;
 | 
			
		||||
 | 
			
		||||
			// Interactions checks
 | 
			
		||||
			SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(ownerPos);
 | 
			
		||||
			Entity* closestTreasure = PetDigServer::GetClosestTresure(ownerPos);
 | 
			
		||||
			if (closestSwitch != nullptr && !closestSwitch->GetActive()) {
 | 
			
		||||
				m_Interaction = closestSwitch->GetParentEntity()->GetObjectID();
 | 
			
		||||
				interactPos = closestSwitch->GetParentEntity()->GetPosition();
 | 
			
		||||
				m_Ability = PetAbilityType::GoToObject;
 | 
			
		||||
			}
 | 
			
		||||
			if (closestTreasure != nullptr && digUnlocked) {
 | 
			
		||||
				m_Interaction = closestTreasure->GetObjectID();
 | 
			
		||||
				interactPos = closestTreasure->GetPosition();
 | 
			
		||||
				m_Ability = PetAbilityType::GoToObject;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Trigger interaction if checks are valid
 | 
			
		||||
			if (m_Ability != PetAbilityType::Invalid) {
 | 
			
		||||
				float distance = Vector3::DistanceSquared(ownerPos, interactPos);
 | 
			
		||||
				if (distance < 20 * 20) {
 | 
			
		||||
					destination = interactPos;
 | 
			
		||||
					m_MovementAI->SetHaltDistance(0.0f);
 | 
			
		||||
					SetPetAiState(PetAiState::interact);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			m_MovementAI->SetDestination(destination);
 | 
			
		||||
			//LOG_DEBUG("Pet destination: %f %f %f", destination.x, destination.y, destination.z);
 | 
			
		||||
			m_Timer = 1.0f;
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		else {
 | 
			
		||||
			m_Timer += 0.5f;
 | 
			
		||||
		}
 | 
			
		||||
		// Handle interact state
 | 
			
		||||
		case PetAiState::interact: {
 | 
			
		||||
			LOG_DEBUG("Interacting with object!");
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
			// Get movement AI component
 | 
			
		||||
			m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
 | 
			
		||||
			if (!m_MovementAI) return;
 | 
			
		||||
	case PetAiState::interact:
 | 
			
		||||
		OnInteract();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
			// Get distance from owner
 | 
			
		||||
			auto ownerPos = owner->GetPosition();
 | 
			
		||||
			auto position = m_MovementAI->GetParent()->GetPosition();
 | 
			
		||||
			float distanceFromOwner = Vector3::DistanceSquared(position, ownerPos);
 | 
			
		||||
 | 
			
		||||
			// Switch back to follow AI state if player moves too far away from pet
 | 
			
		||||
			if (distanceFromOwner > 15 * 15) {
 | 
			
		||||
				m_MovementAI->SetHaltDistance(5.0f); // TODO: Remove this magic number
 | 
			
		||||
				m_Interaction = LWOOBJID_EMPTY;
 | 
			
		||||
				m_Ability = PetAbilityType::Invalid;
 | 
			
		||||
				SetIsReadyToDig(false);
 | 
			
		||||
				SetPetAiState(PetAiState::follow);
 | 
			
		||||
				LOG_DEBUG("Pet interaction aborted due to player distance!");
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Get distance from interactable
 | 
			
		||||
			auto destination = m_MovementAI->GetDestination();
 | 
			
		||||
			float distanceFromInteract = Vector3::DistanceSquared(position, destination);
 | 
			
		||||
			
 | 
			
		||||
			// Handle the interaction
 | 
			
		||||
			if (m_MovementAI->AtFinalWaypoint()) {
 | 
			
		||||
				Entity* interactEntity = Game::entityManager->GetEntity(m_Interaction);
 | 
			
		||||
 | 
			
		||||
				/*auto* switchComponent = interactEntity->GetComponent<SwitchComponent>();
 | 
			
		||||
				if (switchComponent != nullptr) {
 | 
			
		||||
					switchComponent->EntityEnter(m_Parent);
 | 
			
		||||
				}
 | 
			
		||||
				else {*/
 | 
			
		||||
					Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce, true); // Plays 'bounce' animation
 | 
			
		||||
					SetIsReadyToDig(true);
 | 
			
		||||
				//}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_Timer = 1.0f;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		// Handle spawn state
 | 
			
		||||
		case PetAiState::spawn: {
 | 
			
		||||
			LOG_DEBUG("Pet spawned!");
 | 
			
		||||
 | 
			
		||||
			// Get movement AI component
 | 
			
		||||
			m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
 | 
			
		||||
			if (!m_MovementAI) return;
 | 
			
		||||
 | 
			
		||||
			// Determine the pet start position
 | 
			
		||||
			if (m_StartPosition == NiPoint3::ZERO) m_StartPosition = m_Parent->GetPosition();
 | 
			
		||||
 | 
			
		||||
			// Determine next state;
 | 
			
		||||
			if (m_Owner == LWOOBJID_EMPTY) {
 | 
			
		||||
				SetPetAiState(PetAiState::idle);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				SetPetAiState(PetAiState::follow);
 | 
			
		||||
				m_MovementAI->SetMaxSpeed(m_SprintSpeed);
 | 
			
		||||
				m_MovementAI->SetHaltDistance(5.0f); // TODO: Remove magic number
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
 | 
			
		||||
	auto destination = owner->GetPosition();
 | 
			
		||||
@@ -577,7 +468,7 @@ skipTresure:
 | 
			
		||||
	m_Timer = 1;*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::UpdateUnowned(float deltaTime) {
 | 
			
		||||
void PetComponent::UpdateUnowned(float deltaTime) { //CURRENTLY UNUSED
 | 
			
		||||
	if (m_Tamer != LWOOBJID_EMPTY) {
 | 
			
		||||
		if (m_Timer > 0) {
 | 
			
		||||
			m_Timer -= deltaTime;
 | 
			
		||||
@@ -967,9 +858,7 @@ void PetComponent::ClientFailTamingMinigame() {
 | 
			
		||||
void PetComponent::Wander() {
 | 
			
		||||
	m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
 | 
			
		||||
 | 
			
		||||
	if (m_MovementAI == nullptr || !m_MovementAI->AtFinalWaypoint()) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (m_MovementAI == nullptr || !m_MovementAI->AtFinalWaypoint()) return;
 | 
			
		||||
 | 
			
		||||
	m_MovementAI->SetHaltDistance(0);
 | 
			
		||||
 | 
			
		||||
@@ -1007,6 +896,135 @@ void PetComponent::Wander() {
 | 
			
		||||
	m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / info.wanderSpeed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::OnSpawn() {
 | 
			
		||||
	m_MovementAI = m_Parent->GetComponent<MovementAIComponent>();
 | 
			
		||||
	if (!m_MovementAI) return;
 | 
			
		||||
 | 
			
		||||
	LOG_DEBUG("Pet spawn complete, setting AI state.");
 | 
			
		||||
	
 | 
			
		||||
	if (m_Owner != LWOOBJID_EMPTY) SetPetAiState(PetAiState::follow);
 | 
			
		||||
	else SetPetAiState(PetAiState::idle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::OnFollow() {
 | 
			
		||||
	m_MovementAI->SetHaltDistance(5.0f); // TODO: Remove this magic number
 | 
			
		||||
 | 
			
		||||
	Entity* owner = GetOwner();
 | 
			
		||||
	NiPoint3 ownerPos = owner->GetPosition();
 | 
			
		||||
	NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
 | 
			
		||||
 | 
			
		||||
	// If the player's position is within range, stop moving
 | 
			
		||||
	if (Vector3::DistanceSquared(currentPos, ownerPos) <= m_FollowRadius * m_FollowRadius) {
 | 
			
		||||
		m_MovementAI->Stop();
 | 
			
		||||
	}
 | 
			
		||||
	else { // Chase the player's new position
 | 
			
		||||
		m_MovementAI->SetMaxSpeed(m_SprintSpeed);
 | 
			
		||||
		m_MovementAI->SetDestination(ownerPos);
 | 
			
		||||
		LOG_DEBUG("New pet destination: %f %f %f", ownerPos.x, ownerPos.y, ownerPos.z);
 | 
			
		||||
		//SetPetAiState(PetAiState::tether);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//TEST SECTION
 | 
			
		||||
	SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(ownerPos);
 | 
			
		||||
	if (closestSwitch != nullptr && !closestSwitch->GetActive()) {
 | 
			
		||||
		NiPoint3 switchPos = closestSwitch->GetParentEntity()->GetPosition();
 | 
			
		||||
		const float distance = Vector3::DistanceSquared(ownerPos, switchPos);
 | 
			
		||||
		if (distance < 20 * 20) {
 | 
			
		||||
			StartInteract(switchPos, PetInteractType::bouncer);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Determine if the "Lost Tags" mission has been completed and digging has been unlocked
 | 
			
		||||
	auto* missionComponent = owner->GetComponent<MissionComponent>();
 | 
			
		||||
	if (!missionComponent) return;
 | 
			
		||||
	const bool digUnlocked = missionComponent->GetMissionState(842) == eMissionState::COMPLETE;
 | 
			
		||||
 | 
			
		||||
	Entity* closestTreasure = PetDigServer::GetClosestTresure(ownerPos);
 | 
			
		||||
	if (closestTreasure != nullptr && digUnlocked) {
 | 
			
		||||
		NiPoint3 treasurePos = closestTreasure->GetPosition();
 | 
			
		||||
		const float distance = Vector3::DistanceSquared(ownerPos, treasurePos);
 | 
			
		||||
		if (distance < 10 * 10) {
 | 
			
		||||
			StartInteract(treasurePos, PetInteractType::treasure);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_Timer += 0.5f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::OnInteract() {
 | 
			
		||||
	LOG_DEBUG("Beginning interaction with object!");
 | 
			
		||||
 | 
			
		||||
	NiPoint3 ownerPos = GetOwner()->GetPosition();
 | 
			
		||||
	NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
 | 
			
		||||
	const float distanceFromOwner = Vector3::DistanceSquared(ownerPos, currentPos);
 | 
			
		||||
 | 
			
		||||
	if (distanceFromOwner > 25 * 25) {
 | 
			
		||||
		LOG_DEBUG("Disengaging from object interaction due to player distance.");
 | 
			
		||||
		StopInteract();
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (GetInteractType()) {
 | 
			
		||||
		case PetInteractType::bouncer:
 | 
			
		||||
		StartInteractBouncer();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case PetInteractType::treasure:
 | 
			
		||||
		StartInteractDig();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
		LOG_DEBUG("INTERACT = NONE! RETURNING!");
 | 
			
		||||
		StopInteract();
 | 
			
		||||
		m_Timer += 0.5f;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::OnTether() {
 | 
			
		||||
	m_Timer += 0.5f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::StartInteract(NiPoint3 position, PetInteractType interactType) {
 | 
			
		||||
	SetInteractType(interactType);
 | 
			
		||||
	SetAbility(PetAbilityType::GoToObject);
 | 
			
		||||
	SetPetAiState(PetAiState::goToObj);
 | 
			
		||||
	m_MovementAI->SetMaxSpeed(m_RunSpeed);
 | 
			
		||||
	m_MovementAI->SetHaltDistance(0.0f);
 | 
			
		||||
	m_MovementAI->SetDestination(position);
 | 
			
		||||
	LOG_DEBUG("Starting interaction!");
 | 
			
		||||
	Game::entityManager->SerializeEntity(m_Parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::StopInteract() {
 | 
			
		||||
	SetInteractType(PetInteractType::none);
 | 
			
		||||
	SetAbility(PetAbilityType::Invalid);
 | 
			
		||||
	SetPetAiState(PetAiState::follow);
 | 
			
		||||
	m_MovementAI->SetMaxSpeed(m_SprintSpeed);
 | 
			
		||||
	m_MovementAI->SetHaltDistance(m_FollowRadius);
 | 
			
		||||
	LOG_DEBUG("Stopping interaction!");
 | 
			
		||||
	Game::entityManager->SerializeEntity(m_Parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::StartInteractBouncer() {
 | 
			
		||||
	SetAbility(PetAbilityType::JumpOnObject);
 | 
			
		||||
	NiPoint3 destination = m_MovementAI->GetDestination(); 
 | 
			
		||||
	SwitchComponent* closestSwitch = SwitchComponent::GetClosestSwitch(destination);
 | 
			
		||||
	m_Interaction = closestSwitch->GetParentEntity()->GetObjectID();
 | 
			
		||||
	Game::entityManager->SerializeEntity(m_Parent);
 | 
			
		||||
	closestSwitch->EntityEnter(m_Parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::StartInteractDig() {
 | 
			
		||||
	//m_InInteract = true;
 | 
			
		||||
	//m_TresureTime = 2.0f; //TODO: Remove magic number
 | 
			
		||||
	m_Interaction == LWOOBJID_EMPTY; //TODO: Make this not empty
 | 
			
		||||
	Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::Bounce, true);\
 | 
			
		||||
	m_Timer = 2.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
 | 
			
		||||
	AddDrainImaginationTimer(item, fromTaming);
 | 
			
		||||
 | 
			
		||||
@@ -1282,13 +1300,3 @@ void PetComponent::LoadPetNameFromModeration() {
 | 
			
		||||
void PetComponent::SetPreconditions(std::string& preconditions) {
 | 
			
		||||
	m_Preconditions = new PreconditionExpression(preconditions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::StartInteractDig() {
 | 
			
		||||
	//m_InInteract = true;
 | 
			
		||||
	m_TresureTime = 2.0f; //TODO: Remove magic number
 | 
			
		||||
	Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, PetEmote::DigTreasure, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PetComponent::EndInteractDig() {
 | 
			
		||||
	//m_InInteract = false;
 | 
			
		||||
}
 | 
			
		||||
@@ -9,22 +9,31 @@
 | 
			
		||||
/*
 | 
			
		||||
* The current state of the pet AI
 | 
			
		||||
*/
 | 
			
		||||
enum class PetAiState : uint {
 | 
			
		||||
enum class PetAiState : uint8_t {
 | 
			
		||||
	idle = 0,   	// Doing nothing
 | 
			
		||||
	spawn,			// Spawning into the world
 | 
			
		||||
	follow, 		// Following player
 | 
			
		||||
	interact,		// Beginning interaction
 | 
			
		||||
	follow,			// Begin following
 | 
			
		||||
	goToObj,		// Go to object
 | 
			
		||||
	interact,		// Interact with an object
 | 
			
		||||
	despawn 		// Despawning from world
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* The type of object the pet is interacting with
 | 
			
		||||
*/
 | 
			
		||||
enum class PetInteractType : uint8_t {
 | 
			
		||||
	none,		// Not interacting
 | 
			
		||||
	treasure,	// Treasure dig
 | 
			
		||||
	bouncer		// Bouncer switch
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* The status of the pet: Governs the icon above their head and the interactions available
 | 
			
		||||
*/
 | 
			
		||||
enum PetStatus : uint32_t {
 | 
			
		||||
	NONE,
 | 
			
		||||
	BEING_TAMED = 0x10,
 | 
			
		||||
	IS_NOT_WAITING = 0x20, // Right name? - used to be decimal 20
 | 
			
		||||
	IS_NOT_WAITING = 0x20,
 | 
			
		||||
	PLAY_SPAWN_ANIM = 0x80, 
 | 
			
		||||
	TAMEABLE = 0x4000000
 | 
			
		||||
};
 | 
			
		||||
@@ -35,8 +44,7 @@ enum PetEmote : int32_t {
 | 
			
		||||
	Bounce
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class PetAbilityType
 | 
			
		||||
{
 | 
			
		||||
enum class PetAbilityType {
 | 
			
		||||
	Invalid,
 | 
			
		||||
	GoToObject,
 | 
			
		||||
	JumpOnObject,
 | 
			
		||||
@@ -125,6 +133,46 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	void Wander();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Called when the pet is first spawned
 | 
			
		||||
	*/
 | 
			
		||||
	void OnSpawn();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Continues a step in the follow state, making sure that the entity is around its start position
 | 
			
		||||
	*/
 | 
			
		||||
	void OnFollow();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Continues a step in the interact state, handling the pet's interaction with an entity
 | 
			
		||||
	*/
 | 
			
		||||
	void OnInteract();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Continues a step in the tether state, making the entity run towards its target
 | 
			
		||||
	*/
 | 
			
		||||
	void OnTether();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Start a pet interaction with an object at a given position
 | 
			
		||||
	*/
 | 
			
		||||
	void StartInteract(NiPoint3 position, PetInteractType interactType);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Stop a pet interaction with an object
 | 
			
		||||
	*/
 | 
			
		||||
	void StopInteract();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the type of interaction the pet is executing
 | 
			
		||||
	*/
 | 
			
		||||
	void SetInteractType(PetInteractType interactType) { m_InteractType = interactType; };
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the type of interaction the pet is executing
 | 
			
		||||
	*/
 | 
			
		||||
	PetInteractType GetInteractType() { return m_InteractType; };
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Spawns a pet from an item in the inventory of an owner
 | 
			
		||||
	 * @param item the item to create the pet from
 | 
			
		||||
@@ -231,7 +279,12 @@ public:
 | 
			
		||||
	bool GetIsReadyToDig() { return m_ReadyToDig; };
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Start the dig interaction
 | 
			
		||||
	 * Start the pet bouncer interaction
 | 
			
		||||
	*/
 | 
			
		||||
	void StartInteractBouncer();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Start the treasure dig interaction
 | 
			
		||||
	 */
 | 
			
		||||
	void StartInteractDig();
 | 
			
		||||
 | 
			
		||||
@@ -360,6 +413,11 @@ private:
 | 
			
		||||
	 */
 | 
			
		||||
	LWOOBJID m_Interaction;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * The type of object that the pet is currently interacting with (e.g. a treasure chest or switch)
 | 
			
		||||
	*/
 | 
			
		||||
	PetInteractType m_InteractType;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * The ID of the entity that owns this pet
 | 
			
		||||
	 */
 | 
			
		||||
@@ -436,6 +494,11 @@ private:
 | 
			
		||||
	 */
 | 
			
		||||
	NiPoint3 m_StartPosition;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * The halting radius of the pet while following a player
 | 
			
		||||
	*/
 | 
			
		||||
	float m_FollowRadius;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * The movement AI component that is related to this pet, required to move it around
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user