Jump to content

I wrote code for CHW - Next Gen, but to don't have the time to do the rest


AnAtheistBear

Recommended Posts

Here's what I have. The rest of the code can be found here: https://github.com/shavkacagarikia/ClassicHolsteredWeaponsSystem

It needs to be compiled and packaged.

 

F4NVSerialization.cpp

_________________________

#include <fstream>

#include "F4NVSerialization.h"

#include "f4se/PluginAPI.h"

#include "f4se/GameObjects.h"

#include "f4se/GameReferences.h"

#include "VisibleHolster.h"

#include <array>

#include <algorithm>

 

namespace F4NVSerialization

{

    std::array<VisibleHolster::WeaponPosition, 10> SavedWeaponPositionsArr{};

 

    void RevertCallback(const F4SESerializationInterface * intfc)

    {

        // Clearing CHW serialization data.

    }

 

    void LoadCallback(const F4SESerializationInterface * intfc)

    {

        UInt32 type, version, length;

        VisibleHolster::ResetAllWeaponPos((*g_player)->GetActorRootNode(false)->GetAsNiNode());

 

        while (intfc->GetNextRecordInfo(&type, &version, &length))

        {

            switch (type)

            {

            case 'CHW':

                Load(intfc, InternalEventVersion::kCurrentVersion);

                break;

            }

        }

    }

 

    void LoadSavedPositionsData()

    {

        std::vector<VisibleHolster::WeaponPosition>* AttachPosVec = VisibleHolster::GetAttachPosVec();

        for (size_t i = 0; i < SavedWeaponPositionsArr.size(); i++)

        {

            VisibleHolster::WeaponPosition currPos = SavedWeaponPositionsArr;

            for (size_t j = 0; j < AttachPosVec->size(); j++)

            {

                VisibleHolster::WeaponPosition* originalPos = &AttachPosVec->at(j);

                if (currPos.type == HolsterType::NotSet || !originalPos) {

                    continue;

                }

                if (currPos.type == originalPos->type) {

                    originalPos->posX = currPos.posX;

                    originalPos->posY = currPos.posY;

                    originalPos->posZ = currPos.posZ;

                    originalPos->eulerAttitude = currPos.eulerAttitude;

                    originalPos->eulerBank = currPos.eulerBank;

                    originalPos->eulerHeading = currPos.eulerHeading;

                    originalPos->ResetDataOnNode((*g_player)->GetActorRootNode(false)->GetAsNiNode());

                }

            }

        }

    }

 

    void UpsertWeaponPosition(HolsterType type, float posX, float posY, float posZ, float eulerAttitude, float eulerBank, float eulerHeading)

    {

        bool found = false;

        for (size_t i = 0; i < SavedWeaponPositionsArr.size(); i++)

        {

            VisibleHolster::WeaponPosition* currPos = &SavedWeaponPositionsArr;

            if (currPos->type == HolsterType::NotSet) {

                continue;

            }

            if (currPos->type == type) {

                found = true;

                currPos->posX = posX;

                currPos->posY = posY;

                currPos->posZ = posZ;

                currPos->eulerAttitude = eulerAttitude;

                currPos->eulerBank = eulerBank;

                currPos->eulerHeading = eulerHeading;

                currPos->ResetDataOnNode((*g_player)->GetActorRootNode(false)->GetAsNiNode());

                break;

            }

        }

        if (!found && type != HolsterType::NotSet) {

            VisibleHolster::WeaponPosition newPos = {};

            newPos.type = type;

            newPos.posX = posX;

            newPos.posY = posY;

            newPos.posZ = posZ;

            newPos.eulerAttitude = eulerAttitude;

            newPos.eulerBank = eulerBank;

            newPos.eulerHeading = eulerHeading;

            newPos.ResetDataOnNode((*g_player)->GetActorRootNode(false)->GetAsNiNode());

            int index = static_cast<int>(type) - 1;

            SavedWeaponPositionsArr[index] = newPos;

        }

    }

 

    bool Load(const F4SESerializationInterface * intfc, UInt32 version)

    {

        if (!Serialization::ReadData(intfc, &SavedWeaponPositionsArr))

        {

            _MESSAGE("Cannot Load SavedWeaponPositionsArr");

            return false;

        }

        LoadSavedPositionsData();

        return true;

    }

 

    void SaveCallback(const F4SESerializationInterface * intfc)

    {

        Save(intfc, 'CHW', InternalEventVersion::kCurrentVersion);

    }

 

    bool Save(const F4SESerializationInterface * intfc, UInt32 type, UInt32 version)

    {

        intfc->OpenRecord(type, version);

        if (!intfc->WriteRecordData(&SavedWeaponPositionsArr, sizeof(SavedWeaponPositionsArr))) {

            _MESSAGE("Error writing SavedWeaponPositionsArr data");

            return false;

        }

        return true;

    }

}

_________________________

VisibleHolster.cpp

_________________________

#include "VisibleHolster.h"

#include "f4se/GameReferences.h"

