Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Darkflame Cinema #1294

Draft
wants to merge 31 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9e56725
Initial changes.
Wincent01 Oct 22, 2023
da236f2
Merge remote-tracking branch 'refs/remotes/origin/main'
Wincent01 Oct 22, 2023
01b40ff
Merge fix
Wincent01 Oct 22, 2023
b274ea1
Substational additions to dCinema
Wincent01 Oct 27, 2023
3f90a4d
Merge remote-tracking branch 'origin/main' into dCinema
Wincent01 Oct 28, 2023
e4320d3
Brought the branch up to speed
Wincent01 Oct 28, 2023
cdc9dda
dCinema improvements
Wincent01 Oct 29, 2023
9954e20
More scene metadata
Wincent01 Oct 30, 2023
54060f7
Minor refactor
Wincent01 Nov 11, 2023
a09bbdb
Merge remote-tracking branch 'origin/main' into dCinema
Wincent01 Nov 11, 2023
14d4c87
More record types:
Wincent01 Nov 14, 2023
e546737
Reverted local CMakeVariables changes
Wincent01 Nov 14, 2023
7a7bdba
Removed test script
Wincent01 Nov 14, 2023
25e1482
Merge remote-tracking branch 'origin/main' into dCinema
Wincent01 Nov 14, 2023
32cbd18
Fix CMake file
Wincent01 Nov 14, 2023
17a62d9
Resolved some comments
Wincent01 Nov 20, 2023
3a60fff
Resolved some more comments
Wincent01 Nov 20, 2023
a91cf3a
Merge remote-tracking branch 'refs/remotes/origin/main'
Wincent01 Jan 16, 2024
7b7c062
Update to new API
Wincent01 Jan 16, 2024
88e5f0e
Merge remote-tracking branch 'refs/remotes/origin/main'
Wincent01 Feb 17, 2024
685bd5d
Updated to new API
Wincent01 Feb 17, 2024
d52ce80
Merge remote-tracking branch 'refs/remotes/origin/main'
Wincent01 Apr 2, 2024
3efad8a
Merge remote-tracking branch 'origin/main' into dCinema
Wincent01 Sep 8, 2024
c948e4b
Update to new apis
Wincent01 Sep 8, 2024
0d37da7
Add a max showing distance
Wincent01 Sep 8, 2024
06063c8
Fixed mission related preconditions
Wincent01 Sep 10, 2024
a086fe7
Added clean-up param
Wincent01 Sep 10, 2024
dfe9240
Amend preconditions fix
Wincent01 Sep 12, 2024
04e9e74
Additional record types
Wincent01 Sep 12, 2024
f78b28b
New records and commands
Wincent01 Sep 12, 2024
bd863a6
Added a navmesh for old gf
Wincent01 Sep 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ set(INCLUDED_DIRECTORIES
"dGame/dInventory"
"dGame/dMission"
"dGame/dEntity"
"dGame/dCinema"
"dGame/dPropertyBehaviors"
"dGame/dPropertyBehaviors/ControlBehaviorMessages"
"dGame/dUtilities"
Expand Down
4 changes: 2 additions & 2 deletions CMakeVariables.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ LICENSE=AGPL-3.0
# Set __dynamic to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs.
__dynamic=1
# Set __ggdb to 1 to enable the -ggdb flag for the linker, including more debug info.
# __ggdb=1
#__ggdb=1
# Set __include_backtrace__ to 1 to includes the backtrace library for better crashlogs.
# __include_backtrace__=1
#__include_backtrace__=1
Wincent01 marked this conversation as resolved.
Show resolved Hide resolved
# Set __compile_backtrace__ to 1 to compile the backtrace library instead of using system libraries.
# __compile_backtrace__=1
# Set to the number of jobs (make -j equivalent) to compile the mariadbconn files with.
Expand Down
8 changes: 7 additions & 1 deletion dCommon/dConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ void dConfig::ReloadConfig() {
}

const std::string& dConfig::GetValue(std::string key) {
return this->m_ConfigValues[key];
static std::string emptyString{};

const auto& it = this->m_ConfigValues.find(key);

if (it == this->m_ConfigValues.end()) return emptyString;

return it->second;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any particular reason you moved away from operator subscripting here? The memory usage here is in the bytes, so I dont see why we'd basically inline the subscripting

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we were troubleshooting the SQL stuff this was where a crash was occuring.

}

void dConfig::ProcessLine(const std::string& line) {
Expand Down
6 changes: 6 additions & 0 deletions dGame/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,16 @@
set(DGAME_SOURCES ${DGAME_SOURCES} "dUtilities/${file}")
endforeach()

add_subdirectory(dCinema)

foreach(file ${DGAME_DCINEMA_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "dCinema/${file}")
endforeach()

foreach(file ${DSCRIPTS_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "${PROJECT_SOURCE_DIR}/dScripts/${file}")
endforeach()

add_library(dGame STATIC ${DGAME_SOURCES})

Check failure on line 69 in dGame/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / Build & Test (windows-2022)

Cannot find source file:

Check failure on line 69 in dGame/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / Build & Test (windows-2022)

No SOURCES given to target: dGame

Check failure on line 69 in dGame/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / Build & Test (ubuntu-20.04)

Cannot find source file:

Check failure on line 69 in dGame/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / Build & Test (ubuntu-20.04)

No SOURCES given to target: dGame

Check failure on line 69 in dGame/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / Build & Test (macos-11)

Cannot find source file:

Check failure on line 69 in dGame/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / Build & Test (macos-11)

No SOURCES given to target: dGame

target_link_libraries(dGame dDatabase Recast Detour)
13 changes: 9 additions & 4 deletions dGame/EntityManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "eGameMasterLevel.h"
#include "eReplicaComponentType.h"
#include "eReplicaPacketType.h"
#include "ServerPreconditions.hpp"
Wincent01 marked this conversation as resolved.
Show resolved Hide resolved

// Configure which zones have ghosting disabled, mostly small worlds.
std::vector<LWOMAPID> EntityManager::m_GhostingExcludedZones = {
Expand Down Expand Up @@ -518,13 +519,15 @@ void EntityManager::UpdateGhosting(Player* player) {
ghostingDistanceMax = ghostingDistanceMin;
}

if (observed && distance > ghostingDistanceMax && !isOverride) {
auto condition = ServerPreconditions::CheckPreconditions(entity, player);

if (observed && ((distance > ghostingDistanceMax && !isOverride) || !condition)) {
player->GhostEntity(id);

DestructEntity(entity, player->GetSystemAddress());

entity->SetObservers(entity->GetObservers() - 1);
} else if (!observed && ghostingDistanceMin > distance) {
} else if (!observed && ghostingDistanceMin > distance && condition) {
// Check collectables, don't construct if it has been collected
uint32_t collectionId = entity->GetCollectibleID();

Expand Down Expand Up @@ -566,13 +569,15 @@ void EntityManager::CheckGhosting(Entity* entity) {

const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);

if (observed && distance > ghostingDistanceMax) {
const auto precondition = ServerPreconditions::CheckPreconditions(entity, player);

if (observed && (distance > ghostingDistanceMax || !precondition)) {
player->GhostEntity(id);

DestructEntity(entity, player->GetSystemAddress());

entity->SetObservers(entity->GetObservers() - 1);
} else if (!observed && ghostingDistanceMin > distance) {
} else if (!observed && (ghostingDistanceMin > distance && precondition)) {
player->ObserveEntity(id);

ConstructEntity(entity, player->GetSystemAddress());
Expand Down
44 changes: 10 additions & 34 deletions dGame/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Enti
m_GhostReferencePoint = NiPoint3::ZERO;
m_GhostOverridePoint = NiPoint3::ZERO;
m_GhostOverride = false;
m_ObservedEntitiesLength = 256;
m_ObservedEntitiesUsed = 0;
m_ObservedEntities.resize(m_ObservedEntitiesLength);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This had no right being a vector instead of a set

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should be moved to a separate PR since it is quite isolated and a good improvement.


m_Character->SetEntity(this);

Expand Down Expand Up @@ -180,41 +177,21 @@ bool Player::GetGhostOverride() const {
}

void Player::ObserveEntity(int32_t id) {
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
if (m_ObservedEntities[i] == 0 || m_ObservedEntities[i] == id) {
m_ObservedEntities[i] = id;

return;
}
}

const auto index = m_ObservedEntitiesUsed++;

if (m_ObservedEntitiesUsed > m_ObservedEntitiesLength) {
m_ObservedEntities.resize(m_ObservedEntitiesLength + m_ObservedEntitiesLength);

m_ObservedEntitiesLength = m_ObservedEntitiesLength + m_ObservedEntitiesLength;
}

m_ObservedEntities[index] = id;
m_ObservedEntities.emplace(id);
}

bool Player::IsObserved(int32_t id) {
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
if (m_ObservedEntities[i] == id) {
return true;
}
}

return false;
return m_ObservedEntities.find(id) != m_ObservedEntities.end();
}

void Player::GhostEntity(int32_t id) {
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
if (m_ObservedEntities[i] == id) {
m_ObservedEntities[i] = 0;
}
const auto& iter = m_ObservedEntities.find(id);

if (iter == m_ObservedEntities.end()) {
return;
}

m_ObservedEntities.erase(iter);
}

Player* Player::GetPlayer(const SystemAddress& sysAddr) {
Expand Down Expand Up @@ -262,9 +239,8 @@ void Player::SetDroppedCoins(uint64_t value) {
Player::~Player() {
LOG("Deleted player");

for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
const auto id = m_ObservedEntities[i];

for (const auto& id : m_ObservedEntities)
{
if (id == 0) {
continue;
}
Expand Down
8 changes: 3 additions & 5 deletions dGame/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "Entity.h"

#include <unordered_set>

/**
* Extended Entity for player data and behavior.
*
Expand Down Expand Up @@ -120,11 +122,7 @@ class Player final : public Entity

bool m_GhostOverride;

std::vector<int32_t> m_ObservedEntities;

int32_t m_ObservedEntitiesLength;

int32_t m_ObservedEntitiesUsed;
std::unordered_set<int32_t> m_ObservedEntities;

std::vector<LWOOBJID> m_LimboConstructions;

Expand Down
4 changes: 4 additions & 0 deletions dGame/dBehaviors/AttackDelayBehavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
#include "Game.h"
#include "Logger.h"

#include "Recorder.h"

void AttackDelayBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
uint32_t handle{};

if (!bitStream->Read(handle)) {
LOG("Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
return;
};

Cinema::Recording::Recorder::RegisterEffectForActor(context->originator, this->m_effectId);

for (auto i = 0u; i < this->m_numIntervals; ++i) {
context->RegisterSyncBehavior(handle, this, branch, this->m_delay * i, m_ignoreInterrupts);
Expand Down
8 changes: 6 additions & 2 deletions dGame/dBehaviors/PlayEffectBehavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
#include "BehaviorContext.h"
#include "BehaviorBranchContext.h"

#include "Recorder.h"

void PlayEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto& target = branch.target == LWOOBJID_EMPTY ? context->originator : branch.target;

Cinema::Recording::Recorder::RegisterEffectForActor(target, this->m_effectId);

// On managed behaviors this is handled by the client
if (!context->unmanaged)
return;

const auto& target = branch.target == LWOOBJID_EMPTY ? context->originator : branch.target;

PlayFx(u"", target);
}

Expand Down
5 changes: 5 additions & 0 deletions dGame/dCinema/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
set(DGAME_DCINEMA_SOURCES "Recorder.cpp"
"Prefab.cpp"
"Scene.cpp"
"Play.cpp"
PARENT_SCOPE)
89 changes: 89 additions & 0 deletions dGame/dCinema/Play.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include "Play.h"

#include "Scene.h"

#include "EntityManager.h"

using namespace Cinema;
Wincent01 marked this conversation as resolved.
Show resolved Hide resolved

void Cinema::Play::Conclude() {
auto* player = Game::entityManager->GetEntity(this->player);

if (player == nullptr) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can simplify nullptr checks to just be if (!player) in more places than this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've alwayed prefered the clearify of comparing with nullptr, but will consider changing it.

return;
}

scene->Conclude(player);
}

void Cinema::Play::SetupCheckForAudience() {
if (m_CheckForAudience) {
return;
}

m_CheckForAudience = true;

CheckForAudience();
}

void Cinema::Play::CheckForAudience() {
auto* player = Game::entityManager->GetEntity(this->player);

if (player == nullptr) {
CleanUp();

return;
}

if (scene->IsPlayerInBounds(player)) {
SignalBarrier("audience");

m_PlayerHasBeenInsideBounds = true;
}

if (!scene->IsPlayerInShowingDistance(player)) {
if (m_PlayerHasBeenInsideBounds) {
Conclude();
}

CleanUp();

return;
}

// Still don't care
Wincent01 marked this conversation as resolved.
Show resolved Hide resolved
Game::entityManager->GetZoneControlEntity()->AddCallbackTimer(1.0f, [this]() {
CheckForAudience();
});
}

void Cinema::Play::CleanUp() {
LOG("Cleaning up play with %d entities", entities.size());

for (const auto& entity : entities) {
Game::entityManager->DestroyEntity(entity);
}
}

void Cinema::Play::SetupBarrier(const std::string& barrier, std::function<void()> callback) {
// Add the callback to the barrier
if (m_Barriers.find(barrier) == m_Barriers.end()) {
m_Barriers[barrier] = std::vector<std::function<void()>>();
}
Wincent01 marked this conversation as resolved.
Show resolved Hide resolved

m_Barriers[barrier].push_back(callback);
}

void Cinema::Play::SignalBarrier(const std::string& barrier) {
if (m_Barriers.find(barrier) == m_Barriers.end()) {
return;
}
Wincent01 marked this conversation as resolved.
Show resolved Hide resolved

for (const auto& callback : m_Barriers[barrier]) {
callback();
}

m_Barriers.erase(barrier);
}


Loading
Loading