Skip to content

Commit

Permalink
Merge branch 'master' into feat/debug-system
Browse files Browse the repository at this point in the history
  • Loading branch information
Force67 committed Jan 22, 2022
2 parents 73987a4 + 7233d04 commit 00152a9
Show file tree
Hide file tree
Showing 53 changed files with 2,752 additions and 76 deletions.
51 changes: 51 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
# [1.10.0](https://github.com/tiltedphoques/TiltedEvolution/compare/v1.9.0...v1.10.0) (2022-01-21)


### Bug Fixes

* build error ([e7c1f9a](https://github.com/tiltedphoques/TiltedEvolution/commit/e7c1f9a9ab83e994ed848d9a122dd11922521915))
* build errors ([4826b8b](https://github.com/tiltedphoques/TiltedEvolution/commit/4826b8b4db1f8170e789f60e8b385092632c6d39))
* moved opcode check ([f168015](https://github.com/tiltedphoques/TiltedEvolution/commit/f168015c01b36dacec8d9e4a014ff37bbfc967e7))
* variable naming convention ([47f3e70](https://github.com/tiltedphoques/TiltedEvolution/commit/47f3e7093bd31a09e2d84742767e369e9e34f57a))


### Features

* remote horses are now synced ([a8a267a](https://github.com/tiltedphoques/TiltedEvolution/commit/a8a267a9229e8a239bd6d6411590b2171d1d0871))
* take control of remote horse ([400c12e](https://github.com/tiltedphoques/TiltedEvolution/commit/400c12e0a6065e021a7a2ace7744c2e283347aba))
* trigger mounting ([6fe7d4a](https://github.com/tiltedphoques/TiltedEvolution/commit/6fe7d4a04f0f898d303e43d1b9c37714c1535a57))

# [1.9.0](https://github.com/tiltedphoques/TiltedEvolution/compare/v1.8.0...v1.9.0) (2022-01-21)


### Bug Fixes

* compression bug in es parser ([426a251](https://github.com/tiltedphoques/TiltedEvolution/commit/426a25147c65b3436aee49806d1f624e1605540d))
* script property parsing ([3018ad7](https://github.com/tiltedphoques/TiltedEvolution/commit/3018ad761eb098573113e0b245d590e9740f23a0))
* static var rename ([6919096](https://github.com/tiltedphoques/TiltedEvolution/commit/69190962da08c63ed2222cbfb7bd144ec4638d94))


### Features

* another attempt at full inventory control ([4f8fbe0](https://github.com/tiltedphoques/TiltedEvolution/commit/4f8fbe0cf9b0386f75f3002cdd2aac88f01b8f6a))
* base id assignment for parsed records ([dee225a](https://github.com/tiltedphoques/TiltedEvolution/commit/dee225a22f4700420e9c0e595201a2c97f73eced))
* chunk sorting and parsing on REFR records ([8c196f5](https://github.com/tiltedphoques/TiltedEvolution/commit/8c196f523d71242a95266c52375c89d47e70cdef))
* copy parse chunks ([47e0441](https://github.com/tiltedphoques/TiltedEvolution/commit/47e04410994b976c7be0d1a3a2ba8c914fb89b9d))
* ESLoader setup ([3f8dd1b](https://github.com/tiltedphoques/TiltedEvolution/commit/3f8dd1bcc72a6af35276fc76d3301adc2d5a3be4))
* fetch es files from Data/ ([39bfed8](https://github.com/tiltedphoques/TiltedEvolution/commit/39bfed88439f6d365dc02eaf2685ac89a10b528e))
* index parent esms and handle overwritten records ([7866a42](https://github.com/tiltedphoques/TiltedEvolution/commit/7866a42bdf24a21362830a08009e35eebdb32b31))
* integrated es parser into server ([7bd1acd](https://github.com/tiltedphoques/TiltedEvolution/commit/7bd1acd3bf5b4415a5445efb2c29a4adc7ae25d8))
* iterate and parse chunks in record ([173e3ee](https://github.com/tiltedphoques/TiltedEvolution/commit/173e3ee30ceb84a724d5101f1012881a103baaf9))
* load esm data and record base ([a208a85](https://github.com/tiltedphoques/TiltedEvolution/commit/a208a851ea08822a9d1308067f569ca6d8280b61))
* load game settings on server ([b0e1c33](https://github.com/tiltedphoques/TiltedEvolution/commit/b0e1c33dab4c1b4f75cb329acc50b6f43fb8388b))
* parse climate records ([dde6f16](https://github.com/tiltedphoques/TiltedEvolution/commit/dde6f1686e920b34776767aaeb7e8b683b5ad4d3))
* parse containers and decoded scripts data ([1ff6f73](https://github.com/tiltedphoques/TiltedEvolution/commit/1ff6f73ff341072c7e45c28bfb4cb8c1284f94cc))
* parse group headers ([46eb291](https://github.com/tiltedphoques/TiltedEvolution/commit/46eb2915ac054bdcbb1815ad27888c1a1bd3c180))
* parse map markers ([fb45e77](https://github.com/tiltedphoques/TiltedEvolution/commit/fb45e7761ca57c3fabef9d3de143e60853d21b17))
* parse NPCs ([5ce7919](https://github.com/tiltedphoques/TiltedEvolution/commit/5ce79195df3a592b289967f7a85d45dc339231c3))
* parse records and groups, and fetch fields ([a3e69f2](https://github.com/tiltedphoques/TiltedEvolution/commit/a3e69f2fa30dbe0ab1f11bb0f8dbf8b2ce6918b3))
* RecordCollection ([98c0825](https://github.com/tiltedphoques/TiltedEvolution/commit/98c0825e492b46670f3bfc30a046c98e70867454))
* sort files by esm/esp/esl ([e4ec55a](https://github.com/tiltedphoques/TiltedEvolution/commit/e4ec55a49479f6bbff67d7286534c8be96ba1a05))
* store cell records ([8b4021d](https://github.com/tiltedphoques/TiltedEvolution/commit/8b4021d19e4fca8106dd1e5930b1c64f55740451))
* working es parser ([ee5271e](https://github.com/tiltedphoques/TiltedEvolution/commit/ee5271eb5fadb66521e5f8f1ed4665a1157288c3))

# [1.8.0](https://github.com/tiltedphoques/TiltedEvolution/compare/v1.7.0...v1.8.0) (2022-01-17)


Expand Down
11 changes: 11 additions & 0 deletions Code/client/Events/MountEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

struct MountEvent
{
MountEvent(uint32_t aRiderID, uint32_t aMountID)
: RiderID(aRiderID), MountID(aMountID)
{}

uint32_t RiderID;
uint32_t MountID;
};
1 change: 1 addition & 0 deletions Code/client/Games/BSAnimationGraphManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ uint64_t BSAnimationGraphManager::GetDescriptorKey(int aForceIndex)
}
}

// TODO: this sometimes crashes when appending. Adding logging seems to fix it. Ask cosi for repro
for(auto& [id, name] : variables)
{
variableNames += name;
Expand Down
2 changes: 1 addition & 1 deletion Code/client/Games/Primitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ struct GamePtr

GamePtr& operator=(GamePtr<T>&& acRhs)
{
std::swap(m_pPointer, acRhs.m_pPointer);
std::swap(m_pPointer, aRhs.m_pPointer);

return *this;
}
Expand Down
26 changes: 25 additions & 1 deletion Code/client/Games/Skyrim/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <Events/HealthChangeEvent.h>
#include <Events/InventoryChangeEvent.h>
#include <Events/MountEvent.h>

#include <World.h>
#include <Services/PapyrusService.h>
Expand Down Expand Up @@ -350,6 +351,7 @@ void Actor::SetInventory(const Inventory& acInventory) noexcept
pEquipManager->Equip(this, pAmmo, nullptr, count, DefaultObjectManager::Get().rightEquipSlot, false, true, false, false);
}

// TODO: check if weapon drawn state is the same
SetWeaponDrawnEx(acInventory.IsWeaponDrawn);
}

Expand Down Expand Up @@ -464,6 +466,14 @@ void Actor::RemoveFromAllFactions() noexcept
s_pRemoveFromAllFactions(this);
}

TP_THIS_FUNCTION(TInitiateMountPackage, bool, Actor, Actor* apMount);
static TInitiateMountPackage* RealInitiateMountPackage = nullptr;

bool Actor::InitiateMountPackage(Actor* apMount) noexcept
{
return ThisCall(RealInitiateMountPackage, this, apMount);
}

bool Actor::IsDead() noexcept
{
PAPYRUS_FUNCTION(bool, Actor, IsDead);
Expand Down Expand Up @@ -650,7 +660,7 @@ void TP_MAKE_THISCALL(HookUpdateDetectionState, ActorKnowledge, void* apState)

struct DialogueItem;

// This is an AIProcess function
// TODO: This is an AIProcess function
TP_THIS_FUNCTION(TProcessResponse, uint64_t, void, DialogueItem* apVoice, Actor* apTalkingActor, Actor* apTalkedToActor);
static TProcessResponse* RealProcessResponse = nullptr;

Expand All @@ -664,6 +674,17 @@ uint64_t TP_MAKE_THISCALL(HookProcessResponse, void, DialogueItem* apVoice, Acto
return ThisCall(RealProcessResponse, apThis, apVoice, apTalkingActor, apTalkedToActor);
}

bool TP_MAKE_THISCALL(HookInitiateMountPackage, Actor, Actor* apMount)
{
if (!apMount)
{
return ThisCall(RealInitiateMountPackage, apThis, apMount);
}

World::Get().GetRunner().Trigger(MountEvent(apThis->formID, apMount->formID));
return ThisCall(RealInitiateMountPackage, apThis, apMount);
}

static TiltedPhoques::Initializer s_actorHooks([]()
{
POINTER_SKYRIMSE(TCharacterConstructor, s_characterCtor, 0x1406BA280 - 0x140000000);
Expand All @@ -679,6 +700,7 @@ static TiltedPhoques::Initializer s_actorHooks([]()
POINTER_SKYRIMSE(TPickUpItem, s_pickUpItem, 0x14060C280 - 0x140000000);
POINTER_SKYRIMSE(TUpdateDetectionState, s_updateDetectionState, 0x140742FE0 - 0x140000000);
POINTER_SKYRIMSE(TProcessResponse, s_processResponse, 0x14068BC50 - 0x140000000);
POINTER_SKYRIMSE(TInitiateMountPackage, s_initiateMountPackage, 0x14062CF40 - 0x140000000);

FUNC_GetActorLocation = s_GetActorLocation.Get();
RealCharacterConstructor = s_characterCtor.Get();
Expand All @@ -692,6 +714,7 @@ static TiltedPhoques::Initializer s_actorHooks([]()
RealPickUpItem = s_pickUpItem.Get();
RealUpdateDetectionState = s_updateDetectionState.Get();
RealProcessResponse = s_processResponse.Get();
RealInitiateMountPackage = s_initiateMountPackage.Get();

TP_HOOK(&RealCharacterConstructor, HookCharacterConstructor);
TP_HOOK(&RealCharacterConstructor2, HookCharacterConstructor2);
Expand All @@ -704,4 +727,5 @@ static TiltedPhoques::Initializer s_actorHooks([]()
TP_HOOK(&RealPickUpItem, HookPickUpItem);
TP_HOOK(&RealUpdateDetectionState, HookUpdateDetectionState);
TP_HOOK(&RealProcessResponse, HookProcessResponse);
TP_HOOK(&RealInitiateMountPackage, HookInitiateMountPackage);
});
1 change: 1 addition & 0 deletions Code/client/Games/Skyrim/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ struct Actor : TESObjectREFR
void UnEquipAll() noexcept;
void RemoveFromAllFactions() noexcept;
void QueueUpdate() noexcept;
bool InitiateMountPackage(Actor* apMount) noexcept;

bool IsDead() noexcept;
void Kill() noexcept;
Expand Down
8 changes: 8 additions & 0 deletions Code/client/Games/Skyrim/Forms/AlchemyItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include "TESForm.h"

struct AlchemyItem : TESForm
{

};
8 changes: 8 additions & 0 deletions Code/client/Games/Skyrim/Forms/EnchantmentItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include "TESForm.h"

struct EnchantmentItem : TESForm
{

};
6 changes: 6 additions & 0 deletions Code/client/Services/CharacterService.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ struct AddTargetEvent;
struct NotifyAddTarget;
struct ProjectileLaunchedEvent;
struct NotifyProjectileLaunch;
struct MountEvent;
struct NotifyMount;

struct Actor;
struct World;
Expand Down Expand Up @@ -50,6 +52,8 @@ struct CharacterService
void OnRemoteSpawnDataReceived(const NotifySpawnData& acEvent) const noexcept;
void OnProjectileLaunchedEvent(const ProjectileLaunchedEvent& acEvent) const noexcept;
void OnNotifyProjectileLaunch(const NotifyProjectileLaunch& acMessage) const noexcept;
void OnMountEvent(const MountEvent& acEvent) const noexcept;
void OnNotifyMount(const NotifyMount& acMessage) const noexcept;

private:

Expand Down Expand Up @@ -82,4 +86,6 @@ struct CharacterService
entt::scoped_connection m_remoteSpawnDataReceivedConnection;
entt::scoped_connection m_projectileLaunchedConnection;
entt::scoped_connection m_projectileLaunchConnection;
entt::scoped_connection m_mountConnection;
entt::scoped_connection m_notifyMountConnection;
};
12 changes: 8 additions & 4 deletions Code/client/Services/DiscoveryService.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ struct DiscoveryService final

private:

void ResetCachedCellData() noexcept;
void VisitExteriorCell(bool aForceTrigger) noexcept;
void VisitInteriorCell(bool aForceTrigger) noexcept;

World& m_world;
entt::dispatcher& m_dispatcher;

Set<uint32_t> m_forms;
int32_t m_centerGridX = 0xFFFF;
int32_t m_centerGridY = 0xFFFF;
int32_t m_currentGridX = 0xFFFF;
int32_t m_currentGridY = 0xFFFF;
int32_t m_centerGridX = 0x7FFFFFFF;
int32_t m_centerGridY = 0x7FFFFFFF;
int32_t m_currentGridX = 0x7FFFFFFF;
int32_t m_currentGridY = 0x7FFFFFFF;
uint32_t m_worldSpaceId = 0;
uint32_t m_interiorCellId = 0;
struct TESForm *m_pLocation = nullptr;
Expand Down
125 changes: 125 additions & 0 deletions Code/client/Services/Generic/CharacterService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <Events/EquipmentChangeEvent.h>
#include <Events/UpdateEvent.h>
#include <Events/ProjectileLaunchedEvent.h>
#include <Events/MountEvent.h>

#include <Structs/ActionEvent.h>
#include <Messages/CancelAssignmentRequest.h>
Expand All @@ -50,6 +51,8 @@
#include <Messages/RequestOwnershipClaim.h>
#include <Messages/ProjectileLaunchRequest.h>
#include <Messages/NotifyProjectileLaunch.h>
#include <Messages/MountRequest.h>
#include <Messages/NotifyMount.h>

#include <World.h>
#include <Games/TES.h>
Expand Down Expand Up @@ -79,8 +82,12 @@ CharacterService::CharacterService(World& aWorld, entt::dispatcher& aDispatcher,
m_ownershipTransferConnection = m_dispatcher.sink<NotifyOwnershipTransfer>().connect<&CharacterService::OnOwnershipTransfer>(this);
m_removeCharacterConnection = m_dispatcher.sink<NotifyRemoveCharacter>().connect<&CharacterService::OnRemoveCharacter>(this);
m_remoteSpawnDataReceivedConnection = m_dispatcher.sink<NotifySpawnData>().connect<&CharacterService::OnRemoteSpawnDataReceived>(this);

m_projectileLaunchedConnection = m_dispatcher.sink<ProjectileLaunchedEvent>().connect<&CharacterService::OnProjectileLaunchedEvent>(this);
m_projectileLaunchConnection = m_dispatcher.sink<NotifyProjectileLaunch>().connect<&CharacterService::OnNotifyProjectileLaunch>(this);

m_mountConnection = m_dispatcher.sink<MountEvent>().connect<&CharacterService::OnMountEvent>(this);
m_notifyMountConnection = m_dispatcher.sink<NotifyMount>().connect<&CharacterService::OnNotifyMount>(this);
}

void CharacterService::OnFormIdComponentAdded(entt::registry& aRegistry, const entt::entity aEntity) const noexcept
Expand Down Expand Up @@ -1139,3 +1146,121 @@ void CharacterService::OnNotifyProjectileLaunch(const NotifyProjectileLaunch& ac
Projectile::Launch(&result, launchData);
}

void CharacterService::OnMountEvent(const MountEvent& acEvent) const noexcept
{
#if TP_SKYRIM64
auto view = m_world.view<FormIdComponent>();

const auto riderIt = std::find_if(std::begin(view), std::end(view), [id = acEvent.RiderID, view](auto entity) {
return view.get<FormIdComponent>(entity).Id == id;
});

if (riderIt == std::end(view))
{
spdlog::warn("Rider not found, form id: {:X}", acEvent.RiderID);
return;
}

const entt::entity cRiderEntity = *riderIt;

std::optional<uint32_t> riderServerIdRes = utils::GetServerId(cRiderEntity);
if (!riderServerIdRes.has_value())
return;

const auto mountIt = std::find_if(std::begin(view), std::end(view), [id = acEvent.MountID, view](auto entity) {
return view.get<FormIdComponent>(entity).Id == id;
});

if (mountIt == std::end(view))
{
spdlog::warn("Mount not found, form id: {:X}", acEvent.MountID);
return;
}

const entt::entity cMountEntity = *mountIt;

std::optional<uint32_t> mountServerIdRes = utils::GetServerId(cMountEntity);
if (!mountServerIdRes.has_value())
return;

if (m_world.try_get<RemoteComponent>(cMountEntity))
{
const TESForm* pMountForm = TESForm::GetById(acEvent.MountID);
Actor* pMount = RTTI_CAST(pMountForm, TESForm, Actor);
pMount->GetExtension()->SetRemote(false);

m_world.emplace<LocalComponent>(cMountEntity, mountServerIdRes.value());
m_world.emplace<LocalAnimationComponent>(cMountEntity);
m_world.remove<RemoteComponent, InterpolationComponent, RemoteAnimationComponent,
FaceGenComponent, CacheComponent, WaitingFor3D>(cMountEntity);

RequestOwnershipClaim request;
request.ServerId = mountServerIdRes.value();

m_transport.Send(request);
}

MountRequest request;
request.MountId = mountServerIdRes.value();
request.RiderId = riderServerIdRes.value();

m_transport.Send(request);
#endif
}

void CharacterService::OnNotifyMount(const NotifyMount& acMessage) const noexcept
{
#if TP_SKYRIM64
auto remoteView = m_world.view<RemoteComponent, FormIdComponent>();

const auto riderIt = std::find_if(std::begin(remoteView), std::end(remoteView), [remoteView, Id = acMessage.RiderId](auto entity)
{
return remoteView.get<RemoteComponent>(entity).Id == Id;
});

if (riderIt == std::end(remoteView))
{
spdlog::warn("Rider with remote id {:X} not found.", acMessage.RiderId);
return;
}

auto riderFormIdComponent = remoteView.get<FormIdComponent>(*riderIt);
TESForm* pRiderForm = TESForm::GetById(riderFormIdComponent.Id);
Actor* pRider = RTTI_CAST(pRiderForm, TESForm, Actor);

Actor* pMount = nullptr;

auto formView = m_world.view<FormIdComponent>();
for (auto entity : formView)
{
std::optional<uint32_t> serverIdRes = utils::GetServerId(entity);
if (!serverIdRes.has_value())
continue;

uint32_t serverId = serverIdRes.value();

if (serverId == acMessage.MountId)
{
auto mountFormIdComponent = formView.get<FormIdComponent>(entity);

if (m_world.all_of<LocalComponent>(entity))
{
m_world.remove<LocalAnimationComponent, LocalComponent>(entity);
m_world.emplace_or_replace<RemoteComponent>(entity, acMessage.MountId, mountFormIdComponent.Id);
}

TESForm* pMountForm = TESForm::GetById(mountFormIdComponent.Id);
pMount = RTTI_CAST(pMountForm, TESForm, Actor);
pMount->GetExtension()->SetRemote(true);

InterpolationSystem::Setup(m_world, entity);
AnimationSystem::Setup(m_world, entity);

break;
}
}

pRider->InitiateMountPackage(pMount);
#endif
}

Loading

0 comments on commit 00152a9

Please sign in to comment.