#include "f4se/NiNodes.h"

#include <vector>

 

namespace VisibleHolster

{

    std::vector<WeaponPosition> attachPosVec;

 

    void ResetAllWeaponPos(NiNode* rootNode)

    {

        if (!rootNode) return;

        for (auto& weaponPos : attachPosVec)

        {

            weaponPos.posX = 0.0f;

            weaponPos.posY = 0.0f;

            weaponPos.posZ = 0.0f;

            weaponPos.eulerAttitude = 0.0f;

            weaponPos.eulerBank = 0.0f;

            weaponPos.eulerHeading = 0.0f;

            weaponPos.ResetDataOnNode(rootNode);

        }

    }

 

    std::vector<WeaponPosition>* GetAttachPosVec()

    {

        return &attachPosVec;

    }

 

    void WeaponPosition::ResetDataOnNode(NiNode* rootNode)

    {

        if (!rootNode || type == HolsterType::NotSet) return;

 

        NiNode* weaponNode = rootNode->GetObjectByName(typeToNodeName(type));

        if (!weaponNode) return;

 

        weaponNode->m_localTransform.pos.x = posX;

        weaponNode->m_localTransform.pos.y = posY;

        weaponNode->m_localTransform.pos.z = posZ;

        weaponNode->m_localTransform.rot.SetEuler(eulerAttitude, eulerBank, eulerHeading);

        weaponNode->UpdateWorldData(0.0f);

    }

 

    const char* WeaponPosition::typeToNodeName(HolsterType type)

    {

        switch (type)

        {

        case HolsterType::Pistol:

            return "PistolHolster";

        case HolsterType::Rifle:

            return "RifleHolster";

        case HolsterType::Shotgun:

            return "ShotgunHolster";

        case HolsterType::Knife:

            return "KnifeHolster";

        default:

            return "";

        }

    }

}

_________________________

PapyrusFunctions.cpp

_________________________

#include "PapyrusFunctions.h"

#include "VisibleHolster.h"

#include "f4se/PapyrusNativeFunctions.h"

 

namespace PapyrusFunctions

{

    bool RegisterFunctions(VMClassRegistry* registry)

    {

        registry->RegisterFunction(

            new NativeFunction5<StaticFunctionTag, void, SInt32, float, float, float, SInt32>(

                "UpsertWeaponPosition", "ClassicHolsteredWeaponsSystem", UpsertWeaponPosition, registry

            )

        );

 

        registry->RegisterFunction(

            new NativeFunction1<StaticFunctionTag, void, SInt32>(

                "ResetAllWeaponPositions", "ClassicHolsteredWeaponsSystem", ResetAllWeaponPositions, registry

            )

        );

 

        return true;

    }

 

    void UpsertWeaponPosition(StaticFunctionTag*, SInt32 holsterType, float posX, float posY, float posZ, SInt32 rotationMode)

    {

        using namespace VisibleHolster;

        auto type = static_cast<HolsterType>(holsterType);

        float eulerAttitude = 0.0f, eulerBank = 0.0f, eulerHeading = 0.0f;

 

        if (rotationMode == 1) {

            eulerAttitude = 0.5f; // Adjust as needed for different rotation types

        } else if (rotationMode == 2) {

            eulerBank = 0.5f;

        } else if (rotationMode == 3) {

            eulerHeading = 0.5f;

        }

 

        UpsertWeaponPosition(type, posX, posY, posZ, eulerAttitude, eulerBank, eulerHeading);

    }

 

    void ResetAllWeaponPositions(StaticFunctionTag*)

    {

        auto rootNode = (*g_player)->GetActorRootNode(false)->GetAsNiNode();

        VisibleHolster::ResetAllWeaponPos(rootNode);

    }

}

_________________________

Positioner.cpp

_________________________

#include "Positioner.h"

#include "VisibleHolster.h"

#include "f4se/GameReferences.h"

#include "f4se/NiNodes.h"

#include <cmath>

 

namespace Positioner

{

    void PositionWeapon(NiNode* rootNode, VisibleHolster::WeaponPosition& position)

    {

        if (!rootNode) return;

 

        NiNode* weaponNode = rootNode->GetObjectByName(VisibleHolster::WeaponPosition::typeToNodeName(position.type));

        if (!weaponNode) return;

 

        weaponNode->m_localTransform.pos.x = position.posX;

        weaponNode->m_localTransform.pos.y = position.posY;

        weaponNode->m_localTransform.pos.z = position.posZ;

        weaponNode->m_localTransform.rot.SetEuler(position.eulerAttitude, position.eulerBank, position.eulerHeading);

        weaponNode->UpdateWorldData(0.0f);

    }

 

    void ApplyWeaponPositionsToPlayer()

    {

        NiNode* rootNode = (*g_player)->GetActorRootNode(false)->GetAsNiNode();

        if (!rootNode) return;

 

        for (auto& position : VisibleHolster::GetAttachPosVec())

        {

            if (position.type != HolsterType::NotSet)

            {

                PositionWeapon(rootNode, position);

            }

        }

    }

 

