Merge remote-tracking branch 'origin/main' into scripting-lua

This commit is contained in:
Wincent Holm
2022-04-25 17:21:57 +02:00
53 changed files with 606 additions and 423 deletions

View File

@@ -7,10 +7,16 @@
class AgFans : public CppScripts::Script
{
public:
void OnStartup(Entity* self);
void OnDie(Entity* self, Entity* killer);
void OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2,
int32_t param3);
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);
};

View File

@@ -32,7 +32,7 @@ void AmDropshipComputer::OnUse(Entity* self, Entity* user)
return;
}
inventoryComponent->AddItem(12323, 1);
inventoryComponent->AddItem(12323, 1, eLootSourceType::LOOT_SOURCE_NONE);
}
void AmDropshipComputer::OnDie(Entity* self, Entity* killer)

View File

@@ -1,4 +1,4 @@
//I can feel my soul being torn apart with every script added to this monstrosity.
//I can feel my soul being torn apart with every script added to this monstrosity.
// skate fast eat trash
// do you think god stays in heaven because he too lives in fear of what he's created?
@@ -274,6 +274,10 @@
#include "AgSurvivalMech.h"
#include "AgSurvivalSpiderling.h"
// Frostburgh Scripts
#include "RockHydrantBroken.h"
#include "WhFans.h"
//Big bad global bc this is a namespace and not a class:
InvalidScript* invalidToReturn = new InvalidScript();
std::map<std::string, CppScripts::Script*> m_Scripts;
@@ -795,6 +799,12 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr
else if (scriptName == "scripts\\EquipmentScripts\\BuccaneerValiantShip.lua")
script = new BuccaneerValiantShip();
// FB
else if (scriptName == "scripts\\ai\\NS\\WH\\L_ROCKHYDRANT_BROKEN.lua")
script = new RockHydrantBroken();
else if (scriptName == "scripts\\ai\\NS\\L_NS_WH_FANS.lua")
script = new WhFans();
//Ignore these scripts:
else if (scriptName == "scripts\\02_server\\Enemy\\General\\L_SUSPEND_LUA_AI.lua")
script = invalidToReturn;

View File

