Organize dScripts (#814)

* Organize dScripts

whitespace

Remove parent scope

Remove parent scope from initial setter

Remove debug

Remove helper programs

* Fix NtImagimeterVisibility script

Co-authored-by: aronwk-aaron <aronwk.aaron@gmail.com>
This commit is contained in:
David Markowitz
2022-11-03 10:57:54 -07:00
committed by GitHub
parent b974eed8f5
commit 8d37d9b681
567 changed files with 886 additions and 252 deletions

View File

@@ -0,0 +1,5 @@
set(DSCRIPTS_SOURCES_02_SERVER_PETS
"PetFromDigServer.cpp"
"PetFromObjectServer.cpp"
"DamagingPets.cpp"
PARENT_SCOPE)

View File

@@ -0,0 +1,145 @@
#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
};

View File

@@ -0,0 +1,24 @@
#pragma once
#include "CppScripts.h"
/**
* Information about pets regarding which effect to play when a skill is cast
*/
struct PetInfo {
const std::vector<uint32_t> effect;
const std::string skill;
};
class DamagingPets : public CppScripts::Script {
public:
void OnStartup(Entity* self) override;
void OnTimerDone(Entity* self, std::string message) override;
void OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) override;
void OnSkillEventFired(Entity* self, Entity* target, const std::string& message) override;
void OnPlayerLoaded(Entity* self, Entity* player) override;
private:
static void MakeUntamable(Entity* self);
static PetInfo GetPetInfo(Entity* self);
static void ClearEffects(Entity* self);
static const std::map<LOT, PetInfo> petInfo;
};

View File

@@ -0,0 +1,44 @@
#include "PetFromDigServer.h"
#include "PetComponent.h"
void PetFromDigServer::OnStartup(Entity* self) {
auto* petComponent = self->GetComponent<PetComponent>();
if (petComponent == nullptr || petComponent->GetOwner() != nullptr)
return;
// Triggers the local dig pet script for taming etc.
auto tamer = self->GetVar<LWOOBJID>(u"tamer");
// Client compares this with player:GetID() which is a string, so we'll have to give it a string
self->SetNetworkVar(u"pettamer", std::to_string(tamer));
// Kill if the player decides that the dig pet is not worthy
self->AddTimer("killself", 45.0f);
}
void PetFromDigServer::OnTimerDone(Entity* self, std::string timerName) {
if (timerName == "killself") {
// Don't accidentally kill a pet that is already owned
auto* petComponent = self->GetComponent<PetComponent>();
if (petComponent == nullptr || petComponent->GetOwner() != nullptr)
return;
self->Smash(self->GetObjectID(), SILENT);
}
}
void PetFromDigServer::OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) {
if (type == NOTIFY_TYPE_BEGIN) {
self->CancelTimer("killself");
} else if (type == NOTIFY_TYPE_QUIT || type == NOTIFY_TYPE_FAILED) {
self->Smash(self->GetObjectID(), SILENT);
} else if (type == NOTIFY_TYPE_SUCCESS) {
auto* petComponent = self->GetComponent<PetComponent>();
if (petComponent == nullptr)
return;
// TODO: Remove custom group?
// Command the pet to the player as it may otherwise go to its spawn point which is non existant
// petComponent->Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 6, 202, true);
}
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "CppScripts.h"
class PetFromDigServer : public CppScripts::Script
{
public:
void OnStartup(Entity* self) override;
void OnTimerDone(Entity* self, std::string timerName) override;
void OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) override;
};

View File

@@ -0,0 +1,34 @@
#include "PetFromObjectServer.h"
#include "PetComponent.h"
void PetFromObjectServer::OnStartup(Entity* self) {
self->SetNetworkVar(u"pettamer", std::to_string(self->GetVar<LWOOBJID>(u"tamer")));
self->AddTimer("killSelf", 45.0f);
}
void PetFromObjectServer::OnTimerDone(Entity* self, std::string timerName) {
if (timerName == "killSelf") {
const auto* petComponent = self->GetComponent<PetComponent>();
if (petComponent == nullptr || petComponent->GetOwner() != nullptr)
return;
self->Smash(self->GetObjectID(), SILENT);
}
}
void PetFromObjectServer::OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) {
switch (type) {
case NOTIFY_TYPE_BEGIN:
self->CancelAllTimers();
break;
case NOTIFY_TYPE_QUIT:
case NOTIFY_TYPE_FAILED:
self->Smash(self->GetObjectID(), SILENT);
break;
case NOTIFY_TYPE_SUCCESS:
// TODO: Remove from groups?
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"UpdateSuccessPicking", 0,
0, tamer->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS);
default:
break;
}
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "CppScripts.h"
class PetFromObjectServer : public CppScripts::Script {
public:
void OnStartup(Entity* self) override;
void OnTimerDone(Entity* self, std::string timerName) override;
void OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) override;
};