mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
fix(pets): pet bouncers wait for the owner and cost imagination
Issue 536. A pet that reached a pet switch jumped on it by itself for free. Now it works like digs, following what live did (2014 captures): on the way the pet has state 0x500 and the owner gets PR_BOUNCER_TUTORIAL_01; on the switch the pet has state 0x120 and the Jump On Object ability, plays "excited" while the switch plays "engaged", and the owner gets the pet action button (ShowPetActionButton 2) and PR_BOUNCER_TUTORIAL_03. Using it costs PetAbilities.ImaginationCost (2), the pet plays "jump", the owner gets PR_TOOLTIP_1ST_PET_JUMPED_ON_SWITCH and the switch turns its bouncer on. The switch plays "launch" then, as on live, instead of "engaged". The pet switch is no longer written into the pet's serialized interaction (it was never cleared). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -367,18 +367,21 @@ void PetComponent::Update(float deltaTime) {
|
||||
|
||||
float haltDistance = 5;
|
||||
|
||||
if (closestSwitch != nullptr) {
|
||||
if (!closestSwitch->GetActive()) {
|
||||
NiPoint3 switchPosition = closestSwitch->GetParentEntity()->GetPosition();
|
||||
float distance = Vector3::DistanceSquared(position, switchPosition);
|
||||
if (distance < 3 * 3) {
|
||||
m_Interaction = closestSwitch->GetParentEntity()->GetObjectID();
|
||||
closestSwitch->OnUse(m_Parent);
|
||||
} else if (distance < 20 * 20) {
|
||||
haltDistance = 1;
|
||||
Entity* abilityObject = nullptr;
|
||||
auto objectAbility = ePetAbilityType::Invalid;
|
||||
bool atAbilityObject = false;
|
||||
|
||||
destination = switchPosition;
|
||||
}
|
||||
if (closestSwitch != nullptr && !closestSwitch->GetActive()) {
|
||||
NiPoint3 switchPosition = closestSwitch->GetParentEntity()->GetPosition();
|
||||
float distance = Vector3::DistanceSquared(position, switchPosition);
|
||||
if (distance < 20 * 20) {
|
||||
abilityObject = closestSwitch->GetParentEntity();
|
||||
objectAbility = ePetAbilityType::JumpOnObject;
|
||||
atAbilityObject = distance < 3 * 3;
|
||||
|
||||
haltDistance = 1;
|
||||
|
||||
destination = switchPosition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,10 +393,6 @@ void PetComponent::Update(float deltaTime) {
|
||||
|
||||
Entity* closestTreasure = PetDigServer::GetClosestTreasure(position);
|
||||
|
||||
Entity* abilityObject = nullptr;
|
||||
auto objectAbility = ePetAbilityType::Invalid;
|
||||
bool atAbilityObject = false;
|
||||
|
||||
// Skeleton Dragon Pat special case for bone digging
|
||||
if (closestTreasure != nullptr && digUnlocked && (closestTreasure->GetLOT() != 12192 || m_Parent->GetLOT() == 13067)) {
|
||||
NiPoint3 treasurePosition = closestTreasure->GetPosition();
|
||||
@@ -1190,6 +1189,7 @@ void PetComponent::SetAbilityObject(Entity* object, const ePetAbilityType abilit
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
if (ability == ePetAbilityType::DigAtPosition) SendHelp(eHelpType::PR_DIG_TUTORIAL_01);
|
||||
else if (ability == ePetAbilityType::JumpOnObject) SendHelp(eHelpType::PR_BOUNCER_TUTORIAL_01);
|
||||
}
|
||||
|
||||
if (!atObject || m_AbilityButtonShown) return;
|
||||
@@ -1198,6 +1198,13 @@ void PetComponent::SetAbilityObject(Entity* object, const ePetAbilityType abilit
|
||||
SetStatus(status | PET_STATE_USING_ABILITY | PET_STATE_AT_ABILITY_OBJECT);
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
if (ability == ePetAbilityType::JumpOnObject) {
|
||||
// On the pet switch, as live did: the pet gets excited and the switch engages
|
||||
RenderComponent::PlayAnimation(m_Parent, u"excited");
|
||||
RenderComponent::PlayAnimation(object, u"engaged");
|
||||
SendHelp(eHelpType::PR_BOUNCER_TUTORIAL_03);
|
||||
}
|
||||
|
||||
auto* const owner = GetOwner();
|
||||
if (!owner) return;
|
||||
|
||||
@@ -1238,6 +1245,18 @@ void PetComponent::UseAbility() {
|
||||
Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, 202, true);
|
||||
|
||||
m_TreasureTime = 2;
|
||||
} else if (ability == ePetAbilityType::JumpOnObject) {
|
||||
// The pet jumps on the switch, which turns its bouncer on; the pet is done with the switch then
|
||||
m_Ability = ePetAbilityType::Invalid;
|
||||
m_AbilityObject = LWOOBJID_EMPTY;
|
||||
SetStatus(m_Status & ~(PET_STATE_AT_ABILITY_OBJECT | PET_STATE_USING_ABILITY | PET_STATE_GOING_TO_ABILITY_OBJECT));
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
RenderComponent::PlayAnimation(m_Parent, u"jump");
|
||||
SendHelp(eHelpType::PR_TOOLTIP_1ST_PET_JUMPED_ON_SWITCH);
|
||||
|
||||
auto* const switchComponent = object->GetComponent<SwitchComponent>();
|
||||
if (switchComponent) switchComponent->OnUse(m_Parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ public:
|
||||
private:
|
||||
|
||||
/**
|
||||
* Sets the object the pet goes to use its ability on (a dig), or none. The pet first goes to it; once it is there
|
||||
* Sets the object the pet goes to use its ability on (a pet switch or a dig), or none. The pet first goes to it; once it is there
|
||||
* its owner gets the pet's action button, which uses the ability.
|
||||
* @param object the object, nullptr for none
|
||||
* @param ability the ability the object is for
|
||||
@@ -399,7 +399,7 @@ private:
|
||||
bool m_Despawning{ false };
|
||||
|
||||
/**
|
||||
* The object the pet goes to use its ability on (a dig), if any. Live did not serialize it as the interaction.
|
||||
* The object the pet goes to use its ability on (a pet switch or a dig), if any. Live did not serialize it as the interaction.
|
||||
*/
|
||||
LWOOBJID m_AbilityObject{ LWOOBJID_EMPTY };
|
||||
|
||||
|
||||
@@ -80,7 +80,8 @@ void SwitchComponent::EntityEnter(Entity* entity) {
|
||||
|
||||
if (m_PetBouncer != nullptr) {
|
||||
GameMessages::PlayFXEffect(m_Parent->GetObjectID(), 2602, u"pettriggeractive", "BounceEffect").Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
RenderComponent::PlayAnimation(m_Parent, u"engaged");
|
||||
// Live played "launch" here; "engaged" is played when a pet arrives on the switch
|
||||
RenderComponent::PlayAnimation(m_Parent, u"launch");
|
||||
m_PetBouncer->SetPetBouncerEnabled(true);
|
||||
} else {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
Reference in New Issue
Block a user