@@ -2,7 +2,7 @@
#include "EntityManager.h"
#include "GameMessages.h"
void HydrantBroken::OnStartup(Entity* self)
void HydrantBroken::OnStartup(Entity* self)
{
self->AddTimer("playEffect", 1);
@@ -10,8 +10,6 @@ void HydrantBroken::OnStartup(Entity* self)
const auto bouncers = EntityManager::Instance()->GetEntitiesInGroup(hydrant);
Game::logger->Log("HydrantBroken", "Broken Hydrant spawned (%s)\n", hydrant.c_str());
for (auto* bouncer : bouncers)
{
self->SetVar<LWOOBJID>(u"bouncer", bouncer->GetObjectID());
@@ -20,11 +18,11 @@ void HydrantBroken::OnStartup(Entity* self)
GameMessages::SendNotifyObject(bouncer->GetObjectID(), self->GetObjectID(), u"enableCollision", UNASSIGNED_SYSTEM_ADDRESS);
}
self->AddTimer("KillBroken", 25);
}
void HydrantBroken::OnTimerDone(Entity* self, std::string timerName)
void HydrantBroken::OnTimerDone(Entity* self, std::string timerName)
{
if (timerName == "KillBroken")
{

View File

@@ -2,20 +2,18 @@
#include "EntityManager.h"
#include "GeneralUtils.h"
void HydrantSmashable::OnDie(Entity* self, Entity* killer)
void HydrantSmashable::OnDie(Entity* self, Entity* killer)
{
const auto hydrantName = self->GetVar<std::u16string>(u"hydrant");
LDFBaseData* data = new LDFData<std::string>(u"hydrant", GeneralUtils::UTF16ToWTF8(hydrantName));
EntityInfo info {};
info.lot = 7328;
info.lot = HYDRANT_BROKEN;
info.pos = self->GetPosition();
info.rot = self->GetRotation();
info.settings = {data};
info.spawnerID = self->GetSpawnerID();
Game::logger->Log("HydrantBroken", "Hydrant spawned (%s)\n", data->GetString().c_str());
auto* hydrant = EntityManager::Instance()->CreateEntity(info);

View File

@@ -1,8 +1,10 @@
#pragma once
#include "CppScripts.h"
class HydrantSmashable : public CppScripts::Script
class HydrantSmashable : public CppScripts::Script
{
public:
void OnDie(Entity* self, Entity* killer) override;
void OnDie(Entity* self, Entity* killer) override;
private:
LOT HYDRANT_BROKEN = 7328;
};

View File

@@ -11,7 +11,7 @@ void NPCAddRemoveItem::OnMissionDialogueOK(Entity *self, Entity *target, int mis
for (const auto& itemSetting : missionSetting.second) {
for (const auto& lot : itemSetting.items) {
if (itemSetting.add && (missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE)) {
inventory->AddItem(lot, 1);
inventory->AddItem(lot, 1, eLootSourceType::LOOT_SOURCE_NONE);
} else if (itemSetting.remove && (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE)) {
inventory->RemoveItem(lot, 1);
}

View File

@@ -54,6 +54,6 @@ void NjColeNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID,
return;
}
inventoryComponent->AddItem(16644, 1);
inventoryComponent->AddItem(16644, 1, eLootSourceType::LOOT_SOURCE_NONE);
}
}

View File

@@ -12,6 +12,6 @@ void NjScrollChestServer::OnUse(Entity *self, Entity *user) {
playerInventory->RemoveItem(keyLOT, 1);
// Reward the player with the item set
playerInventory->AddItem(rewardItemLOT, 1);
playerInventory->AddItem(rewardItemLOT, 1, eLootSourceType::LOOT_SOURCE_NONE);
}
}

View File

@@ -23,7 +23,7 @@ void NpcCowboyServer::OnMissionDialogueOK(Entity* self, Entity* target, int miss
{
if (inventoryComponent->GetLotCount(14378) == 0)
{
inventoryComponent->AddItem(14378, 1);
inventoryComponent->AddItem(14378, 1, eLootSourceType::LOOT_SOURCE_NONE);
}
}
else if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE)

View File

@@ -9,7 +9,7 @@ void NpcPirateServer::OnMissionDialogueOK(Entity *self, Entity *target, int miss
// Add or remove the lucky shovel based on whether the mission was completed or started
if ((missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE)
&& luckyShovel == nullptr) {
inventory->AddItem(14591, 1);
inventory->AddItem(14591, 1, eLootSourceType::LOOT_SOURCE_NONE);
} else if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) {
inventory->RemoveItem(14591, 1);
}

View File

@@ -20,7 +20,7 @@ void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missio
// For the daily we add the maelstrom vacuum if the player doesn't have it yet
if (missionID == 1883 && (missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE)
&& maelstromVacuum == nullptr) {
inventory->AddItem(maelstromVacuumLot, 1);
inventory->AddItem(maelstromVacuumLot, 1, eLootSourceType::LOOT_SOURCE_NONE);
} else if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) {
inventory->RemoveItem(maelstromVacuumLot, 1);
}

View File

@@ -195,7 +195,7 @@ void NsConcertInstrument::EquipInstruments(Entity *self, Entity *player) {
// Equip the left hand instrument
const auto leftInstrumentLot = instrumentLotLeft.find(GetInstrumentLot(self))->second;
if (leftInstrumentLot != LOT_NULL) {
inventory->AddItem(leftInstrumentLot, 1, TEMP_ITEMS, {}, LWOOBJID_EMPTY, false);
inventory->AddItem(leftInstrumentLot, 1, eLootSourceType::LOOT_SOURCE_ACTIVITY);
auto* leftInstrument = inventory->FindItemByLot(leftInstrumentLot, TEMP_ITEMS);
leftInstrument->Equip();
}
@@ -203,7 +203,7 @@ void NsConcertInstrument::EquipInstruments(Entity *self, Entity *player) {
// Equip the right hand instrument
const auto rightInstrumentLot = instrumentLotRight.find(GetInstrumentLot(self))->second;
if (rightInstrumentLot != LOT_NULL) {
inventory->AddItem(rightInstrumentLot, 1, TEMP_ITEMS, {}, LWOOBJID_EMPTY, false);
inventory->AddItem(rightInstrumentLot, 1, eLootSourceType::LOOT_SOURCE_ACTIVITY);
auto* rightInstrument = inventory->FindItemByLot(rightInstrumentLot, TEMP_ITEMS);
rightInstrument->Equip();
}

View File

@@ -47,24 +47,29 @@ void NsTokenConsoleServer::OnUse(Entity* self, Entity* user)
{
GameMessages::SendPlayNDAudioEmitter(self, UNASSIGNED_SYSTEM_ADDRESS, useSound);
}
// Player must be in faction to interact with this entity.
LOT tokenLOT = 0;
if (character->GetPlayerFlag(46))
{
inventoryComponent->AddItem(8321, 5);
tokenLOT = 8321;
}
else if (character->GetPlayerFlag(47))
{
inventoryComponent->AddItem(8318, 5);
tokenLOT = 8318;
}
else if (character->GetPlayerFlag(48))
{
inventoryComponent->AddItem(8320, 5);
tokenLOT = 8320;
}
else if (character->GetPlayerFlag(49))
{
inventoryComponent->AddItem(8319, 5);
tokenLOT = 8319;
}
inventoryComponent->AddItem(tokenLOT, 5, eLootSourceType::LOOT_SOURCE_NONE);
missionComponent->ForceProgressTaskType(863, 1, 1, false);
GameMessages::SendTerminateInteraction(user->GetObjectID(), FROM_INTERACTION, self->GetObjectID());

View File

@@ -29,7 +29,7 @@ void NtDukeServer::OnMissionDialogueOK(Entity *self, Entity *target, int mission
auto lotCount = inventoryComponent->GetLotCount(m_SwordLot);
if ((state == MissionState::MISSION_STATE_AVAILABLE || state == MissionState::MISSION_STATE_ACTIVE) && lotCount < 1) {
inventoryComponent->AddItem(m_SwordLot, 1);
inventoryComponent->AddItem(m_SwordLot, 1, eLootSourceType::LOOT_SOURCE_NONE);
} else if (state == MissionState::MISSION_STATE_READY_TO_COMPLETE) {
inventoryComponent->RemoveItem(m_SwordLot, lotCount);
}

View File

@@ -0,0 +1,45 @@
#include "RockHydrantBroken.h"
#include "EntityManager.h"
#include "GameMessages.h"
void RockHydrantBroken::OnStartup(Entity* self)
{
self->AddTimer("playEffect", 1);
const auto hydrant = "hydrant" + self->GetVar<std::string>(u"hydrant");
const auto bouncers = EntityManager::Instance()->GetEntitiesInGroup(hydrant);
for (auto* bouncer : bouncers)
{
self->SetVar<LWOOBJID>(u"bouncer", bouncer->GetObjectID());
GameMessages::SendBouncerActiveStatus(bouncer->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS);
GameMessages::SendNotifyObject(bouncer->GetObjectID(), self->GetObjectID(), u"enableCollision", UNASSIGNED_SYSTEM_ADDRESS);
}
self->AddTimer("KillBroken", 10);
}
void RockHydrantBroken::OnTimerDone(Entity* self, std::string timerName)
{
if (timerName == "KillBroken")
{
auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"bouncer"));
if (bouncer != nullptr)
{
GameMessages::SendBouncerActiveStatus(bouncer->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS);
GameMessages::SendNotifyObject(bouncer->GetObjectID(), self->GetObjectID(), u"disableCollision", UNASSIGNED_SYSTEM_ADDRESS);
}
self->Kill();
}
else if (timerName == "playEffect")
{
GameMessages::SendPlayFXEffect(self->GetObjectID(), 4737, u"water", "water", LWOOBJID_EMPTY, 1, 1, true);
}
}

View File

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

View File

@@ -1,24 +1,21 @@
#include "RockHydrantSmashable.h"
#include "EntityManager.h"
#include "SimplePhysicsComponent.h"
#include "Entity.h"
#include "GameMessages.h"
#include "Game.h"
#include "dLogger.h"
#include "GeneralUtils.h"
void RockHydrantSmashable::OnDie(Entity* self, Entity* killer) {
SimplePhysicsComponent* physics = self->GetComponent<SimplePhysicsComponent>();
NiPoint3 pos = physics->GetPosition();
void RockHydrantSmashable::OnDie(Entity* self, Entity* killer)
{
const auto hydrantName = self->GetVar<std::u16string>(u"hydrant");
EntityInfo info;
info.lot = 12293;
info.pos = pos;
info.spawner = nullptr;
LDFBaseData* data = new LDFData<std::string>(u"hydrant", GeneralUtils::UTF16ToWTF8(hydrantName));
EntityInfo info {};
info.lot = ROCK_HYDRANT_BROKEN;
info.pos = self->GetPosition();
info.rot = self->GetRotation();
info.settings = {data};
info.spawnerID = self->GetSpawnerID();
info.spawnerNodeID = 0;
Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr);
if (newEntity) {
EntityManager::Instance()->ConstructEntity(newEntity);
}
}
auto* hydrant = EntityManager::Instance()->CreateEntity(info);
EntityManager::Instance()->ConstructEntity(hydrant);
}

View File

@@ -5,5 +5,7 @@ class RockHydrantSmashable : public CppScripts::Script
{
public:
void OnDie(Entity* self, Entity* killer);
private:
LOT ROCK_HYDRANT_BROKEN = 12293;
};

View File

@@ -574,7 +574,7 @@ void SGCannon::StopGame(Entity *self, bool cancel) {
auto* inventory = player->GetComponent<InventoryComponent>();
if (inventory != nullptr) {
for (const auto rewardLot : self->GetVar<std::vector<LOT>>(RewardsVariable)) {
inventory->AddItem(rewardLot, 1, eInventoryType::MODELS);
inventory->AddItem(rewardLot, 1, eLootSourceType::LOOT_SOURCE_ACTIVITY, eInventoryType::MODELS);
}
}

View File

@@ -21,15 +21,17 @@ void TokenConsoleServer::OnUse(Entity* self, Entity* user) {
//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
inv->AddItem(8321, tokensToGive);
tokenLOT = 8321;
else if (character->GetPlayerFlag(ePlayerFlags::ASSEMBLY_FACTION)) //assembly
inv->AddItem(8318, tokensToGive);
tokenLOT = 8318;
else if (character->GetPlayerFlag(ePlayerFlags::PARADOX_FACTION)) //paradox
inv->AddItem(8320, tokensToGive);
tokenLOT = 8320;
else if (character->GetPlayerFlag(ePlayerFlags::SENTINEL_FACTION)) //sentinel
inv->AddItem(8319, tokensToGive);
tokenLOT = 8319;
inv->AddItem(tokenLOT, tokensToGive, eLootSourceType::LOOT_SOURCE_NONE);
}
GameMessages::SendTerminateInteraction(user->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID());

View File

@@ -10,7 +10,7 @@ void VeBricksampleServer::OnUse(Entity *self, Entity *user) {
auto* inventoryComponent = user->GetComponent<InventoryComponent>();
if (loot && inventoryComponent != nullptr && inventoryComponent->GetLotCount(loot) == 0) {
inventoryComponent->AddItem(loot, 1);
inventoryComponent->AddItem(loot, 1, eLootSourceType::LOOT_SOURCE_ACTIVITY);
for (auto* brickEntity : EntityManager::Instance()->GetEntitiesInGroup("Bricks")) {
GameMessages::SendNotifyClientObject(brickEntity->GetObjectID(), u"Pickedup");

View File

@@ -8,7 +8,7 @@ void VeMissionConsole::OnUse(Entity *self, Entity *user) {
auto* inventoryComponent = user->GetComponent<InventoryComponent>();
if (inventoryComponent != nullptr) {
inventoryComponent->AddItem(12547, 1); // Add the panel required for pickup
inventoryComponent->AddItem(12547, 1, eLootSourceType::LOOT_SOURCE_ACTIVITY); // Add the panel required for pickup
}
// The flag to set is 101<number>

69
dScripts/WhFans.cpp Normal file
View File

@@ -0,0 +1,69 @@
#include "WhFans.h"
#include "RenderComponent.h"
void WhFans::OnStartup(Entity* self) {
self->SetVar<bool>(u"alive", true);
self->SetVar<bool>(u"on", false);
ToggleFX(self, false);
}
void WhFans::ToggleFX(Entity* self, bool hit) {
std::string fanGroup;
const auto& groups = self->GetGroups();
if (!groups.empty()) {
fanGroup = groups[0];
} else {
fanGroup = "";
}
std::vector<Entity*> fanVolumes = EntityManager::Instance()->GetEntitiesInGroup(fanGroup);
auto* renderComponent = self->GetComponent<RenderComponent>();
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) {
auto volumePhys = volume->GetComponent<PhantomPhysicsComponent>();
if (!volumePhys) continue;
volumePhys->SetPhysicsEffectActive(false);
EntityManager::Instance()->SerializeEntity(volume);
}
}
else if (!self->GetVar<bool>(u"on") && self->GetVar<bool>(u"alive")) {
GameMessages::SendPlayAnimation(self, u"fan-on");
self->SetVar<bool>(u"on", true);
for (Entity* volume : fanVolumes) {
auto volumePhys = volume->GetComponent<PhantomPhysicsComponent>();
if (!volumePhys) continue;
volumePhys->SetPhysicsEffectActive(true);
EntityManager::Instance()->SerializeEntity(volume);
}
}
}
void WhFans::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 WhFans::OnDie(Entity* self, Entity* killer) {
if (self->GetVar<bool>(u"on")) {
ToggleFX(self, true);
}
self->SetVar<bool>(u"alive", false);
}

23
dScripts/WhFans.h Normal file
View File

@@ -0,0 +1,23 @@
#pragma once
#include "CppScripts.h"
#include "GameMessages.h"
#include "EntityManager.h"
#include "PhantomPhysicsComponent.h"
class WhFans : 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);
};