Beef
Beef
SMSatisfactory Modding
Created by Beef on 11/15/2024 in #help-developing-mods
Moving Meshes at Runtime
Moving this here as it's still a blocker for me and I guess it's more complicated as the more general UE modding server suggested coming back here to ask again - Do you have to change anything else meshes to update? E.g. setting visibility off and on again, or disabling/re-enabling collision? When updating node location, such as using
ResourceNode->SetActorLocation(NodeData.Location);
ResourceNode->SetActorRotation(NodeData.Rotation);
MeshComponent->SetWorldLocation(NodeData.Location);
MeshComponent->SetWorldRotation(NodeData.Rotation);
ResourceNode->SetActorLocation(NodeData.Location);
ResourceNode->SetActorRotation(NodeData.Rotation);
MeshComponent->SetWorldLocation(NodeData.Location);
MeshComponent->SetWorldRotation(NodeData.Rotation);
I notice that setting this location/rotation for both works if its during their spawn, but it doesn't appear to update their location once they've already been spawned. I'm also not entirely sure if I have to update the MeshComponent separately from the Actor or not, since the mesh is attached to the actor when I spawn them using
ResourceNode->SetRootComponent(MeshComponent);
MeshComponent->RegisterComponent();
ResourceNode->SetRootComponent(MeshComponent);
MeshComponent->RegisterComponent();
tried again with
ResourceNode->SetActorLocation(NodeData.Location, false, nullptr, ETeleportType::TeleportPhysics);
ResourceNode->SetActorRotation(NodeData.Rotation, ETeleportType::TeleportPhysics);
MeshComponent->SetWorldLocation(NodeData.Location, false, nullptr, ETeleportType::TeleportPhysics);
MeshComponent->SetWorldRotation(NodeData.Rotation, false, nullptr, ETeleportType::TeleportPhysics);
ResourceNode->SetActorLocation(NodeData.Location, false, nullptr, ETeleportType::TeleportPhysics);
ResourceNode->SetActorRotation(NodeData.Rotation, ETeleportType::TeleportPhysics);
MeshComponent->SetWorldLocation(NodeData.Location, false, nullptr, ETeleportType::TeleportPhysics);
MeshComponent->SetWorldRotation(NodeData.Rotation, false, nullptr, ETeleportType::TeleportPhysics);
the method is being called and is updating these appropriately, and the mesh is moveable (also as an aside, weird how AActor::SetActorRotation is missing the fields the other methods have ... (https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Engine/GameFramework/AActor/SetActorRotation/1) I can't find anything in UE documentation or forum/reddit/etc that seems to deal with this
23 replies
SMSatisfactory Modding
Created by Beef on 11/14/2024 in #help-developing-mods
Randomization Logic
I'm trying to lay down good logic for randomization that makes sense, and wonder if I've made some oversights in my planning. I know there are efficiency optimizations that can be done, but wrapping my head around this one by itself has already bent my brains into a pretzel so that will come later. Variables:
NotProcessedResourceNodes (sorted by class and then by purity from pure->impure)
NotProcessedPossibleLocations (this is already in pseudorandom order based on seed)

NotProcessedSingleResourceNodes
NotProcessedSinglePossibleLocations
NotProcessedResourceNodes (sorted by class and then by purity from pure->impure)
NotProcessedPossibleLocations (this is already in pseudorandom order based on seed)

NotProcessedSingleResourceNodes
NotProcessedSinglePossibleLocations
Processing Logic
- While there are still nodes in NotProcessedResourceNodes (starting with the last one and working towards first one)
- Check to ensure we still have NotProcessedResourceNodes and we still have NotProcessedPossibleLocations available, otherwise break out of the loop
- If it's one of the non-groupable classes, add it to NotProcessedSingleResourceNodes and remove from NotProcessedResourceNodes.
- Otherwise, grab the last index of NotProcessedPossibleLocations
- Feed this possible location and the current list of all Possible locations into LocationGrouper, and recursively check what other NotProcessedPossibleLocations are within GroupingRadius. We use recursion to ensure we will get multiple resources that are all in a row or otherwise very close but are not all within the radius of the starting NotProcessedPossibleLocations.
- Return the list (and the list of their corresponding indexes in NotProcessedPossibleLocations) for each location within the group.
- If we have only 1 location in the group, then we use a Counter % 4 != 0 that's initialized at the start to give it a deterministic 25% chance of being used. If it fails (75% chance), then we insert the location to the NotProcessedSinglePossibleLocations and remove it from NotProcessedPossibleLocations.
- While there are still nodes in NotProcessedResourceNodes (starting with the last one and working towards first one)
- Check to ensure we still have NotProcessedResourceNodes and we still have NotProcessedPossibleLocations available, otherwise break out of the loop
- If it's one of the non-groupable classes, add it to NotProcessedSingleResourceNodes and remove from NotProcessedResourceNodes.
- Otherwise, grab the last index of NotProcessedPossibleLocations
- Feed this possible location and the current list of all Possible locations into LocationGrouper, and recursively check what other NotProcessedPossibleLocations are within GroupingRadius. We use recursion to ensure we will get multiple resources that are all in a row or otherwise very close but are not all within the radius of the starting NotProcessedPossibleLocations.
- Return the list (and the list of their corresponding indexes in NotProcessedPossibleLocations) for each location within the group.
- If we have only 1 location in the group, then we use a Counter % 4 != 0 that's initialized at the start to give it a deterministic 25% chance of being used. If it fails (75% chance), then we insert the location to the NotProcessedSinglePossibleLocations and remove it from NotProcessedPossibleLocations.
12 replies
SMSatisfactory Modding
Created by Beef on 11/13/2024 in #help-developing-mods
Struct not serializing to savefile
No description
8 replies
SMSatisfactory Modding
Created by Beef on 11/8/2024 in #modding-resources
StreamDeck Actions for Devs
No description
21 replies
SMSatisfactory Modding
Created by Beef on 11/8/2024 in #modding-resources
ModLog Logging Library
I put together a somewhat dirty logging library that allows you to write clean logs to external files. It's got both blueprint and C++ callable methods. https://github.com/TheRealBeef/Satisfactory-ModLog-Lib It could certainly use some improvements but may be handy
1 replies
SMSatisfactory Modding
Created by Beef on 11/5/2024 in #modding-resources
Resource Types (Vanilla and Modded)
These are what you find when iterating and dumping AFGResourceNode. Could be handy for making custom spawners/despawners or randomizing node locations etc Vanilla Resource types:
Gas - EResourceForm::RF_GAS:
Desc_NitrogenGas_C

Heat - EResourceForm::RF_HEAT:
Desc_Geyser_C

Liquid - EResourceForm::RF_LIQUID:
Desc_LiquidOil_C
Desc_Water_C

Solid - EResourceForm::RF_SOLID:
Desc_SAM_C
Desc_Stone_C
Desc_OreIron_C
Desc_OreCopper_C
Desc_OreGold_C
Desc_Coal_C
Desc_RawQuartz_C
Desc_Sulfur_C
Desc_OreBauxite_C
Desc_OreUranium_C
Gas - EResourceForm::RF_GAS:
Desc_NitrogenGas_C

Heat - EResourceForm::RF_HEAT:
Desc_Geyser_C

Liquid - EResourceForm::RF_LIQUID:
Desc_LiquidOil_C
Desc_Water_C

Solid - EResourceForm::RF_SOLID:
Desc_SAM_C
Desc_Stone_C
Desc_OreIron_C
Desc_OreCopper_C
Desc_OreGold_C
Desc_Coal_C
Desc_RawQuartz_C
Desc_Sulfur_C
Desc_OreBauxite_C
Desc_OreUranium_C
Modded (Currently only FF and RP - please let me know of other ones and I'll add to list. OFC these are subject to change more frequently than vanilla))
-- Ficsit Farming --
Solid - EResourceForm::RF_SOLID:
Desc_FF_Dirt_Fertilized_C
Desc_FF_Dirt_C
Desc_FF_Dirt_Wet_C

-- Refined Power --
Liquid - EResourceForm::RF_LIQUID:
Desc_RP_Deanium_C

Solid - EResourceForm::RF_SOLID:
Desc_RP_WaterDamNode_C
Desc_WaterTurbineNode_C
Desc_RP_Thorium_C
-- Ficsit Farming --
Solid - EResourceForm::RF_SOLID:
Desc_FF_Dirt_Fertilized_C
Desc_FF_Dirt_C
Desc_FF_Dirt_Wet_C

-- Refined Power --
Liquid - EResourceForm::RF_LIQUID:
Desc_RP_Deanium_C

Solid - EResourceForm::RF_SOLID:
Desc_RP_WaterDamNode_C
Desc_WaterTurbineNode_C
Desc_RP_Thorium_C
1 replies
SMSatisfactory Modding
Created by Beef on 11/4/2024 in #help-using-mods
Resource Node Randomizer conflicts with Ficsit Farming
Portable miners and miners disappear on (Ficsit Farming) dirt nodes. I believe this is a mod conflict with Resource Node Randomizer. @Marshall I believe I have a fix and will submit a PR to your Github if it works...
6 replies
SMSatisfactory Modding
Created by Beef on 11/3/2024 in #help-using-mods
Heavy Fluid Overhaul - RP/FF compatibility
Any interest in adding compatibility with Refined Power/Ficsit Farming? It may be outside your scope of work, but it appears that Heavy Fluid Overhaul has no effect on these mods (to not much surprise). Since RP/FF are closed source it's perhaps not feasible either.
8 replies
SMSatisfactory Modding
Created by Beef on 10/23/2024 in #help-developing-mods
Access Violations
I started using SUBSCRIBE_UOBJECT_METHOD() as per Mircea/Rex advice, but I still get an access violation. Starting a test world with nothing in it / no other mods besides SML, everything works OK until I place a sign. The build animation plays and then there's about 1 frame where the sign tries to display something and then the game crashes.
#include "MoreLightingOptionsModule.h"
#include "Buildables/FGBuildableWidgetSign.h"
#include "Patching/NativeHookManager.h"

class HFGBuildableWidgetSign
{
public:
static void Hook_GetAdjustedEmissiveValue(TCallScope<float(__cdecl*)(const AFGBuildableWidgetSign*, int32)>& scope, const AFGBuildableWidgetSign* self, int32 Level)
{
if (!self) {
return;
}

float BaseEmissiveValue = scope(self, Level);
float NewEmissiveValue = BaseEmissiveValue * 10.0f;
if (NewEmissiveValue >= 0.0f) {
scope.Override(NewEmissiveValue);
}
}

static void RegisterHooks()
{
SUBSCRIBE_UOBJECT_METHOD(AFGBuildableWidgetSign, GetAdjustedEmissiveValue, &HFGBuildableWidgetSign::Hook_GetAdjustedEmissiveValue);
}
};

// Startup Module for MoreLightingOptions
void FMoreLightingOptionsModule::StartupModule()
{
if (!WITH_EDITOR)
{
HFGBuildableWidgetSign::RegisterHooks();
}
}

void FMoreLightingOptionsModule::ShutdownModule()
{
}

IMPLEMENT_GAME_MODULE(FMoreLightingOptionsModule, MoreLightingOptions);
#include "MoreLightingOptionsModule.h"
#include "Buildables/FGBuildableWidgetSign.h"
#include "Patching/NativeHookManager.h"

class HFGBuildableWidgetSign
{
public:
static void Hook_GetAdjustedEmissiveValue(TCallScope<float(__cdecl*)(const AFGBuildableWidgetSign*, int32)>& scope, const AFGBuildableWidgetSign* self, int32 Level)
{
if (!self) {
return;
}

float BaseEmissiveValue = scope(self, Level);
float NewEmissiveValue = BaseEmissiveValue * 10.0f;
if (NewEmissiveValue >= 0.0f) {
scope.Override(NewEmissiveValue);
}
}

static void RegisterHooks()
{
SUBSCRIBE_UOBJECT_METHOD(AFGBuildableWidgetSign, GetAdjustedEmissiveValue, &HFGBuildableWidgetSign::Hook_GetAdjustedEmissiveValue);
}
};

// Startup Module for MoreLightingOptions
void FMoreLightingOptionsModule::StartupModule()
{
if (!WITH_EDITOR)
{
HFGBuildableWidgetSign::RegisterHooks();
}
}

void FMoreLightingOptionsModule::ShutdownModule()
{
}

IMPLEMENT_GAME_MODULE(FMoreLightingOptionsModule, MoreLightingOptions);
38 replies
SMSatisfactory Modding
Created by Beef on 10/20/2024 in #help-using-mods
SifVerT - Difficulty Tuner
There's an option to enable "Machine Parts" if you disable the crafting table, which is kind, but it also adds several milestones to research to unlock the assembler/manufacturer/etc that can be built with machine parts. However, with machine parts disabled, the milestones to unlock these machines still appear. I'm not sure if this is intended behavior or not.
7 replies
SMSatisfactory Modding
Created by Beef on 10/14/2024 in #help-using-mods
Harder Phases 10x Multiplication Bug
No description
15 replies