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:
23
dScripts/02_server/Map/General/BankInteractServer.cpp
Normal file
23
dScripts/02_server/Map/General/BankInteractServer.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "BankInteractServer.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void BankInteractServer::OnUse(Entity* self, Entity* user) {
|
||||
AMFArrayValue args;
|
||||
AMFStringValue* bank = new AMFStringValue();
|
||||
bank->SetStringValue("bank");
|
||||
args.InsertValue("state", bank);
|
||||
|
||||
GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args);
|
||||
}
|
||||
|
||||
void BankInteractServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1,
|
||||
int32_t param2, int32_t param3) {
|
||||
if (args == "ToggleBank") {
|
||||
AMFArrayValue args;
|
||||
args.InsertValue("visible", new AMFFalseValue());
|
||||
|
||||
GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", &args);
|
||||
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"CloseBank", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress());
|
||||
}
|
||||
}
|
10
dScripts/02_server/Map/General/BankInteractServer.h
Normal file
10
dScripts/02_server/Map/General/BankInteractServer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class BankInteractServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2,
|
||||
int32_t param3) override;
|
||||
};
|
@@ -0,0 +1,30 @@
|
||||
#include "BaseInteractDropLootServer.h"
|
||||
#include "Loot.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void BaseInteractDropLootServer::OnUse(Entity* self, Entity* user) {
|
||||
BaseUse(self, user);
|
||||
}
|
||||
|
||||
void BaseInteractDropLootServer::BaseUse(Entity* self, Entity* user) {
|
||||
auto cooldownTime = self->GetVar<float>(u"cooldownTime");
|
||||
if (cooldownTime == 0) cooldownTime = 5;
|
||||
|
||||
uint32_t lootMatrix = self->GetVar<int32_t>(u"UseLootMatrix");
|
||||
if (lootMatrix == 0) lootMatrix = self->GetVar<int32_t>(u"smashable_loot_matrix");
|
||||
if (lootMatrix == 0) lootMatrix = 715;
|
||||
|
||||
auto useSound = self->GetVar<std::string>(u"sound1");
|
||||
|
||||
if (!useSound.empty()) {
|
||||
GameMessages::SendPlayNDAudioEmitter(self, user->GetSystemAddress(), useSound);
|
||||
}
|
||||
|
||||
self->SetNetworkVar(u"bInUse", true);
|
||||
|
||||
LootGenerator::Instance().DropLoot(user, self, lootMatrix, 0, 0);
|
||||
|
||||
self->AddCallbackTimer(cooldownTime, [this, self]() {
|
||||
self->SetNetworkVar(u"bInUse", false);
|
||||
});
|
||||
}
|
10
dScripts/02_server/Map/General/BaseInteractDropLootServer.h
Normal file
10
dScripts/02_server/Map/General/BaseInteractDropLootServer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class BaseInteractDropLootServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
virtual void OnUse(Entity* self, Entity* user) override;
|
||||
void BaseUse(Entity* self, Entity* user);
|
||||
};
|
||||
|
15
dScripts/02_server/Map/General/Binoculars.cpp
Normal file
15
dScripts/02_server/Map/General/Binoculars.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "Binoculars.h"
|
||||
#include "Character.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Game.h"
|
||||
#include "dServer.h"
|
||||
|
||||
void Binoculars::OnUse(Entity* self, Entity* user) {
|
||||
const auto number = self->GetVarAsString(u"number");
|
||||
|
||||
int32_t flag = std::stoi(std::to_string(Game::server->GetZoneID()).substr(0, 2) + number);
|
||||
if (user->GetCharacter()->GetPlayerFlag(flag) == false) {
|
||||
user->GetCharacter()->SetPlayerFlag(flag, true);
|
||||
GameMessages::SendFireEventClientSide(self->GetObjectID(), user->GetSystemAddress(), u"achieve", LWOOBJID_EMPTY, 0, -1, LWOOBJID_EMPTY);
|
||||
}
|
||||
}
|
7
dScripts/02_server/Map/General/Binoculars.h
Normal file
7
dScripts/02_server/Map/General/Binoculars.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class Binoculars : public CppScripts::Script {
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user);
|
||||
};
|
28
dScripts/02_server/Map/General/CMakeLists.txt
Normal file
28
dScripts/02_server/Map/General/CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL
|
||||
"BankInteractServer.cpp"
|
||||
"BaseInteractDropLootServer.cpp"
|
||||
"Binoculars.cpp"
|
||||
"ExplodingAsset.cpp"
|
||||
"ForceVolumeServer.cpp"
|
||||
"GrowingFlower.cpp"
|
||||
"ImaginationBackpackHealServer.cpp"
|
||||
"InvalidScript.cpp"
|
||||
"MailBoxServer.cpp"
|
||||
"NjRailSwitch.cpp"
|
||||
"PetDigServer.cpp"
|
||||
"PropertyDevice.cpp"
|
||||
"PropertyPlatform.cpp"
|
||||
"QbEnemyStunner.cpp"
|
||||
"QbSpawner.cpp"
|
||||
"StoryBoxInteractServer.cpp"
|
||||
"TokenConsoleServer.cpp"
|
||||
"TouchMissionUpdateServer.cpp"
|
||||
"WishingWellServer.cpp")
|
||||
|
||||
add_subdirectory(Ninjago)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL_NINJAGO})
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL} "Ninjago/${file}")
|
||||
endforeach()
|
||||
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL} PARENT_SCOPE)
|
109
dScripts/02_server/Map/General/ExplodingAsset.cpp
Normal file
109
dScripts/02_server/Map/General/ExplodingAsset.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "ExplodingAsset.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
|
||||
//TODO: this has to be updated so that you only get killed if you're in a certain radius.
|
||||
//And so that all entities in a certain radius are killed, not just the attacker.
|
||||
|
||||
void ExplodingAsset::OnStartup(Entity* self) {
|
||||
self->SetProximityRadius(20.0f, "outRadius");
|
||||
self->SetVar<int32_t>(u"playersNearChest", 0);
|
||||
self->SetProximityRadius(10.0f, "crateHitters");
|
||||
}
|
||||
|
||||
void ExplodingAsset::OnHit(Entity* self, Entity* attacker) {
|
||||
std::vector<Entity*> entities;
|
||||
entities.push_back(attacker);
|
||||
|
||||
if (!self->GetBoolean(u"bIsHit")) {
|
||||
for (Entity* en : entities) {
|
||||
if (en->GetObjectID() == attacker->GetObjectID()) {
|
||||
if (Vector3::DistanceSquared(en->GetPosition(), self->GetPosition()) > 10 * 10) continue;
|
||||
|
||||
auto* destroyable = en->GetComponent<DestroyableComponent>();
|
||||
if (destroyable == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
destroyable->Smash(attacker->GetObjectID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attacker = attacker->GetOwner();
|
||||
self->SetBoolean(u"bIsHit", true);
|
||||
self->SetOwnerOverride(attacker->GetObjectID());
|
||||
|
||||
GameMessages::SendPlayEmbeddedEffectOnAllClientsNearObject(self, u"camshake", self->GetObjectID(), 16);
|
||||
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(147, 4721, LWOOBJID_EMPTY, true);
|
||||
}
|
||||
|
||||
const auto missionID = self->GetVar<int32_t>(u"missionID");
|
||||
auto achievementIDs = self->GetVar<std::u16string>(u"achieveID");
|
||||
|
||||
// Progress all scripted missions related to this asset
|
||||
auto* missionComponent = attacker->GetComponent<MissionComponent>();
|
||||
if (missionComponent != nullptr) {
|
||||
if (missionID != 0) {
|
||||
missionComponent->ForceProgressValue(missionID,
|
||||
static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT),
|
||||
self->GetLOT(), false);
|
||||
}
|
||||
|
||||
if (!achievementIDs.empty()) {
|
||||
for (const auto& achievementID : GeneralUtils::SplitString(achievementIDs, u'_')) {
|
||||
missionComponent->ForceProgressValue(std::stoi(GeneralUtils::UTF16ToWTF8(achievementID)),
|
||||
static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT),
|
||||
self->GetLOT());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->ScheduleKillAfterUpdate();
|
||||
}
|
||||
|
||||
void ExplodingAsset::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) {
|
||||
/*
|
||||
if msg.objId:BelongsToFaction{factionID = 1}.bIsInFaction then
|
||||
if (msg.status == "ENTER") then
|
||||
self:PlayAnimation{ animationID = "bounce" }
|
||||
self:PlayFXEffect{ name = "bouncin", effectType = "anim" }
|
||||
self:SetVar("playersNearChest", (self:GetVar("playersNearChest") + 1 ))
|
||||
elseif (msg.status == "LEAVE") then
|
||||
self:SetVar("playersNearChest", (self:GetVar("playersNearChest") - 1 ))
|
||||
if self:GetVar("playersNearChest") < 1 then
|
||||
self:PlayAnimation{ animationID = "idle" }
|
||||
self:StopFXEffect{ name = "bouncin" }
|
||||
self:SetVar("playersNearChest", 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
auto* destuctableComponent = entering->GetComponent<DestroyableComponent>();
|
||||
|
||||
if (destuctableComponent == nullptr) return;
|
||||
|
||||
const auto& factions = destuctableComponent->GetFactionIDs();
|
||||
|
||||
if (!std::count(factions.begin(), factions.end(), 1)) return;
|
||||
|
||||
if (status == "ENTER") {
|
||||
GameMessages::SendPlayAnimation(self, u"bounce");
|
||||
GameMessages::SendPlayFXEffect(self, -1, u"anim", "bouncin", LWOOBJID_EMPTY, 1, 1, true);
|
||||
self->SetVar(u"playersNearChest", self->GetVar<int32_t>(u"playersNearChest") + 1);
|
||||
} else if (status == "LEAVE") {
|
||||
self->SetVar(u"playersNearChest", self->GetVar<int32_t>(u"playersNearChest") - 1);
|
||||
|
||||
if (self->GetVar<int32_t>(u"playersNearChest") < 1) {
|
||||
GameMessages::SendPlayAnimation(self, u"idle");
|
||||
GameMessages::SendStopFXEffect(self, true, "bouncin");
|
||||
self->SetVar<int32_t>(u"playersNearChest", 0);
|
||||
}
|
||||
}
|
||||
}
|
10
dScripts/02_server/Map/General/ExplodingAsset.h
Normal file
10
dScripts/02_server/Map/General/ExplodingAsset.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ExplodingAsset : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self);
|
||||
void OnHit(Entity* self, Entity* attacker);
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status);
|
||||
};
|
21
dScripts/02_server/Map/General/ForceVolumeServer.cpp
Normal file
21
dScripts/02_server/Map/General/ForceVolumeServer.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "ForceVolumeServer.h"
|
||||
#include "PhantomPhysicsComponent.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void ForceVolumeServer::OnStartup(Entity* self) {
|
||||
auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>();
|
||||
|
||||
if (phantomPhysicsComponent == nullptr) return;
|
||||
|
||||
const auto forceAmount = self->GetVar<float>(u"ForceAmt");
|
||||
const auto forceX = self->GetVar<float>(u"ForceX");
|
||||
const auto forceY = self->GetVar<float>(u"ForceY");
|
||||
const auto forceZ = self->GetVar<float>(u"ForceZ");
|
||||
|
||||
phantomPhysicsComponent->SetEffectType(0); // PUSH
|
||||
phantomPhysicsComponent->SetDirectionalMultiplier(forceAmount);
|
||||
phantomPhysicsComponent->SetDirection({ forceX, forceY, forceZ });
|
||||
phantomPhysicsComponent->SetPhysicsEffectActive(true);
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(self);
|
||||
}
|
8
dScripts/02_server/Map/General/ForceVolumeServer.h
Normal file
8
dScripts/02_server/Map/General/ForceVolumeServer.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ForceVolumeServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
};
|
35
dScripts/02_server/Map/General/GrowingFlower.cpp
Normal file
35
dScripts/02_server/Map/General/GrowingFlower.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "GrowingFlower.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void GrowingFlower::OnSkillEventFired(Entity* self, Entity* target, const std::string& message) {
|
||||
if (!self->GetVar<bool>(u"blooming") && (message == "waterspray" || message == "shovelgrow")) {
|
||||
self->SetVar<bool>(u"blooming", true);
|
||||
self->SetNetworkVar(u"blooming", true);
|
||||
self->AddTimer("FlowerDie", GrowingFlower::aliveTime);
|
||||
|
||||
const auto mission1 = self->GetVar<int32_t>(u"missionID");
|
||||
const auto mission2 = self->GetVar<int32_t>(u"missionID2");
|
||||
|
||||
LootGenerator::Instance().DropActivityLoot(target, self, self->GetLOT(), 0);
|
||||
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (missionComponent != nullptr) {
|
||||
for (const auto mission : achievementIDs)
|
||||
missionComponent->ForceProgressTaskType(mission, static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), 1);
|
||||
|
||||
if (mission1 && missionComponent->GetMissionState(mission1) == MissionState::MISSION_STATE_ACTIVE)
|
||||
missionComponent->ForceProgressTaskType(mission1, static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), 1);
|
||||
|
||||
if (mission2 && missionComponent->GetMissionState(mission2) == MissionState::MISSION_STATE_ACTIVE)
|
||||
missionComponent->ForceProgressTaskType(mission2, static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrowingFlower::OnTimerDone(Entity* self, std::string message) {
|
||||
if (message == "FlowerDie") {
|
||||
self->Smash();
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<uint32_t> GrowingFlower::achievementIDs = { 143, 152, 153, 1409, 1507, 1544, 1581, 1845 };
|
11
dScripts/02_server/Map/General/GrowingFlower.h
Normal file
11
dScripts/02_server/Map/General/GrowingFlower.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class GrowingFlower : public CppScripts::Script {
|
||||
public:
|
||||
void OnSkillEventFired(Entity* self, Entity* target, const std::string& message) override;
|
||||
void OnTimerDone(Entity* self, std::string message) override;
|
||||
private:
|
||||
static const std::vector<uint32_t> achievementIDs;
|
||||
constexpr static const float aliveTime = 16.0f;
|
||||
};
|
@@ -0,0 +1,20 @@
|
||||
#include "ImaginationBackpackHealServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void ImaginationBackpackHealServer::OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) {
|
||||
if (message == "CastImaginationBackpack") {
|
||||
auto healMission = self->GetVar<int32_t>(u"FXOffMis");
|
||||
if (healMission == 0)
|
||||
healMission = self->GetVar<int32_t>(u"FXOnMis");
|
||||
if (healMission == 0)
|
||||
return;
|
||||
|
||||
auto* missionComponent = caster->GetComponent<MissionComponent>();
|
||||
if (missionComponent != nullptr && missionComponent->GetMissionState(healMission) == MissionState::MISSION_STATE_ACTIVE) {
|
||||
missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT());
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ClearMaelstrom", 0, 0,
|
||||
caster->GetObjectID(), "", caster->GetSystemAddress());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class ImaginationBackpackHealServer : public CppScripts::Script {
|
||||
void OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) override;
|
||||
};
|
1
dScripts/02_server/Map/General/InvalidScript.cpp
Normal file
1
dScripts/02_server/Map/General/InvalidScript.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "InvalidScript.h"
|
6
dScripts/02_server/Map/General/InvalidScript.h
Normal file
6
dScripts/02_server/Map/General/InvalidScript.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class InvalidScript : public CppScripts::Script
|
||||
{
|
||||
};
|
19
dScripts/02_server/Map/General/MailBoxServer.cpp
Normal file
19
dScripts/02_server/Map/General/MailBoxServer.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "MailBoxServer.h"
|
||||
#include "AMFFormat.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void MailBoxServer::OnUse(Entity* self, Entity* user) {
|
||||
AMFStringValue* value = new AMFStringValue();
|
||||
value->SetStringValue("Mail");
|
||||
AMFArrayValue args;
|
||||
args.InsertValue("state", value);
|
||||
GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args);
|
||||
}
|
||||
|
||||
void MailBoxServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
|
||||
if (args == "toggleMail") {
|
||||
AMFArrayValue args;
|
||||
args.InsertValue("visible", new AMFFalseValue());
|
||||
GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleMail", &args);
|
||||
}
|
||||
}
|
16
dScripts/02_server/Map/General/MailBoxServer.h
Normal file
16
dScripts/02_server/Map/General/MailBoxServer.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "CppScripts.h"
|
||||
|
||||
class MailBoxServer : public CppScripts::Script {
|
||||
public:
|
||||
/**
|
||||
* When a mailbox is interacted with, this method updates the player game state
|
||||
* to be in a mailbox.
|
||||
*
|
||||
* @param self The object that owns this script.
|
||||
* @param user The user that interacted with this Entity.
|
||||
*/
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override;
|
||||
};
|
6
dScripts/02_server/Map/General/Ninjago/CMakeLists.txt
Normal file
6
dScripts/02_server/Map/General/Ninjago/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL_NINJAGO
|
||||
"NjRailActivatorsServer.cpp"
|
||||
"NjRailPostServer.cpp"
|
||||
"NjIceRailActivator.cpp"
|
||||
"NjhubLavaPlayerDeathTrigger.cpp"
|
||||
PARENT_SCOPE)
|
@@ -0,0 +1,25 @@
|
||||
#include "NjIceRailActivator.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void NjIceRailActivator::OnPlayerRailArrived(Entity* self, Entity* sender, const std::u16string& pathName,
|
||||
int32_t waypoint) {
|
||||
const auto breakPoint = self->GetVar<int32_t>(BreakpointVariable);
|
||||
if (breakPoint == waypoint) {
|
||||
const auto& blockGroup = self->GetVar<std::u16string>(BlockGroupVariable);
|
||||
|
||||
for (auto* block : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(blockGroup))) {
|
||||
GameMessages::SendPlayAnimation(block, u"explode");
|
||||
|
||||
const auto blockID = block->GetObjectID();
|
||||
|
||||
self->AddCallbackTimer(1.0f, [self, blockID]() {
|
||||
auto* block = EntityManager::Instance()->GetEntity(blockID);
|
||||
|
||||
if (block != nullptr) {
|
||||
block->Kill(self);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
10
dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.h
Normal file
10
dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "NjRailActivatorsServer.h"
|
||||
|
||||
class NjIceRailActivator : public NjRailActivatorsServer {
|
||||
void OnPlayerRailArrived(Entity* self, Entity* sender, const std::u16string& pathName, int32_t waypoint) override;
|
||||
private:
|
||||
std::u16string BreakpointVariable = u"BreakPoint";
|
||||
std::u16string BlockGroupVariable = u"BlockGroup";
|
||||
std::u16string IceBlockVariable = u"IceBlock";
|
||||
};
|
@@ -0,0 +1,16 @@
|
||||
#include "NjRailActivatorsServer.h"
|
||||
#include "RebuildComponent.h"
|
||||
#include "Character.h"
|
||||
|
||||
void NjRailActivatorsServer::OnUse(Entity* self, Entity* user) {
|
||||
const auto flag = self->GetVar<int32_t>(u"RailFlagNum");
|
||||
auto* rebuildComponent = self->GetComponent<RebuildComponent>();
|
||||
|
||||
// Only allow use if this is not a quick build or the quick build is built
|
||||
if (rebuildComponent == nullptr || rebuildComponent->GetState() == REBUILD_COMPLETED) {
|
||||
auto* character = user->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
character->SetPlayerFlag(flag, true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "NjRailPostServer.h"
|
||||
|
||||
class NjRailActivatorsServer : public NjRailPostServer {
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
51
dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp
Normal file
51
dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "NjRailPostServer.h"
|
||||
#include "RebuildComponent.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void NjRailPostServer::OnStartup(Entity* self) {
|
||||
auto* rebuildComponent = self->GetComponent<RebuildComponent>();
|
||||
if (rebuildComponent != nullptr) {
|
||||
self->SetNetworkVar<bool>(NetworkNotActiveVariable, true);
|
||||
}
|
||||
}
|
||||
|
||||
void NjRailPostServer::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1,
|
||||
int32_t param2) {
|
||||
if (name == "PostRebuilt") {
|
||||
self->SetNetworkVar<bool>(NetworkNotActiveVariable, false);
|
||||
} else if (name == "PostDied") {
|
||||
self->SetNetworkVar<bool>(NetworkNotActiveVariable, true);
|
||||
}
|
||||
}
|
||||
|
||||
void NjRailPostServer::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state == REBUILD_COMPLETED) {
|
||||
auto* relatedRail = GetRelatedRail(self);
|
||||
if (relatedRail == nullptr)
|
||||
return;
|
||||
|
||||
relatedRail->NotifyObject(self, "PostRebuilt");
|
||||
|
||||
if (self->GetVar<bool>(NotActiveVariable))
|
||||
return;
|
||||
|
||||
self->SetNetworkVar(NetworkNotActiveVariable, false);
|
||||
} else if (state == REBUILD_RESETTING) {
|
||||
auto* relatedRail = GetRelatedRail(self);
|
||||
if (relatedRail == nullptr)
|
||||
return;
|
||||
|
||||
relatedRail->NotifyObject(self, "PostDied");
|
||||
}
|
||||
}
|
||||
|
||||
Entity* NjRailPostServer::GetRelatedRail(Entity* self) {
|
||||
const auto& railGroup = self->GetVar<std::u16string>(RailGroupVariable);
|
||||
if (!railGroup.empty()) {
|
||||
for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(railGroup))) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
13
dScripts/02_server/Map/General/Ninjago/NjRailPostServer.h
Normal file
13
dScripts/02_server/Map/General/Ninjago/NjRailPostServer.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NjRailPostServer : public CppScripts::Script {
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) override;
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
private:
|
||||
Entity* GetRelatedRail(Entity* self);
|
||||
const std::u16string NetworkNotActiveVariable = u"NetworkNotActive";
|
||||
const std::u16string NotActiveVariable = u"NotActive";
|
||||
const std::u16string RailGroupVariable = u"RailGroup";
|
||||
};
|
@@ -0,0 +1,9 @@
|
||||
#include "NjhubLavaPlayerDeathTrigger.h"
|
||||
#include "Entity.h"
|
||||
|
||||
void NjhubLavaPlayerDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (!target->IsPlayer())
|
||||
return;
|
||||
|
||||
target->Smash(self->GetObjectID(), VIOLENT, u"drown");
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NjhubLavaPlayerDeathTrigger : public CppScripts::Script {
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
};
|
12
dScripts/02_server/Map/General/NjRailSwitch.cpp
Normal file
12
dScripts/02_server/Map/General/NjRailSwitch.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "NjRailSwitch.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void NjRailSwitch::OnUse(Entity* self, Entity* user) {
|
||||
// const auto path = self->GetVar<std::u16string>(u"rail_path");
|
||||
// const auto pathStart = self->GetVar<uint32_t>(u"rail_path_start");
|
||||
// const auto pathGoForward = self->GetVar<bool>(u"rail_path_direction");
|
||||
// const auto cinematicName = self->GetVar<std::u16string>(u"cinematic");
|
||||
//
|
||||
// GameMessages::SendSetRailMovement(self->GetObjectID(), pathGoForward, path, pathStart, user->GetSystemAddress());
|
||||
// GameMessages::SendPlayCinematic(self->GetObjectID(), cinematicName, user->GetSystemAddress());
|
||||
}
|
6
dScripts/02_server/Map/General/NjRailSwitch.h
Normal file
6
dScripts/02_server/Map/General/NjRailSwitch.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NjRailSwitch : public CppScripts::Script {
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
234
dScripts/02_server/Map/General/PetDigServer.cpp
Normal file
234
dScripts/02_server/Map/General/PetDigServer.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
#include "dZoneManager.h"
|
||||
#include "PetDigServer.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Character.h"
|
||||
#include "PetComponent.h"
|
||||
|
||||
std::vector<LWOOBJID> PetDigServer::treasures{};
|
||||
|
||||
const DigInfo PetDigServer::defaultDigInfo = DigInfo{ 3495, -1, -1, false, false, false, false };
|
||||
|
||||
/**
|
||||
* Summary of all the special treasure behaviors, indexed by their lot
|
||||
*/
|
||||
const std::map<LOT, DigInfo> PetDigServer::digInfoMap{
|
||||
// Regular treasures
|
||||
{3495, defaultDigInfo},
|
||||
|
||||
// Pet cove treasure
|
||||
{7612, DigInfo { 7612, -1, -1, false, false, false, false }},
|
||||
|
||||
// Gnarled Forest flag treasure
|
||||
{7410, DigInfo { 7410, -1, -1, false, true, false, false }},
|
||||
|
||||
// Gnarled Forest crab treasure
|
||||
{9308, DigInfo { 9308, 7694, -1, false, false, false, false }},
|
||||
|
||||
// Avant Gardens mission treasure
|
||||
{9307, DigInfo { 9307, -1, -1, false, true, false, true }},
|
||||
|
||||
// Avant Gardens bouncer treasure
|
||||
{7559, DigInfo { 7559, -1, -1, false, false, true, false }},
|
||||
|
||||
// Crux Prime dragon treasure
|
||||
{13098, DigInfo { 13098, 13067, 1298, false, false, false, false }},
|
||||
|
||||
// Bone treasure (can only be digged using the dragon)
|
||||
{12192, DigInfo { 12192, -1, -1, true, false, false, false }},
|
||||
};
|
||||
|
||||
void PetDigServer::OnStartup(Entity* self) {
|
||||
treasures.push_back(self->GetObjectID());
|
||||
const auto digInfoIterator = digInfoMap.find(self->GetLOT());
|
||||
const auto digInfo = digInfoIterator != digInfoMap.end() ? digInfoIterator->second : defaultDigInfo;
|
||||
|
||||
// Reset any bouncers that might've been created by the previous dig
|
||||
if (digInfo.bouncer) {
|
||||
auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"BouncerNumber"));
|
||||
auto bouncerSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncer" + bounceNumber);
|
||||
auto switchSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncerSwitch" + bounceNumber);
|
||||
|
||||
for (auto* bouncerSpawner : bouncerSpawners) {
|
||||
for (auto* bouncer : bouncerSpawner->m_Info.nodes)
|
||||
bouncerSpawner->Deactivate();
|
||||
bouncerSpawner->Reset();
|
||||
}
|
||||
|
||||
for (auto* switchSpawner : switchSpawners) {
|
||||
switchSpawner->Deactivate();
|
||||
switchSpawner->Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PetDigServer::OnDie(Entity* self, Entity* killer) {
|
||||
const auto iterator = std::find(treasures.begin(), treasures.end(), self->GetObjectID());
|
||||
if (iterator != treasures.end()) {
|
||||
treasures.erase(iterator);
|
||||
}
|
||||
|
||||
auto* owner = killer->GetOwner();
|
||||
const auto digInfoIterator = digInfoMap.find(self->GetLOT());
|
||||
const auto digInfo = digInfoIterator != digInfoMap.end() ? digInfoIterator->second : defaultDigInfo;
|
||||
|
||||
if (digInfo.spawnLot >= 0) {
|
||||
PetDigServer::SpawnPet(self, owner, digInfo);
|
||||
} else if (digInfo.builderOnly) {
|
||||
|
||||
// Some treasures may only be retrieved by the player that built the diggable
|
||||
auto builder = self->GetVar<LWOOBJID>(u"builder"); // Set by the pet dig build script
|
||||
if (builder != owner->GetObjectID())
|
||||
return;
|
||||
} else if (digInfo.xBuild) {
|
||||
PetDigServer::HandleXBuildDig(self, owner, killer);
|
||||
return;
|
||||
} else if (digInfo.bouncer) {
|
||||
PetDigServer::HandleBouncerDig(self, owner);
|
||||
}
|
||||
|
||||
PetDigServer::ProgressPetDigMissions(owner, self);
|
||||
|
||||
self->SetNetworkVar<bool>(u"treasure_dug", true);
|
||||
// TODO: Reset other pets
|
||||
|
||||
// Handles smashing leftovers (edge case for the AG X)
|
||||
auto* xObject = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"X"));
|
||||
if (xObject != nullptr) {
|
||||
xObject->Smash(xObject->GetObjectID(), VIOLENT);
|
||||
}
|
||||
}
|
||||
|
||||
void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pet) {
|
||||
auto playerID = self->GetVar<LWOOBJID>(u"builder");
|
||||
if (playerID == LWOOBJID_EMPTY || playerID != owner->GetObjectID())
|
||||
return;
|
||||
|
||||
auto* playerEntity = EntityManager::Instance()->GetEntity(playerID);
|
||||
if (!playerEntity || !playerEntity->GetParentUser() || !playerEntity->GetParentUser()->GetLastUsedChar())
|
||||
return;
|
||||
|
||||
auto* player = playerEntity->GetCharacter();
|
||||
const auto groupID = self->GetVar<std::u16string>(u"groupID");
|
||||
auto playerFlag = 0;
|
||||
|
||||
// The flag that the player dug up
|
||||
if (groupID == u"Flag1") {
|
||||
playerFlag = 61;
|
||||
} else if (groupID == u"Flag2") {
|
||||
playerFlag = 62;
|
||||
} else if (groupID == u"Flag3") {
|
||||
playerFlag = 63;
|
||||
}
|
||||
|
||||
// If the player doesn't have the flag yet
|
||||
if (playerFlag != 0 && !player->GetPlayerFlag(playerFlag)) {
|
||||
auto* petComponent = pet->GetComponent<PetComponent>();
|
||||
if (petComponent != nullptr) {
|
||||
// TODO: Pet state = 9 ??
|
||||
}
|
||||
|
||||
// Shows the flag object to the player
|
||||
player->SetPlayerFlag(playerFlag, true);
|
||||
}
|
||||
|
||||
auto* xObject = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"X"));
|
||||
if (xObject != nullptr) {
|
||||
xObject->Smash(xObject->GetObjectID(), VIOLENT);
|
||||
}
|
||||
}
|
||||
|
||||
void PetDigServer::HandleBouncerDig(const Entity* self, const Entity* owner) {
|
||||
auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar<std::u16string>(u"BouncerNumber"));
|
||||
auto bouncerSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncer" + bounceNumber);
|
||||
auto switchSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncerSwitch" + bounceNumber);
|
||||
|
||||
for (auto* bouncerSpawner : bouncerSpawners) {
|
||||
bouncerSpawner->Activate();
|
||||
}
|
||||
|
||||
for (auto* switchSpawner : switchSpawners) {
|
||||
switchSpawner->Activate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Progresses the Can You Dig It mission and the Pet Excavator Achievement if the player has never completed it yet
|
||||
* \param owner the owner that just made a pet dig something up
|
||||
*/
|
||||
void PetDigServer::ProgressPetDigMissions(const Entity* owner, const Entity* chest) {
|
||||
auto* missionComponent = owner->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponent != nullptr) {
|
||||
// Can You Dig It progress
|
||||
const auto digMissionState = missionComponent->GetMissionState(843);
|
||||
if (digMissionState == MissionState::MISSION_STATE_ACTIVE) {
|
||||
missionComponent->ForceProgress(843, 1216, 1);
|
||||
}
|
||||
|
||||
// Pet Excavator progress
|
||||
const auto excavatorMissionState = missionComponent->GetMissionState(505);
|
||||
if (excavatorMissionState == MissionState::MISSION_STATE_ACTIVE) {
|
||||
if (chest->HasVar(u"PetDig")) {
|
||||
int32_t playerFlag = 1260 + chest->GetVarAs<int32_t>(u"PetDig");
|
||||
Character* player = owner->GetCharacter();
|
||||
|
||||
// check if player flag is set
|
||||
if (!player->GetPlayerFlag(playerFlag)) {
|
||||
missionComponent->ForceProgress(505, 767, 1);
|
||||
player->SetPlayerFlag(playerFlag, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some treasures spawn special pets, this handles that case
|
||||
* \param owner the owner that just made a pet dig something up
|
||||
* \param digInfo information regarding the treasure, will also contain info about the pet to spawn
|
||||
*/
|
||||
void PetDigServer::SpawnPet(Entity* self, const Entity* owner, const DigInfo digInfo) {
|
||||
// Some treasures require a mission to be active
|
||||
if (digInfo.requiredMission >= 0) {
|
||||
auto* missionComponent = owner->GetComponent<MissionComponent>();
|
||||
if (missionComponent != nullptr && missionComponent->GetMissionState(digInfo.requiredMission) < MissionState::MISSION_STATE_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EntityInfo info{};
|
||||
info.lot = digInfo.spawnLot;
|
||||
info.pos = self->GetPosition();
|
||||
info.rot = self->GetRotation();
|
||||
info.spawnerID = self->GetSpawnerID();
|
||||
info.settings = {
|
||||
new LDFData<LWOOBJID>(u"tamer", owner->GetObjectID()),
|
||||
new LDFData<std::string>(u"group", "pet" + std::to_string(owner->GetObjectID())),
|
||||
new LDFData<std::string>(u"spawnAnim", "spawn-pet"),
|
||||
new LDFData<float>(u"spawnTimer", 1.0)
|
||||
};
|
||||
|
||||
auto* spawnedPet = EntityManager::Instance()->CreateEntity(info);
|
||||
EntityManager::Instance()->ConstructEntity(spawnedPet);
|
||||
}
|
||||
|
||||
Entity* PetDigServer::GetClosestTresure(NiPoint3 position) {
|
||||
float closestDistance = 0;
|
||||
Entity* closest = nullptr;
|
||||
|
||||
for (const auto tresureId : treasures) {
|
||||
auto* tresure = EntityManager::Instance()->GetEntity(tresureId);
|
||||
|
||||
if (tresure == nullptr) continue;
|
||||
|
||||
float distance = Vector3::DistanceSquared(tresure->GetPosition(), position);
|
||||
|
||||
if (closest == nullptr || distance < closestDistance) {
|
||||
closestDistance = distance;
|
||||
closest = tresure;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
30
dScripts/02_server/Map/General/PetDigServer.h
Normal file
30
dScripts/02_server/Map/General/PetDigServer.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
struct DigInfo {
|
||||
LOT digLot; // The lot of the chest
|
||||
LOT spawnLot; // Option lot of pet to spawn
|
||||
int32_t requiredMission; // Optional mission required before pet can be spawned, if < 0 == don't use
|
||||
bool specificPet; // This treasure requires a specific pet to be dug up
|
||||
bool xBuild; // This treasure is retrieved from a buildable cross
|
||||
bool bouncer; // This treasure spawns a bouncer
|
||||
bool builderOnly; // Only the builder of this diggable may access the rewards, for example with crosses
|
||||
};
|
||||
|
||||
class PetDigServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnDie(Entity* self, Entity* killer) override;
|
||||
|
||||
static Entity* GetClosestTresure(NiPoint3 position);
|
||||
|
||||
private:
|
||||
static void ProgressPetDigMissions(const Entity* owner, const Entity* chest);
|
||||
static void SpawnPet(Entity* self, const Entity* owner, DigInfo digInfo);
|
||||
static void HandleXBuildDig(const Entity* self, Entity* owner, Entity* pet);
|
||||
static void HandleBouncerDig(const Entity* self, const Entity* owner);
|
||||
static std::vector<LWOOBJID> treasures;
|
||||
static const DigInfo defaultDigInfo;
|
||||
static const std::map<LOT, DigInfo> digInfoMap;
|
||||
};
|
25
dScripts/02_server/Map/General/PropertyDevice.cpp
Normal file
25
dScripts/02_server/Map/General/PropertyDevice.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "PropertyDevice.h"
|
||||
#include "GameMessages.h"
|
||||
#include "EntityManager.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void PropertyDevice::OnStartup(Entity* self) {
|
||||
auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity();
|
||||
if (zoneControl != nullptr) {
|
||||
zoneControl->OnFireEventServerSide(self, "CheckForPropertyOwner");
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyDevice::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
auto propertyOwnerID = self->GetNetworkVar<std::string>(m_PropertyOwnerVariable);
|
||||
if (propertyOwnerID == std::to_string(LWOOBJID_EMPTY))
|
||||
return;
|
||||
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (missionComponent != nullptr) {
|
||||
if (missionComponent->GetMissionState(m_PropertyMissionID) == MissionState::MISSION_STATE_ACTIVE) {
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), 641, u"create", "callhome");
|
||||
missionComponent->ForceProgress(m_PropertyMissionID, 1793, self->GetLOT());
|
||||
}
|
||||
}
|
||||
}
|
9
dScripts/02_server/Map/General/PropertyDevice.h
Normal file
9
dScripts/02_server/Map/General/PropertyDevice.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class PropertyDevice : public CppScripts::Script {
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
const std::u16string m_PropertyOwnerVariable = u"PropertyOwnerID";
|
||||
const uint32_t m_PropertyMissionID = 1291;
|
||||
};
|
32
dScripts/02_server/Map/General/PropertyPlatform.cpp
Normal file
32
dScripts/02_server/Map/General/PropertyPlatform.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "PropertyPlatform.h"
|
||||
#include "RebuildComponent.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void PropertyPlatform::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
// auto* movingPlatform = self->GetComponent<MovingPlatformComponent>();
|
||||
// if (movingPlatform != nullptr) {
|
||||
// movingPlatform->StopPathing();
|
||||
// movingPlatform->SetNoAutoStart(true);
|
||||
// }
|
||||
GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0,
|
||||
0, 0, MovementPlatformState::Stationary);
|
||||
}
|
||||
|
||||
void PropertyPlatform::OnUse(Entity* self, Entity* user) {
|
||||
auto* rebuildComponent = self->GetComponent<RebuildComponent>();
|
||||
if (rebuildComponent != nullptr && rebuildComponent->GetState() == REBUILD_COMPLETED) {
|
||||
// auto* movingPlatform = self->GetComponent<MovingPlatformComponent>();
|
||||
// if (movingPlatform != nullptr) {
|
||||
// movingPlatform->GotoWaypoint(1);
|
||||
// }
|
||||
GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0,
|
||||
1, 1, MovementPlatformState::Moving);
|
||||
|
||||
self->AddCallbackTimer(movementDelay + effectDelay, [self, this]() {
|
||||
self->SetNetworkVar<float_t>(u"startEffect", dieDelay);
|
||||
self->AddCallbackTimer(dieDelay, [self]() {
|
||||
self->Smash();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
13
dScripts/02_server/Map/General/PropertyPlatform.h
Normal file
13
dScripts/02_server/Map/General/PropertyPlatform.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class PropertyPlatform : public CppScripts::Script {
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
private:
|
||||
float_t movementDelay = 10.0f;
|
||||
float_t effectDelay = 5.0f;
|
||||
float_t dieDelay = 5.0f;
|
||||
uint32_t desiredWaypoint = 1;
|
||||
};
|
65
dScripts/02_server/Map/General/QbEnemyStunner.cpp
Normal file
65
dScripts/02_server/Map/General/QbEnemyStunner.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "QbEnemyStunner.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "DestroyableComponent.h"
|
||||
|
||||
void QbEnemyStunner::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
auto* destroyable = self->GetComponent<DestroyableComponent>();
|
||||
|
||||
if (destroyable != nullptr) {
|
||||
destroyable->SetFaction(115);
|
||||
}
|
||||
|
||||
auto skillComponent = self->GetComponent<SkillComponent>();
|
||||
if (!skillComponent) return;
|
||||
|
||||
// Get the skill IDs of this object.
|
||||
CDObjectSkillsTable* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills");
|
||||
auto skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == self->GetLOT()); });
|
||||
std::map<uint32_t, uint32_t> skillBehaviorMap;
|
||||
// For each skill, cast it with the associated behavior ID.
|
||||
for (auto skill : skills) {
|
||||
CDSkillBehaviorTable* skillBehaviorTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior");
|
||||
CDSkillBehavior behaviorData = skillBehaviorTable->GetSkillByID(skill.skillID);
|
||||
|
||||
skillBehaviorMap.insert(std::make_pair(skill.skillID, behaviorData.behaviorID));
|
||||
}
|
||||
|
||||
// If there are no skills found, insert a default skill to use.
|
||||
if (skillBehaviorMap.size() == 0) {
|
||||
skillBehaviorMap.insert(std::make_pair(499U, 6095U));
|
||||
}
|
||||
|
||||
// Start all skills associated with the object next tick
|
||||
self->AddTimer("TickTime", 0);
|
||||
|
||||
self->AddTimer("PlayEffect", 20);
|
||||
|
||||
self->SetVar<std::map<uint32_t, uint32_t>>(u"skillBehaviorMap", skillBehaviorMap);
|
||||
}
|
||||
|
||||
void QbEnemyStunner::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "DieTime") {
|
||||
self->Smash();
|
||||
|
||||
self->CancelAllTimers();
|
||||
} else if (timerName == "PlayEffect") {
|
||||
self->SetNetworkVar(u"startEffect", 5.0f, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
self->AddTimer("DieTime", 5.0f);
|
||||
} else if (timerName == "TickTime") {
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent != nullptr) {
|
||||
auto skillBehaviorMap = self->GetVar<std::map<uint32_t, uint32_t>>(u"skillBehaviorMap");
|
||||
if (skillBehaviorMap.size() == 0) {
|
||||
// Should no skills have been found, default to the mermaid stunner
|
||||
skillComponent->CalculateBehavior(499U, 6095U, LWOOBJID_EMPTY);
|
||||
} else {
|
||||
for (auto pair : skillBehaviorMap) {
|
||||
skillComponent->CalculateBehavior(pair.first, pair.second, LWOOBJID_EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
self->AddTimer("TickTime", 1);
|
||||
}
|
||||
}
|
9
dScripts/02_server/Map/General/QbEnemyStunner.h
Normal file
9
dScripts/02_server/Map/General/QbEnemyStunner.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class QbEnemyStunner : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
136
dScripts/02_server/Map/General/QbSpawner.cpp
Normal file
136
dScripts/02_server/Map/General/QbSpawner.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "QbSpawner.h"
|
||||
#include "BaseCombatAIComponent.h"
|
||||
#include "MovementAIComponent.h"
|
||||
|
||||
void QbSpawner::OnStartup(Entity* self) {
|
||||
auto mobNum = self->GetVar<int>(u"mobNum");
|
||||
auto spawnDist = self->GetVar<float>(u"spawnDist");
|
||||
auto mobTemplate = self->GetVar<LWOOBJID>(u"mobTemplate");
|
||||
auto spawnTime = self->GetVar<float>(u"spawnTime");
|
||||
|
||||
if (!mobNum) self->SetVar<int>(u"mobNum", m_DefaultMobNum);
|
||||
if (!spawnDist) self->SetVar<float>(u"spawnDist", m_DefaultSpawnDist);
|
||||
if (!mobTemplate) self->SetVar<LWOOBJID>(u"mobTemplate", m_DefaultMobTemplate);
|
||||
if (!spawnTime) self->SetVar<float>(u"spawnTime", m_DefaultSpawnTime);
|
||||
|
||||
// go ahead and setup the mob table here
|
||||
std::vector<LWOOBJID> mobTable;
|
||||
mobTable.assign(self->GetVar<int>(u"mobNum"), LWOOBJID_EMPTY);
|
||||
|
||||
self->SetVar<std::vector<LWOOBJID>>(u"mobTable", mobTable);
|
||||
}
|
||||
|
||||
void QbSpawner::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
|
||||
auto gateObjID = sender->GetObjectID();
|
||||
if (!gateObjID) return;
|
||||
if (args == "spawnMobs") {
|
||||
self->SetVar(u"gateObj", gateObjID);
|
||||
auto spawnTime = self->GetVar<float>(u"spawnTime");
|
||||
self->AddTimer("SpawnMobEnemies", spawnTime);
|
||||
}
|
||||
}
|
||||
|
||||
void QbSpawner::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "SpawnMobEnemies") {
|
||||
auto mobTable = self->GetVar<std::vector<LWOOBJID>>(u"mobTable");
|
||||
|
||||
auto spawnDist = self->GetVar<float>(u"spawnDist");
|
||||
auto mobTemplate = self->GetVar<LWOOBJID>(u"mobTemplate");
|
||||
|
||||
auto gateObjID = self->GetVar<LWOOBJID>(u"gateObj");
|
||||
if (!gateObjID) return;
|
||||
|
||||
auto* gate = EntityManager::Instance()->GetEntity(gateObjID);
|
||||
if (!gate) return;
|
||||
|
||||
auto oPos = gate->GetPosition();
|
||||
auto oDir = gate->GetRotation().GetForwardVector();
|
||||
NiPoint3 newPos(
|
||||
oPos.x + (oDir.x * spawnDist),
|
||||
oPos.y,
|
||||
oPos.z + (oDir.z * spawnDist)
|
||||
);
|
||||
auto newRot = NiQuaternion::LookAt(newPos, oPos);
|
||||
|
||||
for (int i = 0; i < mobTable.size(); i++) {
|
||||
int posOffset = -10;
|
||||
if (mobTable[i] == LWOOBJID_EMPTY) {
|
||||
posOffset = posOffset + 5 * i;
|
||||
auto newOffset = newPos;
|
||||
newOffset.z = newOffset.z + posOffset;
|
||||
|
||||
EntityInfo info{};
|
||||
info.lot = mobTemplate;
|
||||
info.pos = newOffset;
|
||||
info.rot = newRot;
|
||||
info.spawnerID = self->GetObjectID();
|
||||
info.spawnerNodeID = 0;
|
||||
info.settings = {
|
||||
new LDFData<bool>(u"no_timed_spawn", true),
|
||||
new LDFData<float>(u"aggroRadius", 70),
|
||||
new LDFData<float>(u"softtetherRadius", 80),
|
||||
new LDFData<float>(u"tetherRadius", 90),
|
||||
new LDFData<float>(u"wanderRadius", 5),
|
||||
new LDFData<int>(u"mobTableLoc", i)
|
||||
};
|
||||
|
||||
auto* child = EntityManager::Instance()->CreateEntity(info, nullptr, self);
|
||||
EntityManager::Instance()->ConstructEntity(child);
|
||||
|
||||
OnChildLoaded(self, child);
|
||||
} else {
|
||||
auto* mob = EntityManager::Instance()->GetEntity(mobTable[i]);
|
||||
AggroTargetObject(self, mob);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void QbSpawner::OnChildLoaded(Entity* self, Entity* child) {
|
||||
auto mobTable = self->GetVar<std::vector<LWOOBJID>>(u"mobTable");
|
||||
auto tableLoc = child->GetVar<int>(u"mobTableLoc");
|
||||
|
||||
mobTable[tableLoc] = child->GetObjectID();
|
||||
self->SetVar<std::vector<LWOOBJID>>(u"mobTable", mobTable);
|
||||
|
||||
AggroTargetObject(self, child);
|
||||
|
||||
const auto selfID = self->GetObjectID();
|
||||
|
||||
child->AddDieCallback([this, selfID, child]() {
|
||||
auto* self = EntityManager::Instance()->GetEntity(selfID);
|
||||
OnChildRemoved(self, child);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QbSpawner::OnChildRemoved(Entity* self, Entity* child) {
|
||||
auto mobTable = self->GetVar<std::vector<LWOOBJID>>(u"mobTable");
|
||||
auto tableLoc = child->GetVar<int>(u"mobTableLoc");
|
||||
|
||||
mobTable[tableLoc] = LWOOBJID_EMPTY;
|
||||
self->SetVar<std::vector<LWOOBJID>>(u"mobTable", mobTable);
|
||||
}
|
||||
|
||||
void QbSpawner::AggroTargetObject(Entity* self, Entity* enemy) {
|
||||
auto* baseCombatAIComponent = enemy->GetComponent<BaseCombatAIComponent>();
|
||||
if (!baseCombatAIComponent) return;
|
||||
|
||||
auto gateObjID = self->GetVar<LWOOBJID>(u"gateObj");
|
||||
if (gateObjID) {
|
||||
auto* gate = EntityManager::Instance()->GetEntity(gateObjID);
|
||||
if (gate) {
|
||||
auto* movementAIComponent = enemy->GetComponent<MovementAIComponent>();
|
||||
if (movementAIComponent) movementAIComponent->SetDestination(gate->GetPosition());
|
||||
baseCombatAIComponent->Taunt(gateObjID, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
auto playerObjID = self->GetVar<LWOOBJID>(u"player");
|
||||
if (playerObjID) {
|
||||
baseCombatAIComponent->Taunt(playerObjID, 100);
|
||||
}
|
||||
|
||||
}
|
||||
|
17
dScripts/02_server/Map/General/QbSpawner.h
Normal file
17
dScripts/02_server/Map/General/QbSpawner.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class QbSpawner : 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 OnTimerDone(Entity* self, std::string timerName) override;
|
||||
void OnChildLoaded(Entity* self, Entity* child);
|
||||
void OnChildRemoved(Entity* self, Entity* child);
|
||||
void AggroTargetObject(Entity* self, Entity* enemy);
|
||||
private:
|
||||
const int m_DefaultMobNum = 3;
|
||||
const float m_DefaultSpawnDist = 25.0;
|
||||
const LWOOBJID m_DefaultMobTemplate = 4712;
|
||||
const float m_DefaultSpawnTime = 2.0;
|
||||
};
|
48
dScripts/02_server/Map/General/StoryBoxInteractServer.cpp
Normal file
48
dScripts/02_server/Map/General/StoryBoxInteractServer.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "StoryBoxInteractServer.h"
|
||||
#include "Character.h"
|
||||
#include "GameMessages.h"
|
||||
#include "dServer.h"
|
||||
#include "AMFFormat.h"
|
||||
|
||||
void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) {
|
||||
if (self->GetVar<bool>(u"hasCustomText")) {
|
||||
const auto& customText = self->GetVar<std::string>(u"customText");
|
||||
|
||||
{
|
||||
AMFArrayValue args;
|
||||
|
||||
auto* state = new AMFStringValue();
|
||||
state->SetStringValue("Story");
|
||||
|
||||
args.InsertValue("state", state);
|
||||
|
||||
GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args);
|
||||
}
|
||||
|
||||
user->AddCallbackTimer(0.1f, [user, customText]() {
|
||||
AMFArrayValue args;
|
||||
|
||||
auto* text = new AMFStringValue();
|
||||
text->SetStringValue(customText);
|
||||
|
||||
args.InsertValue("visible", new AMFTrueValue());
|
||||
args.InsertValue("text", text);
|
||||
|
||||
GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "ToggleStoryBox", &args);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto storyText = self->GetVarAsString(u"storyText");
|
||||
|
||||
int32_t boxFlag = self->GetVar<int32_t>(u"altFlagID");
|
||||
if (boxFlag <= 0) {
|
||||
boxFlag = (10000 + Game::server->GetZoneID() + std::stoi(storyText.substr(storyText.length() - 2)));
|
||||
}
|
||||
|
||||
if (user->GetCharacter()->GetPlayerFlag(boxFlag) == false) {
|
||||
user->GetCharacter()->SetPlayerFlag(boxFlag, true);
|
||||
GameMessages::SendFireEventClientSide(self->GetObjectID(), user->GetSystemAddress(), u"achieve", LWOOBJID_EMPTY, 0, -1, LWOOBJID_EMPTY);
|
||||
}
|
||||
}
|
7
dScripts/02_server/Map/General/StoryBoxInteractServer.h
Normal file
7
dScripts/02_server/Map/General/StoryBoxInteractServer.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class StoryBoxInteractServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user);
|
||||
};
|
36
dScripts/02_server/Map/General/TokenConsoleServer.cpp
Normal file
36
dScripts/02_server/Map/General/TokenConsoleServer.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "TokenConsoleServer.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Character.h"
|
||||
|
||||
//2021-05-03 - max - added script, omitted some parts related to inheritance in lua which we don't need
|
||||
|
||||
void TokenConsoleServer::OnUse(Entity* self, Entity* user) {
|
||||
auto* inv = static_cast<InventoryComponent*>(user->GetComponent(COMPONENT_TYPE_INVENTORY));
|
||||
|
||||
//make sure the user has the required amount of infected bricks
|
||||
if (inv && inv->GetLotCount(6194) >= bricksToTake) {
|
||||
//yeet the bricks
|
||||
inv->RemoveItem(6194, bricksToTake);
|
||||
|
||||
//play sound
|
||||
GameMessages::SendPlayNDAudioEmitter(self, user->GetSystemAddress(), "947d0d52-c7f8-4516-8dee-e1593a7fd1d1");
|
||||
|
||||
//figure out which faction the player belongs to:
|
||||
auto character = user->GetCharacter();
|
||||
if (!character) return;
|
||||
// At this point the player has to be in a faction.
|
||||
LOT tokenLOT = 0;
|
||||
if (character->GetPlayerFlag(ePlayerFlags::VENTURE_FACTION)) //venture
|
||||
tokenLOT = 8321;
|
||||
else if (character->GetPlayerFlag(ePlayerFlags::ASSEMBLY_FACTION)) //assembly
|
||||
tokenLOT = 8318;
|
||||
else if (character->GetPlayerFlag(ePlayerFlags::PARADOX_FACTION)) //paradox
|
||||
tokenLOT = 8320;
|
||||
else if (character->GetPlayerFlag(ePlayerFlags::SENTINEL_FACTION)) //sentinel
|
||||
tokenLOT = 8319;
|
||||
inv->AddItem(tokenLOT, tokensToGive, eLootSourceType::LOOT_SOURCE_NONE);
|
||||
}
|
||||
|
||||
GameMessages::SendTerminateInteraction(user->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID());
|
||||
}
|
10
dScripts/02_server/Map/General/TokenConsoleServer.h
Normal file
10
dScripts/02_server/Map/General/TokenConsoleServer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class TokenConsoleServer : public CppScripts::Script {
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
|
||||
private:
|
||||
int bricksToTake = 25;
|
||||
int tokensToGive = 5;
|
||||
};
|
51
dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp
Normal file
51
dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "TouchMissionUpdateServer.h"
|
||||
|
||||
#include "Entity.h"
|
||||
#include "GameMessages.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
void TouchMissionUpdateServer::OnStartup(Entity* self) {
|
||||
self->SetProximityRadius(20, "touchCheck"); // Those does not have a collider for some reason?
|
||||
}
|
||||
|
||||
void TouchMissionUpdateServer::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
int32_t missionId = self->GetVar<int32_t>(u"TouchCompleteID");
|
||||
|
||||
if (missionId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* missionComponent = static_cast<MissionComponent*>(target->GetComponent(COMPONENT_TYPE_MISSION));
|
||||
|
||||
if (missionComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* mission = missionComponent->GetMission(missionId);
|
||||
|
||||
if (mission == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto state = mission->GetMissionState();
|
||||
|
||||
if (state >= MissionState::MISSION_STATE_COMPLETE || mission->GetCompletions() > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto* task : mission->GetTasks()) {
|
||||
if (!task->IsComplete()) {
|
||||
task->Complete();
|
||||
}
|
||||
}
|
||||
|
||||
mission->CheckCompletion();
|
||||
}
|
||||
|
||||
void TouchMissionUpdateServer::OnProximityUpdate(Entity* self, Entity* entering, const std::string name, const std::string status) {
|
||||
if (name != "touchCheck" || status != "ENTER") {
|
||||
return;
|
||||
}
|
||||
|
||||
OnCollisionPhantom(self, entering);
|
||||
}
|
11
dScripts/02_server/Map/General/TouchMissionUpdateServer.h
Normal file
11
dScripts/02_server/Map/General/TouchMissionUpdateServer.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class TouchMissionUpdateServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override;
|
||||
};
|
||||
|
44
dScripts/02_server/Map/General/WishingWellServer.cpp
Normal file
44
dScripts/02_server/Map/General/WishingWellServer.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "WishingWellServer.h"
|
||||
#include "ScriptedActivityComponent.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void WishingWellServer::OnStartup(Entity* self) {
|
||||
}
|
||||
|
||||
void WishingWellServer::OnUse(Entity* self, Entity* user) {
|
||||
auto* scriptedActivity = self->GetComponent<ScriptedActivityComponent>();
|
||||
|
||||
if (!scriptedActivity->TakeCost(user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto audio = self->GetVar<std::string>(u"sound1");
|
||||
|
||||
if (!audio.empty()) {
|
||||
GameMessages::SendPlayNDAudioEmitter(self, user->GetSystemAddress(), audio);
|
||||
}
|
||||
|
||||
LootGenerator::Instance().DropActivityLoot(
|
||||
user,
|
||||
self,
|
||||
static_cast<uint32_t>(scriptedActivity->GetActivityID()),
|
||||
GeneralUtils::GenerateRandomNumber<int32_t>(1, 1000)
|
||||
);
|
||||
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"StartCooldown", 0, 0, LWOOBJID_EMPTY, "", user->GetSystemAddress());
|
||||
|
||||
const auto userID = user->GetObjectID();
|
||||
|
||||
self->AddCallbackTimer(10, [self, userID]() {
|
||||
auto* user = EntityManager::Instance()->GetEntity(userID);
|
||||
|
||||
if (user == nullptr) return;
|
||||
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"StopCooldown", 0, 0, LWOOBJID_EMPTY, "", user->GetSystemAddress());
|
||||
});
|
||||
|
||||
GameMessages::SendTerminateInteraction(user->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID());
|
||||
}
|
||||
|
||||
void WishingWellServer::OnTimerDone(Entity* self, std::string timerName) {
|
||||
}
|
11
dScripts/02_server/Map/General/WishingWellServer.h
Normal file
11
dScripts/02_server/Map/General/WishingWellServer.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class WishingWellServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
||||
|
Reference in New Issue
Block a user