mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-23 14:03:34 +00:00
146 lines
5.2 KiB
C++
146 lines
5.2 KiB
C++
|
#include "DamagingPets.h"
|
||
|
#include "PetComponent.h"
|
||
|
#include "DestroyableComponent.h"
|
||
|
#include "BaseCombatAIComponent.h"
|
||
|
#include "RenderComponent.h"
|
||
|
|
||
|
void DamagingPets::OnStartup(Entity *self) {
|
||
|
|
||
|
// Make the pet hostile or non-hostile based on whether or not it is tamed
|
||
|
const auto* petComponent = self->GetComponent<PetComponent>();
|
||
|
if (petComponent != nullptr && petComponent->GetOwner() == nullptr) {
|
||
|
self->AddTimer("GoEvil", 0.5f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DamagingPets::OnPlayerLoaded(Entity *self, Entity *player) {
|
||
|
|
||
|
// Makes it so that new players also see the effect
|
||
|
self->AddCallbackTimer(2.5f, [self]() {
|
||
|
if (self != nullptr) {
|
||
|
const auto* petComponent = self->GetComponent<PetComponent>();
|
||
|
if (petComponent != nullptr && petComponent->GetOwner() == nullptr && self->GetVar<bool>(u"IsEvil")) {
|
||
|
auto* renderComponent = self->GetComponent<RenderComponent>();
|
||
|
if (renderComponent != nullptr) {
|
||
|
auto counter = 1;
|
||
|
for (const auto petEffect : GetPetInfo(self).effect) {
|
||
|
renderComponent->PlayEffect(petEffect, u"create", "FXname" + std::to_string(counter));
|
||
|
counter++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
void DamagingPets::OnNotifyPetTamingMinigame(Entity *self, Entity *tamer, eNotifyType type) {
|
||
|
switch (type) {
|
||
|
case NOTIFY_TYPE_SUCCESS:
|
||
|
case NOTIFY_TYPE_BEGIN:
|
||
|
self->CancelAllTimers();
|
||
|
ClearEffects(self);
|
||
|
break;
|
||
|
case NOTIFY_TYPE_FAILED:
|
||
|
case NOTIFY_TYPE_QUIT:
|
||
|
{
|
||
|
self->SetNetworkVar<bool>(u"bIAmTamable", false);
|
||
|
self->AddTimer("GoEvil", 1.0f);
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DamagingPets::OnSkillEventFired(Entity *self, Entity *caster, const std::string &message) {
|
||
|
const auto infoForPet = GetPetInfo(self);
|
||
|
if (infoForPet.skill == message) {
|
||
|
|
||
|
// Only make pets tamable that aren't tamed yet
|
||
|
const auto* petComponent = self->GetComponent<PetComponent>();
|
||
|
if (petComponent != nullptr && petComponent->GetOwner() == nullptr && self->GetVar<bool>(u"IsEvil")) {
|
||
|
ClearEffects(self);
|
||
|
self->AddTimer("GoEvil", 30.0f);
|
||
|
self->SetNetworkVar<bool>(u"bIAmTamable", true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DamagingPets::OnTimerDone(Entity *self, std::string message) {
|
||
|
if (message == "GoEvil") {
|
||
|
MakeUntamable(self);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DamagingPets::MakeUntamable(Entity *self) {
|
||
|
auto* petComponent = self->GetComponent<PetComponent>();
|
||
|
|
||
|
// If the pet is currently not being tamed, make it hostile
|
||
|
if (petComponent != nullptr && petComponent->GetStatus() != 5) {
|
||
|
self->SetNetworkVar<bool>(u"bIAmTamable", false);
|
||
|
self->SetVar<bool>(u"IsEvil", true);
|
||
|
petComponent->SetStatus(1);
|
||
|
|
||
|
auto* combatAIComponent = self->GetComponent<BaseCombatAIComponent>();
|
||
|
if (combatAIComponent != nullptr) {
|
||
|
combatAIComponent->SetDisabled(false);
|
||
|
}
|
||
|
|
||
|
// Special faction that can attack the player but the player can't attack
|
||
|
auto* destroyableComponent = self->GetComponent<DestroyableComponent>();
|
||
|
if (destroyableComponent != nullptr) {
|
||
|
destroyableComponent->SetFaction(114);
|
||
|
destroyableComponent->SetHealth(5);
|
||
|
}
|
||
|
|
||
|
auto* renderComponent = self->GetComponent<RenderComponent>();
|
||
|
if (renderComponent != nullptr) {
|
||
|
auto counter = 1;
|
||
|
for (const auto petEffect : GetPetInfo(self).effect) {
|
||
|
renderComponent->PlayEffect(petEffect, u"create", "FXname" + std::to_string(counter));
|
||
|
counter++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DamagingPets::ClearEffects(Entity *self) {
|
||
|
self->SetVar<bool>(u"IsEvil", false);
|
||
|
|
||
|
auto* petComponent = self->GetComponent<PetComponent>();
|
||
|
if (petComponent != nullptr) {
|
||
|
petComponent->SetStatus(67108866);
|
||
|
}
|
||
|
|
||
|
auto* combatAIComponent = self->GetComponent<BaseCombatAIComponent>();
|
||
|
if (combatAIComponent != nullptr) {
|
||
|
combatAIComponent->SetDisabled(true);
|
||
|
}
|
||
|
|
||
|
auto* destroyableComponent = self->GetComponent<DestroyableComponent>();
|
||
|
if (destroyableComponent != nullptr) {
|
||
|
destroyableComponent->SetFaction(99);
|
||
|
}
|
||
|
|
||
|
auto* renderComponent = self->GetComponent<RenderComponent>();
|
||
|
if (renderComponent != nullptr) {
|
||
|
auto counter = 1;
|
||
|
for (const auto petEffect : GetPetInfo(self).effect) {
|
||
|
renderComponent->StopEffect("FXname" + std::to_string(counter));
|
||
|
counter++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PetInfo DamagingPets::GetPetInfo(Entity *self) {
|
||
|
const auto infoForPet = petInfo.find(self->GetLOT());
|
||
|
return infoForPet != petInfo.end() ? infoForPet->second : petInfo.begin()->second;
|
||
|
}
|
||
|
|
||
|
// Does not compile on Win32 with name specifiers
|
||
|
const std::map<LOT, PetInfo> DamagingPets::petInfo = {
|
||
|
{ 5639, { /*.effect =*/ { 3170, 4058 }, /*.skill =*/ "waterspray"}}, // Red dragon
|
||
|
{ 5641, { /*.effect =*/ { 3170, 4058 }, /*.skill =*/ "waterspray"}}, // Green dragon
|
||
|
{ 3261, { /*.effect =*/ { 1490 }, /*.skill =*/ "waterspray"}}, // Skunk
|
||
|
};
|