    void AdjustWeaponPosition(VisibleHolster::WeaponPosition& position, float deltaX, float deltaY, float deltaZ, float deltaAttitude, float deltaBank, float deltaHeading)

    {

        position.posX += deltaX;

        position.posY += deltaY;

        position.posZ += deltaZ;

        position.eulerAttitude += deltaAttitude;

        position.eulerBank += deltaBank;

        position.eulerHeading += deltaHeading;

    }

}

_________________________

AttachHandler.cpp

_________________________

#include "AttachHandler.h"

#include "VisibleHolster.h"

#include "f4se/GameReferences.h"

#include "f4se/NiNodes.h"

 

namespace AttachHandler

{

    bool AttachWeaponToHolster(NiNode* rootNode, VisibleHolster::WeaponPosition& position)

    {

        if (!rootNode) return false;

 

        NiNode* weaponNode = rootNode->GetObjectByName(VisibleHolster::WeaponPosition::typeToNodeName(position.type));

        if (!weaponNode) return false;

 

        weaponNode->m_localTransform.pos.x = position.posX;

        weaponNode->m_localTransform.pos.y = position.posY;

        weaponNode->m_localTransform.pos.z = position.posZ;

        weaponNode->m_localTransform.rot.SetEuler(position.eulerAttitude, position.eulerBank, position.eulerHeading);

        weaponNode->UpdateWorldData(0.0f);

 

        return true;

    }

 

    bool DetachWeaponFromHolster(NiNode* rootNode, HolsterType type)

    {

        if (!rootNode) return false;

 

        NiNode* weaponNode = rootNode->GetObjectByName(VisibleHolster::WeaponPosition::typeToNodeName(type));

        if (!weaponNode) return false;

 

        // Reset weapon position (e.g., hide or reset to default)

        weaponNode->m_localTransform.pos = NiPoint3(0.0f, 0.0f, 0.0f);

        weaponNode->m_localTransform.rot.SetEuler(0.0f, 0.0f, 0.0f);

        weaponNode->UpdateWorldData(0.0f);

 

        return true;

    }

 

    void ProcessWeaponAttachment(HolsterType type, bool attach, float posX, float posY, float posZ, float eulerAttitude, float eulerBank, float eulerHeading)

    {

        NiNode* rootNode = (*g_player)->GetActorRootNode(false)->GetAsNiNode();

        if (!rootNode) return;

 

        VisibleHolster::WeaponPosition position = { type, posX, posY, posZ, eulerAttitude, eulerBank, eulerHeading };

 

        if (attach)

        {

            AttachWeaponToHolster(rootNode, position);

        }

        else

        {

            DetachWeaponFromHolster(rootNode, type);

        }

    }

}

_________________________

ScaleformF4NV.cpp

_________________________

#include "ScaleformF4NV.h"

#include "VisibleHolster.h"

#include "f4se/ScaleformCallbacks.h"

#include "f4se/ScaleformMovie.h"

#include "f4se/ScaleformValue.h"

 

namespace ScaleformF4NV

{

    bool GetHolsterPosition(GFxMovieView* view, GFxValue* result, VisibleHolster::WeaponPosition position)

    {

        if (!view || !result) return false;

 

        GFxValue posX, posY, posZ;

        posX.SetNumber(position.posX);

        posY.SetNumber(position.posY);

        posZ.SetNumber(position.posZ);

 

        result->SetMember("posX", &posX);

        result->SetMember("posY", &posY);

        result->SetMember("posZ", &posZ);

 

        GFxValue eulerAttitude, eulerBank, eulerHeading;

        eulerAttitude.SetNumber(position.eulerAttitude);

        eulerBank.SetNumber(position.eulerBank);

        eulerHeading.SetNumber(position.eulerHeading);

 

        result->SetMember("eulerAttitude", &eulerAttitude);

        result->SetMember("eulerBank", &eulerBank);

        result->SetMember("eulerHeading", &eulerHeading);

 

        return true;

    }

 

    void RegisterScaleform(GFxMovieView* view, GFxValue* f4nvObj)

    {

        GFxValue holsterPositions;

        view->CreateObject(&holsterPositions);

 

        for (const auto& position : VisibleHolster::GetAttachPosVec())

        {

            GFxValue holsterData;

            view->CreateObject(&holsterData);

 

            if (GetHolsterPosition(view, &holsterData, position))

            {

                holsterPositions.SetMember(VisibleHolster::WeaponPosition::typeToNodeName(position.type), &holsterData);

            }

        }

 

        f4nvObj->SetMember("holsterPositions", &holsterPositions);

    }

 

    bool RegisterScaleformFunctions(GFxMovieView* view, GFxValue* f4nvObj)

    {

        if (!view || !f4nvObj) return false;

 

        RegisterScaleform(view, f4nvObj);

        return true;

    }

}

_________________________

 

  • Thanks 1
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...