mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-04 09:44:10 +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:
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)
|
Reference in New Issue
Block a user