mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-05 02:04:04 +00:00
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:
52
dScripts/ai/ACT/ActMine.cpp
Normal file
52
dScripts/ai/ACT/ActMine.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "ActMine.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "RebuildComponent.h"
|
||||
|
||||
void ActMine::OnStartup(Entity* self) {
|
||||
self->SetVar(u"RebuildComplete", false);
|
||||
self->SetProximityRadius(MINE_RADIUS, "mineRadius");
|
||||
}
|
||||
|
||||
void ActMine::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state == eRebuildState::REBUILD_COMPLETED) {
|
||||
auto* rebuild = self->GetComponent<RebuildComponent>();
|
||||
if (rebuild) {
|
||||
auto* builder = rebuild->GetBuilder();
|
||||
self->SetVar(u"Builder", builder->GetObjectID());
|
||||
}
|
||||
|
||||
self->SetVar(u"RebuildComplete", true);
|
||||
self->SetVar(u"NumWarnings", 0);
|
||||
self->AddToGroup("reset");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ActMine::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) {
|
||||
auto* detroyable = self->GetComponent<DestroyableComponent>();
|
||||
if (!detroyable) return;
|
||||
if (status == "ENTER" && self->GetVar<bool>(u"RebuildComplete") == true && detroyable->IsEnemy(entering)) {
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 242, u"orange", "sirenlight_B");
|
||||
self->AddTimer("Tick", TICK_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
void ActMine::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "Tick") {
|
||||
if (self->GetVar<int>(u"NumWarnings") >= MAX_WARNINGS) {
|
||||
auto* skill = self->GetComponent<SkillComponent>();
|
||||
if (!skill) return;
|
||||
skill->CalculateBehavior(SKILL_ID, BEHAVIOR_ID, LWOOBJID_EMPTY);
|
||||
self->AddTimer("BlowedUp", BLOWED_UP_TIME);
|
||||
} else {
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 242, u"orange", "sirenlight_B");
|
||||
self->AddTimer("Tick", TICK_TIME);
|
||||
self->SetVar(u"NumWarnings", self->GetVar<int>(u"NumWarnings") + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (timerName == "BlowedUp") {
|
||||
self->Kill(self);
|
||||
}
|
||||
}
|
18
dScripts/ai/ACT/ActMine.h
Normal file
18
dScripts/ai/ACT/ActMine.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ActMine : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
private:
|
||||
int MAX_WARNINGS = 3;
|
||||
float MINE_RADIUS = 10.0;
|
||||
float TICK_TIME = 0.25;
|
||||
float BLOWED_UP_TIME = 0.1;
|
||||
uint32_t SKILL_ID = 317;
|
||||
uint32_t BEHAVIOR_ID = 3719;
|
||||
};
|
||||
|
7
dScripts/ai/ACT/ActPlayerDeathTrigger.cpp
Normal file
7
dScripts/ai/ACT/ActPlayerDeathTrigger.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "ActPlayerDeathTrigger.h"
|
||||
|
||||
void ActPlayerDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (!target->IsPlayer() || target->GetIsDead() || !target->GetPlayerReadyForUpdates()) return; //Don't kill already dead players or players not ready
|
||||
|
||||
target->Smash(self->GetObjectID(), eKillType::SILENT);
|
||||
}
|
9
dScripts/ai/ACT/ActPlayerDeathTrigger.h
Normal file
9
dScripts/ai/ACT/ActPlayerDeathTrigger.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ActPlayerDeathTrigger : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnCollisionPhantom(Entity* self, Entity* target);
|
||||
};
|
||||
|
52
dScripts/ai/ACT/ActVehicleDeathTrigger.cpp
Normal file
52
dScripts/ai/ACT/ActVehicleDeathTrigger.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "ActVehicleDeathTrigger.h"
|
||||
#include "PossessableComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "RacingControlComponent.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "EntityManager.h"
|
||||
#include "PossessorComponent.h"
|
||||
|
||||
|
||||
void ActVehicleDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
auto* possessableComponent = target->GetComponent<PossessableComponent>();
|
||||
|
||||
Entity* vehicle;
|
||||
Entity* player;
|
||||
|
||||
if (possessableComponent != nullptr) {
|
||||
auto* player = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor());
|
||||
|
||||
if (player == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (target->IsPlayer()) {
|
||||
auto* possessorComponent = target->GetComponent<PossessorComponent>();
|
||||
|
||||
if (possessorComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
|
||||
|
||||
if (vehicle == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
player = target;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GameMessages::SendDie(vehicle, self->GetObjectID(), LWOOBJID_EMPTY, true, VIOLENT, u"", 0, 0, 0, true, false, 0);
|
||||
|
||||
auto* zoneController = dZoneManager::Instance()->GetZoneControlObject();
|
||||
|
||||
auto* racingControlComponent = zoneController->GetComponent<RacingControlComponent>();
|
||||
|
||||
if (racingControlComponent != nullptr) {
|
||||
racingControlComponent->OnRequestDie(player);
|
||||
}
|
||||
}
|
9
dScripts/ai/ACT/ActVehicleDeathTrigger.h
Normal file
9
dScripts/ai/ACT/ActVehicleDeathTrigger.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ActVehicleDeathTrigger : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
};
|
||||
|
12
dScripts/ai/ACT/CMakeLists.txt
Normal file
12
dScripts/ai/ACT/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
set(DSCRIPTS_SOURCES_AI_ACT
|
||||
"ActMine.cpp"
|
||||
"ActPlayerDeathTrigger.cpp"
|
||||
"ActVehicleDeathTrigger.cpp")
|
||||
|
||||
add_subdirectory(FootRace)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_ACT_FOOTRACE})
|
||||
set(DSCRIPTS_SOURCES_AI_ACT ${DSCRIPTS_SOURCES_AI_ACT} "FootRace/${file}")
|
||||
endforeach()
|
||||
|
||||
set(DSCRIPTS_SOURCES_AI_ACT ${DSCRIPTS_SOURCES_AI_ACT} PARENT_SCOPE)
|
48
dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp
Normal file
48
dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "BaseFootRaceManager.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Character.h"
|
||||
|
||||
void BaseFootRaceManager::OnStartup(Entity* self) {
|
||||
// TODO: Add to FootRaceStarter group
|
||||
}
|
||||
|
||||
void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1,
|
||||
int32_t param2, int32_t param3) {
|
||||
const auto splitArguments = GeneralUtils::SplitString(args, '_');
|
||||
if (splitArguments.size() > 1) {
|
||||
|
||||
const auto eventName = splitArguments[0];
|
||||
const auto player = EntityManager::Instance()->GetEntity(std::stoull(splitArguments[1]));
|
||||
|
||||
if (player != nullptr) {
|
||||
if (eventName == "updatePlayer") {
|
||||
UpdatePlayer(self, player->GetObjectID());
|
||||
} else if (IsPlayerInActivity(self, player->GetObjectID())) {
|
||||
if (eventName == "initialActivityScore") {
|
||||
auto* character = player->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
character->SetPlayerFlag(115, true);
|
||||
}
|
||||
|
||||
SetActivityScore(self, player->GetObjectID(), 1);
|
||||
} else if (eventName == "updatePlayerTrue") {
|
||||
auto* character = player->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
character->SetPlayerFlag(115, false);
|
||||
}
|
||||
|
||||
UpdatePlayer(self, player->GetObjectID(), true);
|
||||
} else if (eventName == "PlayerWon") {
|
||||
auto* character = player->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
character->SetPlayerFlag(115, false);
|
||||
if (param2 != -1) // Certain footraces set a flag
|
||||
character->SetPlayerFlag(param2, true);
|
||||
}
|
||||
|
||||
StopActivity(self, player->GetObjectID(), 0, param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
dScripts/ai/ACT/FootRace/BaseFootRaceManager.h
Normal file
9
dScripts/ai/ACT/FootRace/BaseFootRaceManager.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "ActivityManager.h"
|
||||
#include "CppScripts.h"
|
||||
|
||||
class BaseFootRaceManager : public ActivityManager {
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) override;
|
||||
};
|
3
dScripts/ai/ACT/FootRace/CMakeLists.txt
Normal file
3
dScripts/ai/ACT/FootRace/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
set(DSCRIPTS_SOURCES_AI_ACT_FOOTRACE
|
||||
"BaseFootRaceManager.cpp"
|
||||
PARENT_SCOPE)
|
20
dScripts/ai/AG/ActSharkPlayerDeathTrigger.cpp
Normal file
20
dScripts/ai/AG/ActSharkPlayerDeathTrigger.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "ActSharkPlayerDeathTrigger.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "MissionTaskType.h"
|
||||
#include "Entity.h"
|
||||
|
||||
void ActSharkPlayerDeathTrigger::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1,
|
||||
int32_t param2, int32_t param3) {
|
||||
if (args == "achieve") {
|
||||
auto missionComponent = sender->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
|
||||
missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, 8419);
|
||||
|
||||
if (sender->GetIsDead() || !sender->GetPlayerReadyForUpdates()) return; //Don't kill already dead players or players not ready
|
||||
|
||||
if (sender->GetCharacter()) {
|
||||
sender->Smash(self->GetObjectID(), eKillType::VIOLENT, u"big-shark-death");
|
||||
}
|
||||
}
|
||||
}
|
10
dScripts/ai/AG/ActSharkPlayerDeathTrigger.h
Normal file
10
dScripts/ai/AG/ActSharkPlayerDeathTrigger.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ActSharkPlayerDeathTrigger : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) override;
|
||||
};
|
||||
|
65
dScripts/ai/AG/AgBusDoor.cpp
Normal file
65
dScripts/ai/AG/AgBusDoor.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "AgBusDoor.h"
|
||||
#include "Entity.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ProximityMonitorComponent.h"
|
||||
|
||||
void AgBusDoor::OnStartup(Entity* self) {
|
||||
m_Counter = 0;
|
||||
m_OuterCounter = 0;
|
||||
self->SetProximityRadius(75, "busDoor");
|
||||
self->SetProximityRadius(85, "busDoorOuter");
|
||||
}
|
||||
|
||||
void AgBusDoor::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) {
|
||||
if (name != "busDoor" && name != "busDoorOuter") return;
|
||||
|
||||
// Make sure only humans are taken into account
|
||||
if (!entering->GetCharacter()) return;
|
||||
|
||||
auto* proximityMonitorComponent = self->GetComponent<ProximityMonitorComponent>();
|
||||
|
||||
if (proximityMonitorComponent == nullptr) return;
|
||||
|
||||
m_Counter = 0;
|
||||
m_OuterCounter = 0;
|
||||
|
||||
for (const auto& pair : proximityMonitorComponent->GetProximityObjects("busDoor")) {
|
||||
auto* entity = EntityManager::Instance()->GetEntity(pair.first);
|
||||
if (entity != nullptr && entity->IsPlayer()) m_Counter++;
|
||||
}
|
||||
|
||||
for (const auto& pair : proximityMonitorComponent->GetProximityObjects("busDoorOuter")) {
|
||||
auto* entity = EntityManager::Instance()->GetEntity(pair.first);
|
||||
if (entity != nullptr && entity->IsPlayer()) m_OuterCounter++;
|
||||
}
|
||||
|
||||
if (status == "ENTER") {
|
||||
// move up when a player is inside both radii
|
||||
if (m_Counter > 0) {
|
||||
MoveDoor(self, true);
|
||||
}
|
||||
} else if (status == "LEAVE") {
|
||||
// move down when no players are inside either radii
|
||||
if (m_Counter <= 0) {
|
||||
MoveDoor(self, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AgBusDoor::MoveDoor(Entity* self, bool bOpen) {
|
||||
if (bOpen) {
|
||||
GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 1, 0);
|
||||
} else {
|
||||
GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, 1);
|
||||
self->AddTimer("dustTimer", 2.0f);
|
||||
}
|
||||
|
||||
//This is currently commented out because it might be the reason that people's audio is cutting out.
|
||||
GameMessages::SendPlayNDAudioEmitter(self, UNASSIGNED_SYSTEM_ADDRESS, "{9a24f1fa-3177-4745-a2df-fbd996d6e1e3}");
|
||||
}
|
||||
|
||||
void AgBusDoor::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "dustTimer") {
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 642, u"create", "busDust", LWOOBJID_EMPTY, 1.0f, 1.0f, true);
|
||||
}
|
||||
}
|
15
dScripts/ai/AG/AgBusDoor.h
Normal file
15
dScripts/ai/AG/AgBusDoor.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgBusDoor : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self);
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status);
|
||||
void OnTimerDone(Entity* self, std::string timerName);
|
||||
private:
|
||||
void MoveDoor(Entity* self, bool bOpen);
|
||||
int m_Counter;
|
||||
int m_OuterCounter;
|
||||
};
|
||||
|
9
dScripts/ai/AG/AgDarkSpiderling.cpp
Normal file
9
dScripts/ai/AG/AgDarkSpiderling.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "AgDarkSpiderling.h"
|
||||
#include "BaseCombatAIComponent.h"
|
||||
|
||||
void AgDarkSpiderling::OnStartup(Entity* self) {
|
||||
auto* combatAI = self->GetComponent<BaseCombatAIComponent>();
|
||||
if (combatAI != nullptr) {
|
||||
combatAI->SetStunImmune(true);
|
||||
}
|
||||
}
|
6
dScripts/ai/AG/AgDarkSpiderling.h
Normal file
6
dScripts/ai/AG/AgDarkSpiderling.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgDarkSpiderling : public CppScripts::Script {
|
||||
void OnStartup(Entity* self) override;
|
||||
};
|
83
dScripts/ai/AG/AgFans.cpp
Normal file
83
dScripts/ai/AG/AgFans.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "AgFans.h"
|
||||
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
#include "PhantomPhysicsComponent.h"
|
||||
#include "RenderComponent.h"
|
||||
|
||||
void AgFans::OnStartup(Entity* self) {
|
||||
self->SetVar<bool>(u"alive", true);
|
||||
self->SetVar<bool>(u"on", false);
|
||||
|
||||
ToggleFX(self, false);
|
||||
|
||||
auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER));
|
||||
|
||||
if (renderComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderComponent->PlayEffect(495, u"fanOn", "fanOn");
|
||||
}
|
||||
|
||||
void AgFans::ToggleFX(Entity* self, bool hit) {
|
||||
std::string fanGroup = self->GetGroups()[0];
|
||||
std::vector<Entity*> fanVolumes = EntityManager::Instance()->GetEntitiesInGroup(fanGroup);
|
||||
|
||||
auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER));
|
||||
|
||||
if (renderComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fanVolumes.size() == 0 || !self->GetVar<bool>(u"alive")) return;
|
||||
|
||||
if (self->GetVar<bool>(u"on")) {
|
||||
GameMessages::SendPlayAnimation(self, u"fan-off");
|
||||
|
||||
renderComponent->StopEffect("fanOn");
|
||||
self->SetVar<bool>(u"on", false);
|
||||
|
||||
for (Entity* volume : fanVolumes) {
|
||||
PhantomPhysicsComponent* volumePhys = static_cast<PhantomPhysicsComponent*>(volume->GetComponent(COMPONENT_TYPE_PHANTOM_PHYSICS));
|
||||
if (!volumePhys) continue;
|
||||
volumePhys->SetPhysicsEffectActive(false);
|
||||
EntityManager::Instance()->SerializeEntity(volume);
|
||||
if (!hit) {
|
||||
Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0];
|
||||
GameMessages::SendPlayAnimation(fxObj, u"trigger");
|
||||
}
|
||||
}
|
||||
} else if (!self->GetVar<bool>(u"on") && self->GetVar<bool>(u"alive")) {
|
||||
GameMessages::SendPlayAnimation(self, u"fan-on");
|
||||
|
||||
renderComponent->PlayEffect(495, u"fanOn", "fanOn");
|
||||
self->SetVar<bool>(u"on", true);
|
||||
|
||||
for (Entity* volume : fanVolumes) {
|
||||
PhantomPhysicsComponent* volumePhys = static_cast<PhantomPhysicsComponent*>(volume->GetComponent(COMPONENT_TYPE_PHANTOM_PHYSICS));
|
||||
if (!volumePhys) continue;
|
||||
volumePhys->SetPhysicsEffectActive(true);
|
||||
EntityManager::Instance()->SerializeEntity(volume);
|
||||
if (!hit) {
|
||||
Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0];
|
||||
GameMessages::SendPlayAnimation(fxObj, u"idle");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AgFans::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) {
|
||||
if (args.length() == 0 || !self->GetVar<bool>(u"alive")) return;
|
||||
|
||||
if ((args == "turnOn" && self->GetVar<bool>(u"on")) || (args == "turnOff" && !self->GetVar<bool>(u"on"))) return;
|
||||
ToggleFX(self, false);
|
||||
}
|
||||
|
||||
void AgFans::OnDie(Entity* self, Entity* killer) {
|
||||
if (self->GetVar<bool>(u"on")) {
|
||||
ToggleFX(self, true);
|
||||
}
|
||||
self->SetVar<bool>(u"alive", false);
|
||||
}
|
20
dScripts/ai/AG/AgFans.h
Normal file
20
dScripts/ai/AG/AgFans.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgFans : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnDie(Entity* self, Entity* killer) override;
|
||||
void OnFireEventServerSide(
|
||||
Entity* self,
|
||||
Entity* sender,
|
||||
std::string args,
|
||||
int32_t param1,
|
||||
int32_t param2,
|
||||
int32_t param3
|
||||
) override;
|
||||
private:
|
||||
void ToggleFX(Entity* self, bool hit);
|
||||
};
|
||||
|
42
dScripts/ai/AG/AgImagSmashable.cpp
Normal file
42
dScripts/ai/AG/AgImagSmashable.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "AgImagSmashable.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "GameMessages.h"
|
||||
#include "DestroyableComponent.h"
|
||||
|
||||
void AgImagSmashable::OnDie(Entity* self, Entity* killer) {
|
||||
bool maxImagGreaterThanZero = false;
|
||||
|
||||
if (killer) {
|
||||
DestroyableComponent* dest = static_cast<DestroyableComponent*>(killer->GetComponent(COMPONENT_TYPE_DESTROYABLE));
|
||||
if (dest) {
|
||||
maxImagGreaterThanZero = dest->GetMaxImagination() > 0;
|
||||
}
|
||||
|
||||
if (maxImagGreaterThanZero) {
|
||||
int amount = GeneralUtils::GenerateRandomNumber<int>(0, 3);
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
GameMessages::SendDropClientLoot(killer, self->GetObjectID(), 935, 0, self->GetPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CrateAnimal(self);
|
||||
}
|
||||
|
||||
void AgImagSmashable::CrateAnimal(Entity* self) {
|
||||
int funnychance = GeneralUtils::GenerateRandomNumber<int>(0, 26);
|
||||
if (funnychance == 1) {
|
||||
EntityInfo info;
|
||||
info.lot = 8114;
|
||||
info.pos = self->GetPosition();
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = self->GetSpawnerID();
|
||||
info.spawnerNodeID = 0;
|
||||
|
||||
Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr);
|
||||
if (newEntity) {
|
||||
EntityManager::Instance()->ConstructEntity(newEntity);
|
||||
}
|
||||
}
|
||||
}
|
9
dScripts/ai/AG/AgImagSmashable.h
Normal file
9
dScripts/ai/AG/AgImagSmashable.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgImagSmashable : public CppScripts::Script {
|
||||
public:
|
||||
void OnDie(Entity* self, Entity* killer);
|
||||
private:
|
||||
void CrateAnimal(Entity* self);
|
||||
};
|
116
dScripts/ai/AG/AgJetEffectServer.cpp
Normal file
116
dScripts/ai/AG/AgJetEffectServer.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "AgJetEffectServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "EntityManager.h"
|
||||
#include "SkillComponent.h"
|
||||
|
||||
void AgJetEffectServer::OnUse(Entity* self, Entity* user) {
|
||||
if (inUse) {
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendNotifyClientObject(
|
||||
self->GetObjectID(),
|
||||
u"isInUse",
|
||||
0,
|
||||
0,
|
||||
LWOOBJID_EMPTY,
|
||||
"",
|
||||
UNASSIGNED_SYSTEM_ADDRESS
|
||||
);
|
||||
|
||||
inUse = true;
|
||||
|
||||
auto entities = EntityManager::Instance()->GetEntitiesInGroup("Jet_FX");
|
||||
|
||||
if (entities.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* effect = entities[0];
|
||||
|
||||
GameMessages::SendPlayFXEffect(effect, 641, u"create", "radarDish", LWOOBJID_EMPTY, 1, 1, true);
|
||||
|
||||
self->AddTimer("radarDish", 2);
|
||||
self->AddTimer("CineDone", 9);
|
||||
}
|
||||
|
||||
void AgJetEffectServer::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
auto entities = EntityManager::Instance()->GetEntitiesInGroup("Jet_FX");
|
||||
|
||||
if (entities.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* effect = entities[0];
|
||||
|
||||
auto groups = self->GetGroups();
|
||||
|
||||
if (groups.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
builder = target->GetObjectID();
|
||||
|
||||
const auto group = groups[0];
|
||||
|
||||
GameMessages::SendPlayAnimation(effect, u"jetFX");
|
||||
|
||||
self->AddTimer("PlayEffect", 2.5f);
|
||||
|
||||
if (group == "Base_Radar") {
|
||||
self->AddTimer("CineDone", 5);
|
||||
}
|
||||
}
|
||||
|
||||
void AgJetEffectServer::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "radarDish") {
|
||||
GameMessages::SendStopFXEffect(self, true, "radarDish");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (timerName == "PlayEffect") {
|
||||
auto entities = EntityManager::Instance()->GetEntitiesInGroup("mortarMain");
|
||||
|
||||
if (entities.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto size = entities.size();
|
||||
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto selected = GeneralUtils::GenerateRandomNumber<int>(0, size - 1);
|
||||
|
||||
auto* mortar = entities[selected];
|
||||
|
||||
Game::logger->Log("AgJetEffectServer", "Mortar (%i) (&d)", mortar->GetLOT(), mortar->HasComponent(COMPONENT_TYPE_SKILL));
|
||||
|
||||
mortar->SetOwnerOverride(builder);
|
||||
|
||||
SkillComponent* skillComponent;
|
||||
if (!mortar->TryGetComponent(COMPONENT_TYPE_SKILL, skillComponent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
skillComponent->CalculateBehavior(318, 3727, LWOOBJID_EMPTY, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (timerName == "CineDone") {
|
||||
GameMessages::SendNotifyClientObject(
|
||||
self->GetObjectID(),
|
||||
u"toggleInUse",
|
||||
-1,
|
||||
0,
|
||||
LWOOBJID_EMPTY,
|
||||
"",
|
||||
UNASSIGNED_SYSTEM_ADDRESS
|
||||
);
|
||||
|
||||
inUse = false;
|
||||
}
|
||||
}
|
15
dScripts/ai/AG/AgJetEffectServer.h
Normal file
15
dScripts/ai/AG/AgJetEffectServer.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgJetEffectServer final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
private:
|
||||
LWOOBJID builder;
|
||||
bool inUse;
|
||||
};
|
16
dScripts/ai/AG/AgPicnicBlanket.cpp
Normal file
16
dScripts/ai/AG/AgPicnicBlanket.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "AgPicnicBlanket.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void AgPicnicBlanket::OnUse(Entity* self, Entity* user) {
|
||||
GameMessages::SendTerminateInteraction(user->GetObjectID(), FROM_INTERACTION, self->GetObjectID());
|
||||
if (self->GetVar<bool>(u"active"))
|
||||
return;
|
||||
self->SetVar<bool>(u"active", true);
|
||||
|
||||
auto lootTable = std::unordered_map<LOT, int32_t>{ {935, 3} };
|
||||
LootGenerator::Instance().DropLoot(user, self, lootTable, 0, 0);
|
||||
|
||||
self->AddCallbackTimer(5.0f, [self]() {
|
||||
self->SetVar<bool>(u"active", false);
|
||||
});
|
||||
}
|
6
dScripts/ai/AG/AgPicnicBlanket.h
Normal file
6
dScripts/ai/AG/AgPicnicBlanket.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgPicnicBlanket : public CppScripts::Script {
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
60
dScripts/ai/AG/AgQbElevator.cpp
Normal file
60
dScripts/ai/AG/AgQbElevator.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "AgQbElevator.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void AgQbElevator::OnStartup(Entity* self) {
|
||||
|
||||
}
|
||||
|
||||
//when the QB is finished being built by a player
|
||||
void AgQbElevator::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
self->SetProximityRadius(proxRadius, "elevatorProx");
|
||||
self->SetI64(u"qbPlayer", target->GetObjectID());
|
||||
|
||||
float delayTime = killTime - endTime;
|
||||
if (delayTime < 1) delayTime = 1;
|
||||
|
||||
GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0,
|
||||
0, 0, MovementPlatformState::Stationary);
|
||||
|
||||
//add a timer that will kill the QB if no players get on in the killTime
|
||||
self->AddTimer("startKillTimer", killTime);
|
||||
}
|
||||
|
||||
void AgQbElevator::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) {
|
||||
//make sure we haven't already started pathing.
|
||||
if (self->GetBoolean(u"qbPlayerRdy")) return;
|
||||
|
||||
if (status == "ENTER") {
|
||||
Entity* builder = EntityManager::Instance()->GetEntity(self->GetI64(u"qbPlayer"));
|
||||
if (builder && builder == entering) {
|
||||
//the builder has entered so cancel the start timer and just start moving
|
||||
self->SetBoolean(u"qbPlayerRdy", true);
|
||||
self->CancelTimer("StartElevator");
|
||||
|
||||
GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0,
|
||||
1, 1, MovementPlatformState::Moving);
|
||||
} else if (!self->GetBoolean(u"StartTimer")) {
|
||||
self->SetBoolean(u"StartTimer", true);
|
||||
self->AddTimer("StartElevator", startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AgQbElevator::OnTimerDone(Entity* self, std::string timerName) {
|
||||
|
||||
if (timerName == "StartElevator") {
|
||||
GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0,
|
||||
1, 1, MovementPlatformState::Moving);
|
||||
} else if (timerName == "startKillTimer") {
|
||||
killTimerStartup(self);
|
||||
} else if (timerName == "KillTimer") {
|
||||
self->Smash(self->GetObjectID(), VIOLENT);
|
||||
}
|
||||
}
|
||||
|
||||
void AgQbElevator::killTimerStartup(Entity* self) const {
|
||||
self->CancelAllTimers();
|
||||
self->AddTimer("KillTimer", endTime);
|
||||
self->SetNetworkVar<float>(u"startEffect", endTime); // Blinking effect
|
||||
}
|
19
dScripts/ai/AG/AgQbElevator.h
Normal file
19
dScripts/ai/AG/AgQbElevator.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgQbElevator : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
|
||||
private:
|
||||
void killTimerStartup(Entity* self) const;
|
||||
|
||||
// constants
|
||||
float endTime = 4.0f;
|
||||
float startTime = 8.0f;
|
||||
float killTime = 10.0f;
|
||||
float proxRadius = 5.0f;
|
||||
};
|
15
dScripts/ai/AG/AgQbWall.cpp
Normal file
15
dScripts/ai/AG/AgQbWall.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "AgQbWall.h"
|
||||
|
||||
void AgQbWall::OnRebuildComplete(Entity* self, Entity* player) {
|
||||
self->SetVar(u"player", player->GetObjectID());
|
||||
auto targetWallSpawners = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"spawner"));
|
||||
if (targetWallSpawners != "") {
|
||||
auto groupObjs = EntityManager::Instance()->GetEntitiesInGroup(targetWallSpawners);
|
||||
for (auto* obj : groupObjs) {
|
||||
if (obj) {
|
||||
obj->SetVar(u"player", player->GetObjectID());
|
||||
obj->OnFireEventServerSide(self, "spawnMobs");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
dScripts/ai/AG/AgQbWall.h
Normal file
7
dScripts/ai/AG/AgQbWall.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgQbWall : public CppScripts::Script {
|
||||
public:
|
||||
void OnRebuildComplete(Entity* self, Entity* player) override;
|
||||
};
|
11
dScripts/ai/AG/AgSalutingNpcs.cpp
Normal file
11
dScripts/ai/AG/AgSalutingNpcs.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "AgSalutingNpcs.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
|
||||
void AgSalutingNpcs::OnEmoteReceived(Entity* self, const int32_t emote, Entity* target) {
|
||||
if (emote != 356) {
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendPlayAnimation(self, u"salutePlayer");
|
||||
}
|
8
dScripts/ai/AG/AgSalutingNpcs.h
Normal file
8
dScripts/ai/AG/AgSalutingNpcs.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgSalutingNpcs final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnEmoteReceived(Entity* self, int32_t emote, Entity* target) override;
|
||||
};
|
8
dScripts/ai/AG/AgShipPlayerDeathTrigger.cpp
Normal file
8
dScripts/ai/AG/AgShipPlayerDeathTrigger.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "AgShipPlayerDeathTrigger.h"
|
||||
#include "Entity.h"
|
||||
|
||||
void AgShipPlayerDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (target->GetLOT() == 1 && !target->GetIsDead()) {
|
||||
target->Smash(self->GetObjectID(), eKillType::VIOLENT, u"electro-shock-death");
|
||||
}
|
||||
}
|
9
dScripts/ai/AG/AgShipPlayerDeathTrigger.h
Normal file
9
dScripts/ai/AG/AgShipPlayerDeathTrigger.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgShipPlayerDeathTrigger : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnCollisionPhantom(Entity* self, Entity* target);
|
||||
};
|
||||
|
20
dScripts/ai/AG/AgShipPlayerShockServer.cpp
Normal file
20
dScripts/ai/AG/AgShipPlayerShockServer.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "AgShipPlayerShockServer.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void AgShipPlayerShockServer::OnUse(Entity* self, Entity* user) {
|
||||
GameMessages::SendTerminateInteraction(user->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID());
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
GameMessages::SendPlayAnimation(user, shockAnim);
|
||||
GameMessages::SendKnockback(user->GetObjectID(), self->GetObjectID(), self->GetObjectID(), 0, NiPoint3(-20, 10, -20));
|
||||
|
||||
GameMessages::SendPlayFXEffect(self, 1430, u"create", "console_sparks", LWOOBJID_EMPTY, 1.0, 1.0, true);
|
||||
self->AddTimer("FXTime", fxTime);
|
||||
}
|
||||
|
||||
void AgShipPlayerShockServer::OnTimerDone(Entity* self, std::string timerName) {
|
||||
GameMessages::SendStopFXEffect(self, true, "console_sparks");
|
||||
active = false;
|
||||
}
|
14
dScripts/ai/AG/AgShipPlayerShockServer.h
Normal file
14
dScripts/ai/AG/AgShipPlayerShockServer.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgShipPlayerShockServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user);
|
||||
void OnTimerDone(Entity* self, std::string timerName);
|
||||
private:
|
||||
std::u16string shockAnim = u"knockback-recovery";
|
||||
float fxTime = 2.0;
|
||||
bool active = false;
|
||||
};
|
||||
|
103
dScripts/ai/AG/AgSpaceStuff.cpp
Normal file
103
dScripts/ai/AG/AgSpaceStuff.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "AgSpaceStuff.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "GameMessages.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void AgSpaceStuff::OnStartup(Entity* self) {
|
||||
self->AddTimer("FloaterScale", 5.0f);
|
||||
|
||||
EntityInfo info{};
|
||||
|
||||
info.pos = { -418, 585, -30 };
|
||||
info.lot = 33;
|
||||
info.spawnerID = self->GetObjectID();
|
||||
|
||||
auto* ref = EntityManager::Instance()->CreateEntity(info);
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(ref);
|
||||
|
||||
self->SetVar(u"ShakeObject", ref->GetObjectID());
|
||||
|
||||
self->AddTimer("ShipShakeIdle", 2.0f);
|
||||
self->SetVar(u"RandomTime", 10);
|
||||
}
|
||||
|
||||
void AgSpaceStuff::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "FloaterScale") {
|
||||
int scaleType = GeneralUtils::GenerateRandomNumber<int>(1, 5);
|
||||
|
||||
GameMessages::SendPlayAnimation(self, u"scale_0" + GeneralUtils::to_u16string(scaleType));
|
||||
self->AddTimer("FloaterPath", 0.4);
|
||||
} else if (timerName == "FloaterPath") {
|
||||
int pathType = GeneralUtils::GenerateRandomNumber<int>(1, 4);
|
||||
int randTime = GeneralUtils::GenerateRandomNumber<int>(20, 25);
|
||||
|
||||
GameMessages::SendPlayAnimation(self, u"path_0" + (GeneralUtils::to_u16string(pathType)));
|
||||
self->AddTimer("FloaterScale", randTime);
|
||||
} else if (timerName == "ShipShakeExplode") {
|
||||
DoShake(self, true);
|
||||
} else if (timerName == "ShipShakeIdle") {
|
||||
DoShake(self, false);
|
||||
}
|
||||
}
|
||||
|
||||
void AgSpaceStuff::DoShake(Entity* self, bool explodeIdle) {
|
||||
|
||||
if (!explodeIdle) {
|
||||
auto* ref = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"ShakeObject"));
|
||||
|
||||
const auto randomTime = self->GetVar<int>(u"RandomTime");
|
||||
auto time = GeneralUtils::GenerateRandomNumber<int>(0, randomTime + 1);
|
||||
|
||||
if (time < randomTime / 2) {
|
||||
time += randomTime / 2;
|
||||
}
|
||||
|
||||
self->AddTimer("ShipShakeIdle", static_cast<float>(time));
|
||||
|
||||
if (ref)
|
||||
GameMessages::SendPlayEmbeddedEffectOnAllClientsNearObject(ref, FXName, ref->GetObjectID(), 500.0f);
|
||||
|
||||
auto* debrisObject = GetEntityInGroup(DebrisFX);
|
||||
|
||||
if (debrisObject)
|
||||
GameMessages::SendPlayFXEffect(debrisObject, -1, u"DebrisFall", "Debris", LWOOBJID_EMPTY, 1.0f, 1.0f, true);
|
||||
|
||||
const auto randomFx = GeneralUtils::GenerateRandomNumber<int>(0, 3);
|
||||
|
||||
auto* shipFxObject = GetEntityInGroup(ShipFX);
|
||||
if (shipFxObject) {
|
||||
std::string effectType = "shipboom" + std::to_string(randomFx);
|
||||
GameMessages::SendPlayFXEffect(shipFxObject, 559, GeneralUtils::ASCIIToUTF16(effectType), "FX", LWOOBJID_EMPTY, 1.0f, 1.0f, true);
|
||||
}
|
||||
|
||||
self->AddTimer("ShipShakeExplode", 5.0f);
|
||||
|
||||
auto* shipFxObject2 = GetEntityInGroup(ShipFX2);
|
||||
if (shipFxObject2)
|
||||
GameMessages::SendPlayAnimation(shipFxObject2, u"explosion");
|
||||
} else {
|
||||
auto* shipFxObject = GetEntityInGroup(ShipFX);
|
||||
auto* shipFxObject2 = GetEntityInGroup(ShipFX2);
|
||||
|
||||
if (shipFxObject)
|
||||
GameMessages::SendPlayAnimation(shipFxObject, u"idle");
|
||||
|
||||
if (shipFxObject2)
|
||||
GameMessages::SendPlayAnimation(shipFxObject2, u"idle");
|
||||
}
|
||||
}
|
||||
|
||||
Entity* AgSpaceStuff::GetEntityInGroup(const std::string& group) {
|
||||
auto entities = EntityManager::Instance()->GetEntitiesInGroup(group);
|
||||
Entity* en = nullptr;
|
||||
|
||||
for (auto entity : entities) {
|
||||
if (entity) {
|
||||
en = entity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return en;
|
||||
}
|
18
dScripts/ai/AG/AgSpaceStuff.h
Normal file
18
dScripts/ai/AG/AgSpaceStuff.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgSpaceStuff : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self);
|
||||
void OnTimerDone(Entity* self, std::string timerName);
|
||||
void DoShake(Entity* self, bool explodeIdle);
|
||||
|
||||
std::string DebrisFX = "DebrisFX";
|
||||
std::string ShipFX = "ShipFX";
|
||||
std::string ShipFX2 = "ShipFX2";
|
||||
std::u16string FXName = u"camshake-bridge";
|
||||
|
||||
private:
|
||||
Entity* GetEntityInGroup(const std::string& group);
|
||||
};
|
||||
|
16
dScripts/ai/AG/AgStagePlatforms.cpp
Normal file
16
dScripts/ai/AG/AgStagePlatforms.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "AgStagePlatforms.h"
|
||||
#include "MovingPlatformComponent.h"
|
||||
|
||||
void AgStagePlatforms::OnStartup(Entity* self) {
|
||||
auto* component = self->GetComponent<MovingPlatformComponent>();
|
||||
if (component) {
|
||||
component->SetNoAutoStart(true);
|
||||
component->StopPathing();
|
||||
}
|
||||
}
|
||||
|
||||
void AgStagePlatforms::OnWaypointReached(Entity* self, uint32_t waypointIndex) {
|
||||
auto* component = self->GetComponent<MovingPlatformComponent>();
|
||||
if (waypointIndex == 0 && component)
|
||||
component->StopPathing();
|
||||
}
|
8
dScripts/ai/AG/AgStagePlatforms.h
Normal file
8
dScripts/ai/AG/AgStagePlatforms.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgStagePlatforms : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnWaypointReached(Entity* self, uint32_t waypointIndex) override;
|
||||
};
|
16
dScripts/ai/AG/AgStromlingProperty.cpp
Normal file
16
dScripts/ai/AG/AgStromlingProperty.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "AgStromlingProperty.h"
|
||||
#include "MovementAIComponent.h"
|
||||
|
||||
void AgStromlingProperty::OnStartup(Entity* self) {
|
||||
auto movementInfo = MovementAIInfo{
|
||||
"Wander",
|
||||
71,
|
||||
3,
|
||||
100,
|
||||
1,
|
||||
4
|
||||
};
|
||||
|
||||
auto* movementAIComponent = new MovementAIComponent(self, movementInfo);
|
||||
self->AddComponent(COMPONENT_TYPE_MOVEMENT_AI, movementAIComponent);
|
||||
}
|
6
dScripts/ai/AG/AgStromlingProperty.h
Normal file
6
dScripts/ai/AG/AgStromlingProperty.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgStromlingProperty : public CppScripts::Script {
|
||||
void OnStartup(Entity* self) override;
|
||||
};
|
17
dScripts/ai/AG/AgTurret.cpp
Normal file
17
dScripts/ai/AG/AgTurret.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "AgTurret.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void AgTurret::OnStartup(Entity* self) {
|
||||
// TODO: do this legit way
|
||||
self->AddTimer("killTurret", 20.0f);
|
||||
}
|
||||
|
||||
void AgTurret::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "killTurret") {
|
||||
self->ScheduleKillAfterUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void AgTurret::OnRebuildStart(Entity* self, Entity* user) {
|
||||
GameMessages::SendLockNodeRotation(self, "base");
|
||||
}
|
8
dScripts/ai/AG/AgTurret.h
Normal file
8
dScripts/ai/AG/AgTurret.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class AgTurret : public CppScripts::Script {
|
||||
void OnStartup(Entity* self);
|
||||
void OnTimerDone(Entity* self, std::string timerName);
|
||||
void OnRebuildStart(Entity* self, Entity* user);
|
||||
};
|
18
dScripts/ai/AG/CMakeLists.txt
Normal file
18
dScripts/ai/AG/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
set(DSCRIPTS_SOURCES_AI_AG
|
||||
"AgShipPlayerDeathTrigger.cpp"
|
||||
"AgSpaceStuff.cpp"
|
||||
"AgShipPlayerShockServer.cpp"
|
||||
"AgImagSmashable.cpp"
|
||||
"ActSharkPlayerDeathTrigger.cpp"
|
||||
"AgBusDoor.cpp"
|
||||
"AgTurret.cpp"
|
||||
"AgFans.cpp"
|
||||
"AgSalutingNpcs.cpp"
|
||||
"AgJetEffectServer.cpp"
|
||||
"AgQbElevator.cpp"
|
||||
"AgStromlingProperty.cpp"
|
||||
"AgDarkSpiderling.cpp"
|
||||
"AgPicnicBlanket.cpp"
|
||||
"AgStagePlatforms.cpp"
|
||||
"AgQbWall.cpp"
|
||||
PARENT_SCOPE)
|
81
dScripts/ai/CMakeLists.txt
Normal file
81
dScripts/ai/CMakeLists.txt
Normal file
@@ -0,0 +1,81 @@
|
||||
set(DSCRIPTS_SOURCES_AI)
|
||||
|
||||
add_subdirectory(ACT)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_ACT})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "ACT/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(AG)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_AG})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "AG/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(FV)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_FV})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "FV/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(GENERAL)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_GENERAL})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "GENERAL/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(GF)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_GF})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "GF/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(MINIGAME)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_MINIGAME})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "MINIGAME/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(NP)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_NP})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "NP/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(NS)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_NS})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "NS/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(PETS)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_PETS})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "PETS/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(PROPERTY)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_PROPERTY})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "PROPERTY/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(RACING)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_RACING})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "RACING/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(SPEC)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_SPEC})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "SPEC/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(WILD)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_WILD})
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} "WILD/${file}")
|
||||
endforeach()
|
||||
|
||||
set(DSCRIPTS_SOURCES_AI ${DSCRIPTS_SOURCES_AI} PARENT_SCOPE)
|
17
dScripts/ai/FV/ActNinjaTurret.cpp
Normal file
17
dScripts/ai/FV/ActNinjaTurret.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "ActNinjaTurret.h"
|
||||
|
||||
void ActNinjaTurret::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state == eRebuildState::REBUILD_COMPLETED) {
|
||||
self->SetVar(u"AmBuilt", true);
|
||||
} else if (state == eRebuildState::REBUILD_RESETTING) {
|
||||
self->SetVar(u"AmBuilt", false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ActNinjaTurret::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) {
|
||||
if (args == "ISpawned" && self->GetVar<bool>(u"AmBuilt")) {
|
||||
sender->Smash();
|
||||
}
|
||||
}
|
11
dScripts/ai/FV/ActNinjaTurret.h
Normal file
11
dScripts/ai/FV/ActNinjaTurret.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ActNinjaTurret : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) override;
|
||||
};
|
||||
|
61
dScripts/ai/FV/ActParadoxPipeFix.cpp
Normal file
61
dScripts/ai/FV/ActParadoxPipeFix.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "ActParadoxPipeFix.h"
|
||||
#include "EntityManager.h"
|
||||
#include "RebuildComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
const auto myGroup = "AllPipes";
|
||||
|
||||
const auto groupObjs = EntityManager::Instance()->GetEntitiesInGroup(myGroup);
|
||||
|
||||
auto indexCount = 0;
|
||||
|
||||
self->SetVar(u"PlayerID", target->GetObjectID());
|
||||
|
||||
for (auto* object : groupObjs) {
|
||||
if (object == self) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* rebuildComponent = object->GetComponent<RebuildComponent>();
|
||||
|
||||
if (rebuildComponent->GetState() == REBUILD_COMPLETED) {
|
||||
indexCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (indexCount >= 2) {
|
||||
const auto refinery = EntityManager::Instance()->GetEntitiesInGroup("Paradox");
|
||||
|
||||
if (!refinery.empty()) {
|
||||
GameMessages::SendPlayFXEffect(refinery[0]->GetObjectID(), 3999, u"create", "pipeFX");
|
||||
}
|
||||
|
||||
for (auto* object : groupObjs) {
|
||||
auto* player = EntityManager::Instance()->GetEntity(object->GetVar<LWOOBJID>(u"PlayerID"));
|
||||
|
||||
if (player != nullptr) {
|
||||
auto* missionComponent = player->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponent != nullptr) {
|
||||
missionComponent->ForceProgressTaskType(769, 1, 1, false);
|
||||
}
|
||||
|
||||
GameMessages::SendPlayCinematic(player->GetObjectID(), u"ParadoxPipeFinish", player->GetSystemAddress(), true, true, false, false, 0, false, 2.0f);
|
||||
}
|
||||
|
||||
object->SetVar(u"PlayerID", LWOOBJID_EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActParadoxPipeFix::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state == REBUILD_RESETTING) {
|
||||
const auto refinery = EntityManager::Instance()->GetEntitiesInGroup("Paradox");
|
||||
|
||||
if (!refinery.empty()) {
|
||||
GameMessages::SendStopFXEffect(refinery[0], true, "pipeFX");
|
||||
}
|
||||
}
|
||||
}
|
10
dScripts/ai/FV/ActParadoxPipeFix.h
Normal file
10
dScripts/ai/FV/ActParadoxPipeFix.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ActParadoxPipeFix : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
};
|
||||
|
18
dScripts/ai/FV/CMakeLists.txt
Normal file
18
dScripts/ai/FV/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
set(DSCRIPTS_SOURCES_AI_FV
|
||||
"ActNinjaTurret.cpp"
|
||||
"FvFlyingCreviceDragon.cpp"
|
||||
"FvDragonSmashingGolemQb.cpp"
|
||||
"FvFreeGfNinjas.cpp"
|
||||
"FvPandaSpawnerServer.cpp"
|
||||
"FvPandaServer.cpp"
|
||||
"FvBrickPuzzleServer.cpp"
|
||||
"FvConsoleLeftQuickbuild.cpp"
|
||||
"FvConsoleRightQuickbuild.cpp"
|
||||
"FvFacilityBrick.cpp"
|
||||
"FvFacilityPipes.cpp"
|
||||
"ActParadoxPipeFix.cpp"
|
||||
"FvNinjaGuard.cpp"
|
||||
"FvPassThroughWall.cpp"
|
||||
"FvBounceOverWall.cpp"
|
||||
"FvMaelstromGeyser.cpp"
|
||||
PARENT_SCOPE)
|
10
dScripts/ai/FV/FvBounceOverWall.cpp
Normal file
10
dScripts/ai/FV/FvBounceOverWall.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "FvBounceOverWall.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void FvBounceOverWall::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
auto missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (missionComponent == nullptr) return;
|
||||
|
||||
// We force progress here to the Gate Crasher mission due to an overlap in LOTs with the 'Shark Bite' missions.
|
||||
missionComponent->ForceProgress(GateCrasherMissionId, GateCrasherMissionUid, 1);
|
||||
}
|
22
dScripts/ai/FV/FvBounceOverWall.h
Normal file
22
dScripts/ai/FV/FvBounceOverWall.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvBounceOverWall : public CppScripts::Script
|
||||
{
|
||||
/**
|
||||
* @brief When a collision has been made with self this method is called.
|
||||
*
|
||||
* @param self The Entity that called this function.
|
||||
* @param target The target Entity of self.
|
||||
*/
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
private:
|
||||
/**
|
||||
* MissionId for the Gate Crasher mission.
|
||||
*/
|
||||
int32_t GateCrasherMissionId = 849;
|
||||
/**
|
||||
* MissionUid for the Gate Crasher mission.
|
||||
*/
|
||||
int32_t GateCrasherMissionUid = 1241;
|
||||
};
|
68
dScripts/ai/FV/FvBrickPuzzleServer.cpp
Normal file
68
dScripts/ai/FV/FvBrickPuzzleServer.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "FvBrickPuzzleServer.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "Spawner.h"
|
||||
#include "RebuildComponent.h"
|
||||
|
||||
void FvBrickPuzzleServer::OnStartup(Entity* self) {
|
||||
const auto myGroup = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"spawner_name"));
|
||||
|
||||
int32_t pipeNum = 0;
|
||||
if (!GeneralUtils::TryParse<int32_t>(myGroup.substr(10, 1), pipeNum)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipeNum != 1) {
|
||||
self->AddTimer("reset", 30);
|
||||
}
|
||||
}
|
||||
|
||||
void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) {
|
||||
const auto myGroup = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"spawner_name"));
|
||||
|
||||
int32_t pipeNum = 0;
|
||||
if (!GeneralUtils::TryParse<int32_t>(myGroup.substr(10, 1), pipeNum)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto pipeGroup = myGroup.substr(0, 10);
|
||||
|
||||
const auto nextPipeNum = pipeNum + 1;
|
||||
|
||||
const auto samePipeSpawners = dZoneManager::Instance()->GetSpawnersByName(myGroup);
|
||||
|
||||
if (!samePipeSpawners.empty()) {
|
||||
samePipeSpawners[0]->SoftReset();
|
||||
|
||||
samePipeSpawners[0]->Deactivate();
|
||||
}
|
||||
|
||||
if (killer != nullptr && killer->IsPlayer()) {
|
||||
const auto nextPipe = pipeGroup + std::to_string(nextPipeNum);
|
||||
|
||||
const auto nextPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe);
|
||||
|
||||
if (!nextPipeSpawners.empty()) {
|
||||
nextPipeSpawners[0]->Activate();
|
||||
}
|
||||
} else {
|
||||
const auto nextPipe = pipeGroup + "1";
|
||||
|
||||
const auto firstPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe);
|
||||
|
||||
if (!firstPipeSpawners.empty()) {
|
||||
firstPipeSpawners[0]->Activate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FvBrickPuzzleServer::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "reset") {
|
||||
auto* rebuildComponent = self->GetComponent<RebuildComponent>();
|
||||
|
||||
if (rebuildComponent != nullptr && rebuildComponent->GetState() == REBUILD_OPEN) {
|
||||
self->Smash(self->GetObjectID(), SILENT);
|
||||
}
|
||||
}
|
||||
}
|
10
dScripts/ai/FV/FvBrickPuzzleServer.h
Normal file
10
dScripts/ai/FV/FvBrickPuzzleServer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvBrickPuzzleServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnDie(Entity* self, Entity* killer) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
47
dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp
Normal file
47
dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "FvConsoleLeftQuickbuild.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void FvConsoleLeftQuickbuild::OnStartup(Entity* self) {
|
||||
self->SetVar(u"IAmBuilt", false);
|
||||
self->SetVar(u"AmActive", false);
|
||||
}
|
||||
|
||||
void FvConsoleLeftQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state == REBUILD_COMPLETED) {
|
||||
self->SetVar(u"IAmBuilt", true);
|
||||
|
||||
const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility");
|
||||
|
||||
if (!objects.empty()) {
|
||||
objects[0]->NotifyObject(self, "ConsoleLeftUp");
|
||||
}
|
||||
} else if (state == REBUILD_RESETTING) {
|
||||
self->SetVar(u"IAmBuilt", false);
|
||||
self->SetVar(u"AmActive", false);
|
||||
|
||||
const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility");
|
||||
|
||||
if (!objects.empty()) {
|
||||
objects[0]->NotifyObject(self, "ConsoleLeftDown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FvConsoleLeftQuickbuild::OnUse(Entity* self, Entity* user) {
|
||||
if (self->GetVar<bool>(u"AmActive")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->GetVar<bool>(u"IAmBuilt")) {
|
||||
self->SetVar(u"AmActive", true);
|
||||
|
||||
const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility");
|
||||
|
||||
if (!objects.empty()) {
|
||||
objects[0]->NotifyObject(self, "ConsoleLeftActive");
|
||||
}
|
||||
}
|
||||
|
||||
GameMessages::SendTerminateInteraction(user->GetObjectID(), FROM_INTERACTION, self->GetObjectID());
|
||||
}
|
10
dScripts/ai/FV/FvConsoleLeftQuickbuild.h
Normal file
10
dScripts/ai/FV/FvConsoleLeftQuickbuild.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvConsoleLeftQuickbuild : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
47
dScripts/ai/FV/FvConsoleRightQuickbuild.cpp
Normal file
47
dScripts/ai/FV/FvConsoleRightQuickbuild.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "FvConsoleRightQuickbuild.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void FvConsoleRightQuickbuild::OnStartup(Entity* self) {
|
||||
self->SetVar(u"IAmBuilt", false);
|
||||
self->SetVar(u"AmActive", false);
|
||||
}
|
||||
|
||||
void FvConsoleRightQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state == REBUILD_COMPLETED) {
|
||||
self->SetVar(u"IAmBuilt", true);
|
||||
|
||||
const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility");
|
||||
|
||||
if (!objects.empty()) {
|
||||
objects[0]->NotifyObject(self, "ConsoleRightUp");
|
||||
}
|
||||
} else if (state == REBUILD_RESETTING) {
|
||||
self->SetVar(u"IAmBuilt", false);
|
||||
self->SetVar(u"AmActive", false);
|
||||
|
||||
const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility");
|
||||
|
||||
if (!objects.empty()) {
|
||||
objects[0]->NotifyObject(self, "ConsoleRightDown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FvConsoleRightQuickbuild::OnUse(Entity* self, Entity* user) {
|
||||
if (self->GetVar<bool>(u"AmActive")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->GetVar<bool>(u"IAmBuilt")) {
|
||||
self->SetVar(u"AmActive", true);
|
||||
|
||||
const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility");
|
||||
|
||||
if (!objects.empty()) {
|
||||
objects[0]->NotifyObject(self, "ConsoleRightActive");
|
||||
}
|
||||
}
|
||||
|
||||
GameMessages::SendTerminateInteraction(user->GetObjectID(), FROM_INTERACTION, self->GetObjectID());
|
||||
}
|
10
dScripts/ai/FV/FvConsoleRightQuickbuild.h
Normal file
10
dScripts/ai/FV/FvConsoleRightQuickbuild.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvConsoleRightQuickbuild : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
30
dScripts/ai/FV/FvDragonSmashingGolemQb.cpp
Normal file
30
dScripts/ai/FV/FvDragonSmashingGolemQb.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "FvDragonSmashingGolemQb.h"
|
||||
#include "GameMessages.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void FvDragonSmashingGolemQb::OnStartup(Entity* self) {
|
||||
self->AddTimer("GolemBreakTimer", 10.5f);
|
||||
}
|
||||
|
||||
void FvDragonSmashingGolemQb::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "GolemBreakTimer") {
|
||||
self->Smash();
|
||||
}
|
||||
}
|
||||
|
||||
void FvDragonSmashingGolemQb::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state == eRebuildState::REBUILD_COMPLETED) {
|
||||
GameMessages::SendPlayAnimation(self, u"dragonsmash");
|
||||
|
||||
const auto dragonId = self->GetVar<LWOOBJID>(u"Dragon");
|
||||
|
||||
auto* dragon = EntityManager::Instance()->GetEntity(dragonId);
|
||||
|
||||
if (dragon != nullptr) {
|
||||
dragon->OnFireEventServerSide(self, "rebuildDone");
|
||||
}
|
||||
|
||||
self->CancelTimer("GolemBreakTimer");
|
||||
self->AddTimer("GolemBreakTimer", 10.5f);
|
||||
}
|
||||
}
|
10
dScripts/ai/FV/FvDragonSmashingGolemQb.h
Normal file
10
dScripts/ai/FV/FvDragonSmashingGolemQb.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvDragonSmashingGolemQb : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
};
|
97
dScripts/ai/FV/FvFacilityBrick.cpp
Normal file
97
dScripts/ai/FV/FvFacilityBrick.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "FvFacilityBrick.h"
|
||||
#include "GameMessages.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void FvFacilityBrick::OnStartup(Entity* self) {
|
||||
self->SetVar(u"ConsoleLEFTActive", false);
|
||||
self->SetVar(u"ConsoleRIGHTtActive", false);
|
||||
}
|
||||
|
||||
void FvFacilityBrick::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) {
|
||||
auto* brickSpawner = dZoneManager::Instance()->GetSpawnersByName("ImaginationBrick")[0];
|
||||
auto* bugSpawner = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug")[0];
|
||||
auto* canisterSpawner = dZoneManager::Instance()->GetSpawnersByName("BrickCanister")[0];
|
||||
|
||||
if (name == "ConsoleLeftUp") {
|
||||
GameMessages::SendStopFXEffect(self, true, "LeftPipeOff");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2775, u"create", "LeftPipeEnergy");
|
||||
} else if (name == "ConsoleLeftDown") {
|
||||
self->SetVar(u"ConsoleLEFTActive", false);
|
||||
|
||||
GameMessages::SendStopFXEffect(self, true, "LeftPipeEnergy");
|
||||
GameMessages::SendStopFXEffect(self, true, "LeftPipeOn");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2774, u"create", "LeftPipeOff");
|
||||
} else if (name == "ConsoleLeftActive") {
|
||||
self->SetVar(u"ConsoleLEFTActive", true);
|
||||
|
||||
GameMessages::SendStopFXEffect(self, true, "LeftPipeEnergy");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2776, u"create", "LeftPipeOn");
|
||||
}
|
||||
|
||||
else if (name == "ConsoleRightUp") {
|
||||
GameMessages::SendStopFXEffect(self, true, "RightPipeOff");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2778, u"create", "RightPipeEnergy");
|
||||
} else if (name == "ConsoleRightDown") {
|
||||
self->SetVar(u"ConsoleRIGHTActive", false);
|
||||
|
||||
GameMessages::SendStopFXEffect(self, true, "RightPipeEnergy");
|
||||
GameMessages::SendStopFXEffect(self, true, "RightPipeOn");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2777, u"create", "RightPipeOff");
|
||||
} else if (name == "ConsoleRightActive") {
|
||||
self->SetVar(u"ConsoleRIGHTActive", true);
|
||||
|
||||
GameMessages::SendStopFXEffect(self, true, "RightPipeOff");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2779, u"create", "RightPipeEnergy");
|
||||
}
|
||||
|
||||
if (self->GetVar<bool>(u"ConsoleLEFTActive") && self->GetVar<bool>(u"ConsoleRIGHTActive")) {
|
||||
auto* object = EntityManager::Instance()->GetEntitiesInGroup("Brick")[0];
|
||||
|
||||
if (object != nullptr) {
|
||||
GameMessages::SendPlayFXEffect(object->GetObjectID(), 122, u"create", "bluebrick");
|
||||
GameMessages::SendPlayFXEffect(object->GetObjectID(), 1034, u"cast", "imaginationexplosion");
|
||||
}
|
||||
|
||||
object = EntityManager::Instance()->GetEntitiesInGroup("Canister")[0];
|
||||
|
||||
if (object != nullptr) {
|
||||
object->Smash(self->GetObjectID(), SILENT);
|
||||
}
|
||||
|
||||
canisterSpawner->Reset();
|
||||
canisterSpawner->Deactivate();
|
||||
} else if (self->GetVar<bool>(u"ConsoleLEFTActive") || self->GetVar<bool>(u"ConsoleRIGHTActive")) {
|
||||
brickSpawner->Activate();
|
||||
|
||||
auto* object = EntityManager::Instance()->GetEntitiesInGroup("Brick")[0];
|
||||
|
||||
if (object != nullptr) {
|
||||
GameMessages::SendStopFXEffect(object, true, "bluebrick");
|
||||
}
|
||||
|
||||
bugSpawner->Reset();
|
||||
bugSpawner->Deactivate();
|
||||
|
||||
canisterSpawner->Reset();
|
||||
canisterSpawner->Activate();
|
||||
} else {
|
||||
brickSpawner->Reset();
|
||||
brickSpawner->Deactivate();
|
||||
|
||||
bugSpawner->Reset();
|
||||
bugSpawner->Activate();
|
||||
}
|
||||
}
|
||||
|
||||
void FvFacilityBrick::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) {
|
||||
if (args != "PlayFX") {
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2774, u"create", "LeftPipeOff");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2777, u"create", "RightPipeOff");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2750, u"create", "imagination_canister");
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 2751, u"create", "canister_light_filler");
|
||||
}
|
11
dScripts/ai/FV/FvFacilityBrick.h
Normal file
11
dScripts/ai/FV/FvFacilityBrick.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvFacilityBrick : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1 = 0, int32_t param2 = 0) override;
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) override;
|
||||
};
|
10
dScripts/ai/FV/FvFacilityPipes.cpp
Normal file
10
dScripts/ai/FV/FvFacilityPipes.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "FvFacilityPipes.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void FvFacilityPipes::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
|
||||
if (args == "startFX") {
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), m_LeftPipeEffectID, m_EffectType, m_LeftPipeEffectName);
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), m_RightPipeEffectID, m_EffectType, m_RightPipeEffectName);
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), m_ImaginationCanisterEffectID, m_EffectType, m_ImaginationCanisterEffectName);
|
||||
}
|
||||
}
|
15
dScripts/ai/FV/FvFacilityPipes.h
Normal file
15
dScripts/ai/FV/FvFacilityPipes.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvFacilityPipes : public CppScripts::Script {
|
||||
public:
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override;
|
||||
private:
|
||||
const std::u16string m_EffectType = u"create";
|
||||
const std::string m_LeftPipeEffectName = "LeftPipeOff";
|
||||
const int32_t m_LeftPipeEffectID = 2774;
|
||||
const std::string m_RightPipeEffectName = "RightPipeOff";
|
||||
const int32_t m_RightPipeEffectID = 2777;
|
||||
const std::string m_ImaginationCanisterEffectName = "imagination_canister";
|
||||
const int32_t m_ImaginationCanisterEffectID = 2750;
|
||||
};
|
107
dScripts/ai/FV/FvFlyingCreviceDragon.cpp
Normal file
107
dScripts/ai/FV/FvFlyingCreviceDragon.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "FvFlyingCreviceDragon.h"
|
||||
#include "GameMessages.h"
|
||||
#include "EntityManager.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "GeneralUtils.h"
|
||||
|
||||
void FvFlyingCreviceDragon::OnStartup(Entity* self) {
|
||||
self->AddTimer("waypoint", 5);
|
||||
}
|
||||
|
||||
void FvFlyingCreviceDragon::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "waypoint") {
|
||||
auto point = self->GetVar<int32_t>(u"waypoint");
|
||||
|
||||
if (point >= 20) {
|
||||
point = 0;
|
||||
}
|
||||
|
||||
self->SetVar<int32_t>(u"waypoint", point + 1);
|
||||
|
||||
self->AddTimer("waypoint", 5);
|
||||
|
||||
OnArrived(self);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string groupName = "";
|
||||
|
||||
if (timerName == "platform1attack") {
|
||||
groupName = "dragonFireballs1";
|
||||
} else if (timerName == "platform3attack") {
|
||||
groupName = "dragonFireballs3";
|
||||
}
|
||||
|
||||
const auto& group = EntityManager::Instance()->GetEntitiesInGroup(groupName);
|
||||
|
||||
if (group.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* skillComponent = group[0]->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(762, 12506, LWOOBJID_EMPTY, true);
|
||||
}
|
||||
|
||||
auto minionCount = 1;
|
||||
for (size_t i = 1; i < group.size(); i++) {
|
||||
if (minionCount == 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (/*GeneralUtils::GenerateRandomNumber<int32_t>(1, 5) > 3*/ true) {
|
||||
skillComponent = group[i]->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(762, 12506, LWOOBJID_EMPTY);
|
||||
|
||||
++minionCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FvFlyingCreviceDragon::OnArrived(Entity* self) {
|
||||
auto point = self->GetVar<int32_t>(u"waypoint");
|
||||
|
||||
if (point == 4) {
|
||||
GameMessages::SendPlayAnimation(self, u"attack1", 2);
|
||||
self->AddTimer("platform1attack", 1.75f);
|
||||
} else if (point == 12) {
|
||||
GameMessages::SendPlayAnimation(self, u"attack2", 2);
|
||||
|
||||
const auto& group2 = EntityManager::Instance()->GetEntitiesInGroup("dragonFireballs2");
|
||||
|
||||
if (group2.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* skillComponent = group2[0]->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(762, 12506, LWOOBJID_EMPTY);
|
||||
}
|
||||
|
||||
auto minionCount = 1;
|
||||
for (size_t i = 1; i < group2.size(); i++) {
|
||||
if (minionCount == 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GeneralUtils::GenerateRandomNumber<int32_t>(1, 5) > 3) {
|
||||
skillComponent = group2[i]->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(762, 12506, LWOOBJID_EMPTY, true);
|
||||
|
||||
++minionCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (point == 16) {
|
||||
GameMessages::SendPlayAnimation(self, u"attack3", 2);
|
||||
self->AddTimer("platform3attack", 0.5f);
|
||||
}
|
||||
}
|
10
dScripts/ai/FV/FvFlyingCreviceDragon.h
Normal file
10
dScripts/ai/FV/FvFlyingCreviceDragon.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvFlyingCreviceDragon : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
void OnArrived(Entity* self);
|
||||
};
|
42
dScripts/ai/FV/FvFreeGfNinjas.cpp
Normal file
42
dScripts/ai/FV/FvFreeGfNinjas.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "FvFreeGfNinjas.h"
|
||||
#include "Character.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void FvFreeGfNinjas::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) {
|
||||
if (missionID == 705 && missionState == MissionState::MISSION_STATE_AVAILABLE) {
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (missionComponent == nullptr)
|
||||
return;
|
||||
|
||||
missionComponent->AcceptMission(701);
|
||||
missionComponent->AcceptMission(702);
|
||||
missionComponent->AcceptMission(703);
|
||||
missionComponent->AcceptMission(704);
|
||||
|
||||
auto* character = target->GetCharacter();
|
||||
if (character != nullptr)
|
||||
character->SetPlayerFlag(68, true);
|
||||
} else if (missionID == 786) {
|
||||
auto* character = target->GetCharacter();
|
||||
if (character != nullptr)
|
||||
character->SetPlayerFlag(81, true);
|
||||
}
|
||||
}
|
||||
|
||||
void FvFreeGfNinjas::OnUse(Entity* self, Entity* user) {
|
||||
// To allow player who already have the mission to progress.
|
||||
auto* missionComponent = user->GetComponent<MissionComponent>();
|
||||
if (missionComponent == nullptr)
|
||||
return;
|
||||
|
||||
if (missionComponent->GetMissionState(705) == MissionState::MISSION_STATE_ACTIVE) {
|
||||
auto* character = user->GetCharacter();
|
||||
if (character != nullptr)
|
||||
character->SetPlayerFlag(68, true);
|
||||
|
||||
missionComponent->AcceptMission(701, true);
|
||||
missionComponent->AcceptMission(702, true);
|
||||
missionComponent->AcceptMission(703, true);
|
||||
missionComponent->AcceptMission(704, true);
|
||||
}
|
||||
}
|
8
dScripts/ai/FV/FvFreeGfNinjas.h
Normal file
8
dScripts/ai/FV/FvFreeGfNinjas.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvFreeGfNinjas : public CppScripts::Script {
|
||||
public:
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override;
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
18
dScripts/ai/FV/FvMaelstromGeyser.cpp
Normal file
18
dScripts/ai/FV/FvMaelstromGeyser.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "FvMaelstromGeyser.h"
|
||||
#include "SkillComponent.h"
|
||||
|
||||
void FvMaelstromGeyser::OnStartup(Entity* self) {
|
||||
self->AddTimer(m_StartSkillTimerName, m_StartSkillTimerTime);
|
||||
self->AddTimer(m_KillSelfTimerName, m_KillSelfTimerTime);
|
||||
}
|
||||
|
||||
void FvMaelstromGeyser::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == m_StartSkillTimerName) {
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
skillComponent->CalculateBehavior(m_SkillID, m_BehaviorID, LWOOBJID_EMPTY, true);
|
||||
}
|
||||
if (timerName == m_KillSelfTimerName) {
|
||||
self->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
|
||||
}
|
||||
}
|
||||
|
18
dScripts/ai/FV/FvMaelstromGeyser.h
Normal file
18
dScripts/ai/FV/FvMaelstromGeyser.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvMaelstromGeyser final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
|
||||
|
||||
private:
|
||||
const std::string m_StartSkillTimerName = "startSkill";
|
||||
const float m_StartSkillTimerTime = 2.0;
|
||||
const std::string m_KillSelfTimerName = "killSelf";
|
||||
const float m_KillSelfTimerTime = 5.5;
|
||||
const uint32_t m_SkillID = 831;
|
||||
const uint32_t m_BehaviorID = 15500;
|
||||
};
|
42
dScripts/ai/FV/FvNinjaGuard.cpp
Normal file
42
dScripts/ai/FV/FvNinjaGuard.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "FvNinjaGuard.h"
|
||||
#include "GameMessages.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void FvNinjaGuard::OnStartup(Entity* self) {
|
||||
if (self->GetLOT() == 7412) {
|
||||
m_LeftGuard = self->GetObjectID();
|
||||
} else if (self->GetLOT() == 11128) {
|
||||
m_RightGuard = self->GetObjectID();
|
||||
}
|
||||
}
|
||||
|
||||
void FvNinjaGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* target) {
|
||||
if (emote != 392) {
|
||||
GameMessages::SendPlayAnimation(self, u"no");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendPlayAnimation(self, u"scared");
|
||||
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponent != nullptr && missionComponent->HasMission(737)) {
|
||||
missionComponent->ForceProgressTaskType(737, 5, 1, false);
|
||||
}
|
||||
|
||||
if (self->GetLOT() == 7412) {
|
||||
auto* rightGuard = EntityManager::Instance()->GetEntity(m_RightGuard);
|
||||
|
||||
if (rightGuard != nullptr) {
|
||||
GameMessages::SendPlayAnimation(rightGuard, u"laugh_rt");
|
||||
}
|
||||
} else if (self->GetLOT() == 11128) {
|
||||
auto* leftGuard = EntityManager::Instance()->GetEntity(m_LeftGuard);
|
||||
|
||||
if (leftGuard != nullptr) {
|
||||
GameMessages::SendPlayAnimation(leftGuard, u"laugh_lt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
dScripts/ai/FV/FvNinjaGuard.h
Normal file
13
dScripts/ai/FV/FvNinjaGuard.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvNinjaGuard final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnEmoteReceived(Entity* self, int32_t emote, Entity* target) override;
|
||||
|
||||
private:
|
||||
LWOOBJID m_LeftGuard;
|
||||
LWOOBJID m_RightGuard;
|
||||
};
|
35
dScripts/ai/FV/FvPandaServer.cpp
Normal file
35
dScripts/ai/FV/FvPandaServer.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "FvPandaServer.h"
|
||||
#include "PetComponent.h"
|
||||
#include "Character.h"
|
||||
|
||||
void FvPandaServer::OnStartup(Entity* self) {
|
||||
const auto* petComponent = self->GetComponent<PetComponent>();
|
||||
if (petComponent != nullptr && petComponent->GetOwner() == nullptr) {
|
||||
self->SetNetworkVar<std::string>(u"pandatamer", std::to_string(self->GetVar<LWOOBJID>(u"tamer")));
|
||||
self->AddTimer("killSelf", 45);
|
||||
}
|
||||
}
|
||||
|
||||
void FvPandaServer::OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) {
|
||||
if (type == NOTIFY_TYPE_BEGIN) {
|
||||
self->CancelAllTimers();
|
||||
} else if (type == NOTIFY_TYPE_QUIT || type == NOTIFY_TYPE_FAILED) {
|
||||
self->Smash();
|
||||
} else if (type == NOTIFY_TYPE_SUCCESS) {
|
||||
// TODO: Remove from groups
|
||||
|
||||
auto* character = tamer->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
character->SetPlayerFlag(82, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FvPandaServer::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "killSelf") {
|
||||
const auto* petComponent = self->GetComponent<PetComponent>();
|
||||
if (petComponent != nullptr && petComponent->GetOwner() == nullptr) {
|
||||
self->Smash(self->GetObjectID(), SILENT);
|
||||
}
|
||||
}
|
||||
}
|
8
dScripts/ai/FV/FvPandaServer.h
Normal file
8
dScripts/ai/FV/FvPandaServer.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvPandaServer : public CppScripts::Script {
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
48
dScripts/ai/FV/FvPandaSpawnerServer.cpp
Normal file
48
dScripts/ai/FV/FvPandaSpawnerServer.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "FvPandaSpawnerServer.h"
|
||||
#include "Character.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ScriptedActivityComponent.h"
|
||||
|
||||
void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
auto* character = target->GetCharacter();
|
||||
if (character != nullptr && character->GetPlayerFlag(81)) {
|
||||
|
||||
auto raceObjects = EntityManager::Instance()->GetEntitiesInGroup("PandaRaceObject");
|
||||
if (raceObjects.empty())
|
||||
return;
|
||||
|
||||
// Check if the player is currently in a footrace
|
||||
auto* scriptedActivityComponent = raceObjects.at(0)->GetComponent<ScriptedActivityComponent>();
|
||||
if (scriptedActivityComponent == nullptr || !scriptedActivityComponent->IsPlayedBy(target))
|
||||
return;
|
||||
|
||||
// If the player already spawned a panda
|
||||
auto playerPandas = EntityManager::Instance()->GetEntitiesInGroup("panda" + std::to_string(target->GetObjectID()));
|
||||
if (!playerPandas.empty()) {
|
||||
GameMessages::SendFireEventClientSide(self->GetObjectID(), target->GetSystemAddress(), u"playerPanda",
|
||||
target->GetObjectID(), 0, 0, target->GetObjectID());
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's already too many spawned pandas
|
||||
auto pandas = EntityManager::Instance()->GetEntitiesInGroup("pandas");
|
||||
if (pandas.size() > 4) {
|
||||
GameMessages::SendFireEventClientSide(self->GetObjectID(), target->GetSystemAddress(), u"tooManyPandas",
|
||||
target->GetObjectID(), 0, 0, target->GetObjectID());
|
||||
return;
|
||||
}
|
||||
|
||||
EntityInfo info{};
|
||||
info.spawnerID = target->GetObjectID();
|
||||
info.pos = self->GetPosition();
|
||||
info.lot = 5643;
|
||||
info.settings = {
|
||||
new LDFData<LWOOBJID>(u"tamer", target->GetObjectID()),
|
||||
new LDFData<std::u16string>(u"groupID", u"panda" + (GeneralUtils::to_u16string(target->GetObjectID())) + u";pandas")
|
||||
};
|
||||
|
||||
auto* panda = EntityManager::Instance()->CreateEntity(info);
|
||||
EntityManager::Instance()->ConstructEntity(panda);
|
||||
}
|
||||
}
|
6
dScripts/ai/FV/FvPandaSpawnerServer.h
Normal file
6
dScripts/ai/FV/FvPandaSpawnerServer.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvPandaSpawnerServer : public CppScripts::Script {
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
};
|
18
dScripts/ai/FV/FvPassThroughWall.cpp
Normal file
18
dScripts/ai/FV/FvPassThroughWall.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "FvPassThroughWall.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void FvPassThroughWall::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
auto missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (missionComponent == nullptr) return;
|
||||
|
||||
//Because at the moment we do not have an ItemComponent component, we check to make sure a Maelstrom-Infused hood is equipped. There are only three in the game right now.
|
||||
auto inventoryComponent = target->GetComponent<InventoryComponent>();
|
||||
// If no inventory component is found then abort.
|
||||
if (inventoryComponent == nullptr) return;
|
||||
// If no Maelstrom hoods are equipped then abort.
|
||||
if (!inventoryComponent->IsEquipped(WhiteMaelstromHood) && !inventoryComponent->IsEquipped(BlackMaelstromHood) && !inventoryComponent->IsEquipped(RedMaelstromHood)) return;
|
||||
|
||||
// Progress mission Friend of the Ninja since all prerequisites are met.
|
||||
missionComponent->ForceProgress(friendOfTheNinjaMissionId, friendOfTheNinjaMissionUid, 1);
|
||||
}
|
34
dScripts/ai/FV/FvPassThroughWall.h
Normal file
34
dScripts/ai/FV/FvPassThroughWall.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FvPassThroughWall : public CppScripts::Script
|
||||
{
|
||||
/**
|
||||
* @brief This method is called when there is a collision with self from target.
|
||||
*
|
||||
* @param self The Entity that called this method.
|
||||
* @param target The Entity that self is targetting.
|
||||
*/
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
private:
|
||||
/**
|
||||
* Mission ID for Friend of the Ninjas.
|
||||
*/
|
||||
int32_t friendOfTheNinjaMissionId = 848;
|
||||
/**
|
||||
* Mission UID for Friend of the Ninjas.
|
||||
*/
|
||||
int32_t friendOfTheNinjaMissionUid = 1221;
|
||||
/**
|
||||
* Item LOT for Maelstrom-Infused White Ninja Hood
|
||||
*/
|
||||
int32_t WhiteMaelstromHood = 2641;
|
||||
/**
|
||||
* Item LOT for Maelstrom-Infused Black Ninja Hood
|
||||
*/
|
||||
int32_t BlackMaelstromHood = 2642;
|
||||
/**
|
||||
* Item LOT for Red Ninja Hood - Maelstrom Infused
|
||||
*/
|
||||
int32_t RedMaelstromHood = 1889;
|
||||
};
|
4
dScripts/ai/GENERAL/CMakeLists.txt
Normal file
4
dScripts/ai/GENERAL/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
set(DSCRIPTS_SOURCES_AI_GENERAL
|
||||
"InstanceExitTransferPlayerToLastNonInstance.cpp"
|
||||
"LegoDieRoll.cpp"
|
||||
PARENT_SCOPE)
|
@@ -0,0 +1,56 @@
|
||||
#include "InstanceExitTransferPlayerToLastNonInstance.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Player.h"
|
||||
#include "Character.h"
|
||||
#include "dServer.h"
|
||||
|
||||
void InstanceExitTransferPlayerToLastNonInstance::OnUse(Entity* self, Entity* user) {
|
||||
auto transferText = self->GetVar<std::u16string>(u"transferText");
|
||||
if (transferText.empty())
|
||||
transferText = u"DRAGON_EXIT_QUESTION";
|
||||
|
||||
GameMessages::SendDisplayMessageBox(
|
||||
user->GetObjectID(),
|
||||
true,
|
||||
self->GetObjectID(),
|
||||
u"Instance_Exit",
|
||||
1,
|
||||
transferText,
|
||||
u"",
|
||||
user->GetSystemAddress()
|
||||
);
|
||||
}
|
||||
|
||||
void InstanceExitTransferPlayerToLastNonInstance::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) {
|
||||
auto* player = dynamic_cast<Player*>(sender);
|
||||
if (player == nullptr)
|
||||
return;
|
||||
|
||||
auto* character = sender->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
if (identifier == u"Instance_Exit" && button == 1) {
|
||||
auto lastInstance = character->GetLastNonInstanceZoneID();
|
||||
|
||||
// Sanity check
|
||||
if (lastInstance == 0) {
|
||||
switch (Game::server->GetZoneID()) {
|
||||
case 2001:
|
||||
lastInstance = 2000;
|
||||
break;
|
||||
case 1402:
|
||||
lastInstance = 1400;
|
||||
break;
|
||||
default:
|
||||
lastInstance = 1100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
player->SendToZone(lastInstance);
|
||||
}
|
||||
}
|
||||
|
||||
GameMessages::SendTerminateInteraction(sender->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID());
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class InstanceExitTransferPlayerToLastNonInstance : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
void OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) override;
|
||||
};
|
52
dScripts/ai/GENERAL/LegoDieRoll.cpp
Normal file
52
dScripts/ai/GENERAL/LegoDieRoll.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "LegoDieRoll.h"
|
||||
#include "Entity.h"
|
||||
#include "GameMessages.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void LegoDieRoll::OnStartup(Entity* self) {
|
||||
self->AddTimer("DoneRolling", 10.0f);
|
||||
self->AddTimer("ThrowDice", LegoDieRoll::animTime);
|
||||
}
|
||||
|
||||
void LegoDieRoll::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "DoneRolling") {
|
||||
self->Smash(self->GetObjectID(), SILENT);
|
||||
} else if (timerName == "ThrowDice") {
|
||||
int dieRoll = GeneralUtils::GenerateRandomNumber<int>(1, 6);
|
||||
|
||||
switch (dieRoll) {
|
||||
case 1:
|
||||
GameMessages::SendPlayAnimation(self, u"roll-die-1");
|
||||
break;
|
||||
case 2:
|
||||
GameMessages::SendPlayAnimation(self, u"roll-die-2");
|
||||
break;
|
||||
case 3:
|
||||
GameMessages::SendPlayAnimation(self, u"roll-die-3");
|
||||
break;
|
||||
case 4:
|
||||
GameMessages::SendPlayAnimation(self, u"roll-die-4");
|
||||
break;
|
||||
case 5:
|
||||
GameMessages::SendPlayAnimation(self, u"roll-die-5");
|
||||
break;
|
||||
case 6:
|
||||
{
|
||||
GameMessages::SendPlayAnimation(self, u"roll-die-6");
|
||||
// tracking the It's Truly Random Achievement
|
||||
auto* owner = self->GetOwner();
|
||||
auto* missionComponent = owner->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponent != nullptr) {
|
||||
const auto rollMissionState = missionComponent->GetMissionState(756);
|
||||
if (rollMissionState == MissionState::MISSION_STATE_ACTIVE) {
|
||||
missionComponent->ForceProgress(756, 1103, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
11
dScripts/ai/GENERAL/LegoDieRoll.h
Normal file
11
dScripts/ai/GENERAL/LegoDieRoll.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class LegoDieRoll : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self);
|
||||
void OnTimerDone(Entity* self, std::string timerName);
|
||||
private:
|
||||
constexpr static const float animTime = 2.0f;
|
||||
};
|
||||
|
14
dScripts/ai/GF/CMakeLists.txt
Normal file
14
dScripts/ai/GF/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
set(DSCRIPTS_SOURCES_AI_GF
|
||||
"GfCampfire.cpp"
|
||||
"GfOrgan.cpp"
|
||||
"GfBanana.cpp"
|
||||
"GfBananaCluster.cpp"
|
||||
"GfJailkeepMission.cpp"
|
||||
"TriggerAmbush.cpp"
|
||||
"GfJailWalls.cpp"
|
||||
"PetDigBuild.cpp"
|
||||
"GfArchway.cpp"
|
||||
"GfMaelstromGeyser.cpp"
|
||||
"PirateRep.cpp"
|
||||
"GfParrotCrash.cpp"
|
||||
PARENT_SCOPE)
|
8
dScripts/ai/GF/GfArchway.cpp
Normal file
8
dScripts/ai/GF/GfArchway.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "GfArchway.h"
|
||||
#include "Entity.h"
|
||||
#include "SkillComponent.h"
|
||||
|
||||
void GfArchway::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
auto* skillComponent = target->GetComponent<SkillComponent>();
|
||||
if (skillComponent) skillComponent->CalculateBehavior(SHIELDING_SKILL, SHIELDING_BEHAVIOR, target->GetObjectID(), true);
|
||||
}
|
10
dScripts/ai/GF/GfArchway.h
Normal file
10
dScripts/ai/GF/GfArchway.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfArchway : public CppScripts::Script {
|
||||
public:
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
private:
|
||||
const uint32_t SHIELDING_SKILL = 863;
|
||||
const uint32_t SHIELDING_BEHAVIOR = 3788;
|
||||
};
|
93
dScripts/ai/GF/GfBanana.cpp
Normal file
93
dScripts/ai/GF/GfBanana.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include "GfBanana.h"
|
||||
|
||||
#include "Entity.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void GfBanana::SpawnBanana(Entity* self) {
|
||||
auto position = self->GetPosition();
|
||||
const auto rotation = self->GetRotation();
|
||||
|
||||
position.y += 12;
|
||||
position.x -= rotation.GetRightVector().x * 5;
|
||||
position.z -= rotation.GetRightVector().z * 5;
|
||||
|
||||
EntityInfo info{};
|
||||
|
||||
info.pos = position;
|
||||
info.rot = rotation;
|
||||
info.lot = 6909;
|
||||
info.spawnerID = self->GetObjectID();
|
||||
|
||||
auto* entity = EntityManager::Instance()->CreateEntity(info);
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(entity);
|
||||
|
||||
self->SetVar(u"banana", entity->GetObjectID());
|
||||
|
||||
entity->AddDieCallback([self]() {
|
||||
self->SetVar(u"banana", LWOOBJID_EMPTY);
|
||||
|
||||
self->AddTimer("bananaTimer", 30);
|
||||
});
|
||||
}
|
||||
|
||||
void GfBanana::OnStartup(Entity* self) {
|
||||
SpawnBanana(self);
|
||||
}
|
||||
|
||||
void GfBanana::OnHit(Entity* self, Entity* attacker) {
|
||||
auto* destroyable = self->GetComponent<DestroyableComponent>();
|
||||
|
||||
destroyable->SetHealth(9999);
|
||||
|
||||
const auto bananaId = self->GetVar<LWOOBJID>(u"banana");
|
||||
|
||||
if (bananaId == LWOOBJID_EMPTY) return;
|
||||
|
||||
auto* bananaEntity = EntityManager::Instance()->GetEntity(bananaId);
|
||||
|
||||
if (bananaEntity == nullptr) {
|
||||
self->SetVar(u"banana", LWOOBJID_EMPTY);
|
||||
|
||||
self->AddTimer("bananaTimer", 30);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bananaEntity->SetPosition(bananaEntity->GetPosition() - NiPoint3::UNIT_Y * 8);
|
||||
|
||||
auto* bananaDestroyable = bananaEntity->GetComponent<DestroyableComponent>();
|
||||
|
||||
bananaDestroyable->SetHealth(0);
|
||||
|
||||
bananaDestroyable->Smash(attacker->GetObjectID());
|
||||
|
||||
/*
|
||||
auto position = self->GetPosition();
|
||||
const auto rotation = self->GetRotation();
|
||||
|
||||
position.y += 12;
|
||||
position.x -= rotation.GetRightVector().x * 5;
|
||||
position.z -= rotation.GetRightVector().z * 5;
|
||||
|
||||
EntityInfo info {};
|
||||
|
||||
info.pos = position;
|
||||
info.rot = rotation;
|
||||
info.lot = 6718;
|
||||
info.spawnerID = self->GetObjectID();
|
||||
|
||||
auto* entity = EntityManager::Instance()->CreateEntity(info);
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(entity, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
*/
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(self);
|
||||
}
|
||||
|
||||
void GfBanana::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "bananaTimer") {
|
||||
SpawnBanana(self);
|
||||
}
|
||||
}
|
14
dScripts/ai/GF/GfBanana.h
Normal file
14
dScripts/ai/GF/GfBanana.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfBanana final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void SpawnBanana(Entity* self);
|
||||
|
||||
void OnStartup(Entity* self) override;
|
||||
|
||||
void OnHit(Entity* self, Entity* attacker) override;
|
||||
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
12
dScripts/ai/GF/GfBananaCluster.cpp
Normal file
12
dScripts/ai/GF/GfBananaCluster.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "GfBananaCluster.h"
|
||||
#include "Entity.h"
|
||||
|
||||
void GfBananaCluster::OnStartup(Entity* self) {
|
||||
self->AddTimer("startup", 100);
|
||||
}
|
||||
|
||||
void GfBananaCluster::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "startup") {
|
||||
self->ScheduleKillAfterUpdate(nullptr);
|
||||
}
|
||||
}
|
10
dScripts/ai/GF/GfBananaCluster.h
Normal file
10
dScripts/ai/GF/GfBananaCluster.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfBananaCluster final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
100
dScripts/ai/GF/GfCampfire.cpp
Normal file
100
dScripts/ai/GF/GfCampfire.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "GfCampfire.h"
|
||||
#include "RenderComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "RenderComponent.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void GfCampfire::OnStartup(Entity* self) {
|
||||
self->SetI32(u"counter", static_cast<int32_t>(0));
|
||||
self->SetProximityRadius(2.0f, "placeholder");
|
||||
self->SetBoolean(u"isBurning", true);
|
||||
|
||||
auto* render = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER));
|
||||
if (render == nullptr)
|
||||
return;
|
||||
|
||||
render->PlayEffect(295, u"running", "Burn");
|
||||
}
|
||||
|
||||
void GfCampfire::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) {
|
||||
if (args == "physicsReady") {
|
||||
auto* render = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER));
|
||||
|
||||
render->PlayEffect(295, u"running", "Burn");
|
||||
}
|
||||
}
|
||||
|
||||
void GfCampfire::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) {
|
||||
auto* skill = self->GetComponent<SkillComponent>();
|
||||
|
||||
if (self->GetBoolean(u"isBurning")) {
|
||||
if (status == "ENTER") {
|
||||
if (entering->GetCharacter()) {
|
||||
int32_t counter = self->GetI32(u"counter");
|
||||
counter = counter + 1;
|
||||
self->SetI32(u"counter", counter);
|
||||
|
||||
if (counter == 1) {
|
||||
skill->CalculateBehavior(m_skillCastId, 115, entering->GetObjectID());
|
||||
self->AddTimer("TimeBetweenCast", FIRE_COOLDOWN);
|
||||
|
||||
//self->SetVar<LWOOBJID>("target", entering->GetObjectID());
|
||||
|
||||
auto* missionComponet = entering->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponet != nullptr) {
|
||||
missionComponet->ForceProgress(440, 658, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int32_t counter = self->GetI32(u"counter");
|
||||
if (counter > 0) {
|
||||
counter = counter - 1;
|
||||
self->SetI32(u"counter", counter);
|
||||
if (counter == 0) {
|
||||
self->CancelAllTimers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GfCampfire::OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) {
|
||||
if (message == "waterspray" && self->GetVar<bool>(u"isBurning")) {
|
||||
auto* renderComponent = self->GetComponent<RenderComponent>();
|
||||
if (renderComponent != nullptr) {
|
||||
renderComponent->StopEffect("Burn");
|
||||
renderComponent->PlayEffect(295, u"idle", "Off");
|
||||
|
||||
self->SetVar<bool>(u"isBurning", false);
|
||||
self->AddTimer("FireRestart", 37);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GfCampfire::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "TimeBetweenCast") {
|
||||
/*
|
||||
self->AddTimer("TimeBetweenCast", FIRE_COOLDOWN);
|
||||
|
||||
const auto targetId = self->GetVar<LWOOBJID>("target");
|
||||
|
||||
auto* entering = EntityManager::Instance()->GetEntity(targetId);
|
||||
|
||||
if (entering == nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
} else if (timerName == "FireRestart" && !self->GetVar<bool>(u"isBurning")) {
|
||||
auto* renderComponent = self->GetComponent<RenderComponent>();
|
||||
if (renderComponent != nullptr) {
|
||||
renderComponent->StopEffect("Off");
|
||||
renderComponent->PlayEffect(295, u"running", "Burn");
|
||||
self->SetVar<bool>(u"isBurning", true);
|
||||
}
|
||||
}
|
||||
}
|
16
dScripts/ai/GF/GfCampfire.h
Normal file
16
dScripts/ai/GF/GfCampfire.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfCampfire : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) override;
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
void OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) override;
|
||||
private:
|
||||
int32_t m_skillCastId = 43;
|
||||
int32_t FIRE_COOLDOWN = 2;
|
||||
};
|
29
dScripts/ai/GF/GfJailWalls.cpp
Normal file
29
dScripts/ai/GF/GfJailWalls.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "GfJailWalls.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "GeneralUtils.h"
|
||||
|
||||
void GfJailWalls::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
const auto wall = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"Wall"));
|
||||
|
||||
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("Jail0" + wall)) {
|
||||
spawner->Deactivate();
|
||||
}
|
||||
|
||||
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("JailCaptain0" + wall)) {
|
||||
spawner->Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void GfJailWalls::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state != eRebuildState::REBUILD_RESETTING) return;
|
||||
|
||||
const auto wall = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"Wall"));
|
||||
|
||||
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("Jail0" + wall)) {
|
||||
spawner->Activate();
|
||||
}
|
||||
|
||||
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("JailCaptain0" + wall)) {
|
||||
spawner->Activate();
|
||||
}
|
||||
}
|
9
dScripts/ai/GF/GfJailWalls.h
Normal file
9
dScripts/ai/GF/GfJailWalls.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfJailWalls final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
};
|
38
dScripts/ai/GF/GfJailkeepMission.cpp
Normal file
38
dScripts/ai/GF/GfJailkeepMission.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "GfJailkeepMission.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "Character.h"
|
||||
|
||||
void GfJailkeepMission::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) {
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (missionComponent == nullptr)
|
||||
return;
|
||||
|
||||
if (missionID == 385 && missionState == MissionState::MISSION_STATE_AVAILABLE) {
|
||||
missionComponent->AcceptMission(386, true);
|
||||
missionComponent->AcceptMission(387, true);
|
||||
missionComponent->AcceptMission(388, true);
|
||||
missionComponent->AcceptMission(390, true);
|
||||
} else if (missionID == 385 && missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) {
|
||||
auto* character = target->GetCharacter();
|
||||
if (character != nullptr && character->GetPlayerFlag(68)) {
|
||||
missionComponent->AcceptMission(701);
|
||||
missionComponent->AcceptMission(702);
|
||||
missionComponent->AcceptMission(703);
|
||||
missionComponent->AcceptMission(704);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GfJailkeepMission::OnUse(Entity* self, Entity* user) {
|
||||
auto* missionComponent = user->GetComponent<MissionComponent>();
|
||||
if (missionComponent == nullptr)
|
||||
return;
|
||||
|
||||
if (missionComponent->GetMissionState(385) == MissionState::MISSION_STATE_ACTIVE) {
|
||||
missionComponent->AcceptMission(386, true);
|
||||
missionComponent->AcceptMission(387, true);
|
||||
missionComponent->AcceptMission(388, true);
|
||||
missionComponent->AcceptMission(390, true);
|
||||
}
|
||||
}
|
||||
|
9
dScripts/ai/GF/GfJailkeepMission.h
Normal file
9
dScripts/ai/GF/GfJailkeepMission.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfJailkeepMission final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override;
|
||||
};
|
18
dScripts/ai/GF/GfMaelstromGeyser.cpp
Normal file
18
dScripts/ai/GF/GfMaelstromGeyser.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "GfMaelstromGeyser.h"
|
||||
#include "SkillComponent.h"
|
||||
|
||||
void GfMaelstromGeyser::OnStartup(Entity* self) {
|
||||
self->AddTimer(m_StartSkillTimerName, m_StartSkillTimerTime);
|
||||
self->AddTimer(m_KillSelfTimerName, m_KillSelfTimerTime);
|
||||
}
|
||||
|
||||
void GfMaelstromGeyser::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == m_StartSkillTimerName) {
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
skillComponent->CalculateBehavior(m_SkillID, m_BehaviorID, LWOOBJID_EMPTY, true);
|
||||
}
|
||||
if (timerName == m_KillSelfTimerName) {
|
||||
self->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
|
||||
}
|
||||
}
|
||||
|
17
dScripts/ai/GF/GfMaelstromGeyser.h
Normal file
17
dScripts/ai/GF/GfMaelstromGeyser.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfMaelstromGeyser final : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
|
||||
private:
|
||||
const std::string m_StartSkillTimerName = "startSkill";
|
||||
const float m_StartSkillTimerTime = 2.0;
|
||||
const std::string m_KillSelfTimerName = "killSelf";
|
||||
const float m_KillSelfTimerTime = 7.5;
|
||||
const uint32_t m_SkillID = 607;
|
||||
const uint32_t m_BehaviorID = 10500;
|
||||
};
|
21
dScripts/ai/GF/GfOrgan.cpp
Normal file
21
dScripts/ai/GF/GfOrgan.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "GfOrgan.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void GfOrgan::OnUse(Entity* self, Entity* user) {
|
||||
if (self->GetBoolean(u"bIsInUse")) {
|
||||
m_canUse = false;
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendPlayNDAudioEmitter(self, UNASSIGNED_SYSTEM_ADDRESS, "{15d5f8bd-139a-4c31-8904-970c480cd70f}");
|
||||
self->SetBoolean(u"bIsInUse", true);
|
||||
self->AddTimer("reset", 5.0f);
|
||||
|
||||
GameMessages::SendPlayAnimation(user, u"jig");
|
||||
}
|
||||
|
||||
void GfOrgan::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "reset") {
|
||||
self->SetBoolean(u"bIsInUse", false);
|
||||
}
|
||||
}
|
11
dScripts/ai/GF/GfOrgan.h
Normal file
11
dScripts/ai/GF/GfOrgan.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GfOrgan : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user);
|
||||
void OnTimerDone(Entity* self, std::string timerName);
|
||||
private:
|
||||
bool m_canUse;
|
||||
};
|
13
dScripts/ai/GF/GfParrotCrash.cpp
Normal file
13
dScripts/ai/GF/GfParrotCrash.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "GfParrotCrash.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "Entity.h"
|
||||
#include "dLogger.h"
|
||||
|
||||
void GfParrotCrash::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
if (args == "Slow") {
|
||||
skillComponent->CalculateBehavior(m_SlowSkillID, m_SlowBehaviorID, sender->GetObjectID());
|
||||
} else if (args == "Unslow") {
|
||||
skillComponent->CalculateBehavior(m_UnslowSkillID, m_UnslowBehaviorID, sender->GetObjectID());
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user