int alliance_id;
AShooterPlayerState* State = static_cast<AShooterPlayerState*>(shooter_pc->PlayerStateField());
FTribeAlliance* FTA = static_cast <FTribeAlliance*>(State->MyTribeDataField()->FindTribeAlliance(alliance_id));
shooter_pc
in that case? (edited)Log::GetLog()->info("tribemembersInviter: {}", alliance.MembersTribeIDField().Num());
returns me this: -623357952
and cuz its negative it doesnt go into the next stepServerRequestRemoveAllianceMember_Implementation
TArray<FTribeAlliance> allys = aPlState->MyTribeDataField()->TribeAlliancesField();
if (allys.Num() > 0) {
m_AllianceID = allys[0].AllianceIDField();
}
that's how i get it now which is the wrong one -.-MembersTribeIDField()
(edited) AShooterPlayerState* state = static_cast<AShooterPlayerState*>(shooter_pc->PlayerStateField());
if (state)
{
FTribeData* mytribedata = state->MyTribeDataField();
int mytribe_id = state->TargetingTeamField();
Log::GetLog()->info("Checking For Tribe ID: {}", mytribe_id);
int tribeMemberCount = mytribedata->MembersPlayerDataIDField().Num();
Log::GetLog()->info("My Member Count: {}", tribeMemberCount); // will return the count of players in your tribe
if (tribeMemberCount > 0)
{
int alliancesCount = mytribedata->TribeAlliancesField().Num();
Log::GetLog()->info("My Alliance Count: {}", alliancesCount); // Will return the count of how many alliances you have
int allyMemberCount = state->MyTribeDataField()->TribeAlliancesField().GetData()->MembersTribeIDField().Num();
Log::GetLog()->info("My Alliance Member Count: {}", allyMemberCount); // Will return the count of you and the members of the alliance
(edited)struct FUniqueNetIdUInt64 : FUniqueNetId
{
unsigned __int64 UniqueNetId;
};
void outPos(AShooterPlayerController* spc, FString* cmd, bool /**/)
{
if (spc) {
FVector pos = spc->DefaultActorLocationField();
FString aaa = pos.ToString();
Log::GetLog()->info("Player position ({})", pos.ToString());
}
}
When the player type /outPos it should output to the screen, but my knowledge of c++ is limited and I cant figure out how to get the FString to the Log::GetLog()->info function. I keep getting the error โCannot format argument. To enable the use of ostream operator<< include fmt/ostream.h. Otherwise provide an overload of format_arg.โ
Any tips on how to proceed, is greatly appreciatedFVector Location = player->GetPlayerCharacter()->RootComponentField()->RelativeLocationField();
FMath::Abs((vector1 - vector2).Size())
FVector::Distance(location1, location2)
to get the distance (edited)if (primal_character)
(edited) if (primal_character != nullptr)
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\include\xtree(1458): message : see reference to function template instantiation 'std::_Tree_find_result<std::_Tree_node<std::pair<const StringType,nlohmann::basic_json<std::map,std::vector,StringType,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>,std::_Default_allocator_traits<_Alloc>::void_pointer> *> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Find_lower_bound<_Other>(const _Keyty &) const' being compiled
1> with
1> [
1> StringType=std::string,
1> _Alloc=std::allocator<std::pair<const std::string,nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>>>,
1> _Kty=std::string,
1> _Ty=nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>,
1> _Pr=nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::object_comparator_t,
1> _Other=SIZE_T,
1> _Keyty=SIZE_T
1> ]
When saving from a json variable to an ofstream file ?/mtape start
/mtape stop
(edited)COMMANDS.AddConsoleCommand("mtape", ChatCommand);
(edited)ArkApi::GetCommands()
void GivePlayerStat(AShooterCharacter* Char, EPrimalCharacterStatusValue::Type Stat, float AmountToGive)
{
if (Char && Char->MyCharacterStatusComponentField() && AmountToGive > 0)
{
UPrimalCharacterStatusComponent* Comp = Char->MyCharacterStatusComponentField();
float CurrentStat = Comp->BPGetCurrentStatusValue(Stat);
float MaxStat = Comp->BPGetMaxStatusValue(Stat);
float NewStat;
if (CurrentStat + AmountToGive >= MaxStat)
NewStat = MaxStat;
else
NewStat = CurrentStat + AmountToGive;
Comp->BPDirectSetCurrentStatusValue(Stat, NewStat);
Comp->ServerSyncReplicatedValues();
}
}
if (ArkApi::GetApiUtils().GetStatus() == ArkApi::ServerStatus::Ready)
Log::GetLog()
does will be in the API logs.#pragma comment(lib, "Permissions.lib")
1>Suicide.cpp
1>C:\******\ARK-Server-API-master\version\Core\Public\API\UE\Templates\Tuple.h(409,121): error C2760: syntax error: unexpected token ')', expected 'expression'
1>C:\******\ARK-Server-API-master\version\Core\Public\API\UE\Templates\Tuple.h(455): message : see reference to class template instantiation 'UE4Tuple_Private::TTupleImpl<TIntegerSequence<uint32,Indices...>,Types...>' being compiled
1>C:\******\ARK-Server-API-master\version\Core\Public\API\UE\Templates\Tuple.h(419,94): error C2760: syntax error: unexpected token ')', expected 'expression'
1>Done building project "Suicide.vcxproj" -- FAILED.
Tuple.h
//#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
// #define USE_TUPLE_AUTO_RETURN_TYPES (PLATFORM_COMPILER_HAS_AUTO_RETURN_TYPES && USING_CODE_ANALYSIS)
//#else
#define USE_TUPLE_AUTO_RETURN_TYPES 1
//#endif
c++
void Hook_AShooterGameMode_RemovePlayerFromTribe(AShooterGameMode* _this, unsigned __int64 TribeID, unsigned __int64 PlayerDataID, bool bDontUpdatePlayerState)
{
bool bCanNeverLeaveTribe = config["General"].value("LifetimeTribeMembership", false);
if (bCanNeverLeaveTribe) {
Log::GetLog()->info("CannotRemovePlayerFromTribe");
return;
}
AShooterGameMode_RemovePlayerFromTribe_original(_this, TribeID, PlayerDataID, bDontUpdatePlayerState);
}
void Hook_AShooterPlayerState_ServerRequestLeaveTribe_Implementation(AShooterPlayerState* _this)
{
AShooterPlayerState_ServerRequestLeaveTribe_Implementation_original(_this);
}
void Hook_AShooterPlayerState_ServerRequestLeaveTribe_Implementation(AShooterPlayerState* _this)
{
AShooterPlayerState_ServerRequestLeaveTribe_Implementation_original(_this);
}
void Hook_AShooterPlayerState_ServerRequestLeaveTribe_Implementation(AShooterPlayerState* _this)
{
return;
}
szitem["Word"]
to std::stringFTribeData* CreatedTribeData = static_cast<FTribeData*>(FMemory::Malloc(0x200));
RtlSecureZeroMemory(CreatedTribeData, 0x200);
ArkApi::GetApiUtils().GetShooterGameMode()->GetOrLoadTribeData(CreatedTribeID, CreatedTribeData);
FMemory::Free(CreatedTribeData);
c++
bool Hook_APrimalDinoCharacter_Die(APrimalDinoCharacter* _this, float KillingDamage, FDamageEvent* DamageEvent, AController* Killer, AActor* DamageCauser)
{
return APrimalDinoCharacter_Die_original(_this, KillingDamage, DamageEvent, Killer, DamageCauser);
}
thank you in advancec++
FString myDescriptiveName = _this->DescriptiveNameField();
(edited)
uint64 playerTribeId = player->TargetingTeamField();
const int dinoTribeId = dino->TargetingTeamField();
if (playerTribeId != dinoTribeId) <--- this line is crashing
return;
void Imprint(AShooterPlayerController* player, FString* message, EChatSendMode::Type /*unused*/)
{
if (!player || !player->PlayerStateField() || ArkApi::IApiUtils::IsPlayerDead(player))
return;
const uint64 steamid = ArkApi::IApiUtils::GetSteamIdFromController(player);
uint64 playerTribeId = player->TargetingTeamField();
AActor* Actor = player->GetPlayerCharacter()->GetAimedActor(ECC_GameTraceChannel2, nullptr, 0.0, 0.0, nullptr, nullptr, false, false, false);
if (Actor && Actor->IsA(APrimalDinoCharacter::GetPrivateStaticClass()) == false) {
ArkApi::GetApiUtils().SendChatMessage(player, GetText("Sender"), *GetText("Invalid"));
return;
}
APrimalDinoCharacter* dino = static_cast<APrimalDinoCharacter*>(Actor);
const int dinoTribeId = dino->TargetingTeamField();
if (playerTribeId != dinoTribeId) {
ArkApi::GetApiUtils().SendChatMessage(player, GetText("Sender"), *GetText("NotInTribe"));
return;
}
....
}
(edited)DECLARE_HOOK(AShooterPlayerController_OnAddItemFinished, void, AShooterCharacter*, bool, TArray<unsigned __int64>, unsigned __int64);
void Hook_AShooterPlayerController_OnAddItemFinished(AShooterCharacter* _this, bool bSuccess, TArray<unsigned __int64> SteamItemUserIds, unsigned __int64 SteamID)
{
const FLinearColor color{ 255, 255, 255, 255 };
ArkApi::GetApiUtils().SendServerMessageToAll(color, "[TEST]Player added item!");
}
(edited) ArkApi::GetHooks().SetHook("AShooterPlayerController.OnAddItemFinished", &Hook_AShooterPlayerController_OnAddItemFinished, &AShooterPlayerController_OnAddItemFinished_original);
void CC_RunString(APlayerController* player_controller, FString* cmd, bool /*unused*/)
{
ArkApi::GetApiUtils().SendServerMessageToAll(FColorList::Blue, "Testing!");
if (cmd != nullptr && cmd->Len() > 0)
luaL_dostring(CGELuaHandle::GetSingleton()->GetState(), cmd->ToString().c_str());
}
void RegisterLuaConCommands()
{
auto& commands = ArkApi::GetCommands();
commands.AddConsoleCommand("lua_run", &CC_RunString);
}
cheat lua_run
? (edited)c++
// A
typedef unordered_map<string, int> Sub; // possibly 30+ entries
typedef unordered_map<string, Sub> Main; // possibly 30 or fewer
// B
typedef vector<tuple<string, int>> Sub; // possibly 30+ entries
typedef unordered_map<string, Sub> Main; // possibly 30 or fewer
(edited)// m_pInstance is AShooterCharacter*
auto ctrl = m_pInstance->GetCharacterController();
auto shooter_ctrl = static_cast<AShooterPlayerController*>(ctrl);
shooter_ctrl->AddExperience(100, false, false);
AShooterPlayerController* aspc = ArkApi::GetApiUtils().FindControllerFromCharacter(character);
(edited)AShooterPlayerController* aspc = ArkApi::GetApiUtils().FindControllerFromCharacter(character);
(edited) AShooterPlayerController* FindControllerFromCharacter(AShooterCharacter* character) const
{
AShooterPlayerController* result = nullptr;
const auto& player_controllers = GetWorld()->PlayerControllerListField();
for (TWeakObjectPtr<APlayerController> player_controller : player_controllers)
{
auto* shooter_pc = static_cast<AShooterPlayerController*>(player_controller.Get());
if (shooter_pc->GetPlayerCharacter() == character)
{
result = shooter_pc;
break;
}
}
return result;
}
while that field should always have the player controllerFindControllerFromCharacter
to use the field if the field is non-nullFindControllerFromCharacter
has null checks but GetSteamName
does not for exampleAShooterPlayerController* FindControllerFromCharacter(AShooterCharacter* character) const
{
if (character)
{
AShooterPlayerController* result = (character->GetOwnerController() != nullptr) ?
static_cast<AShooterPlayerController*>(character->GetOwnerController())
:
static_cast<AShooterPlayerController*>(character->GetInstigatorController());
return result;
}
return nullptr;
}
GetOwnerController
GetOwnerController
compress2
error is fixed with DumpAll i'm pretty sure which is why we need to just release the API with it enabled. I have been providing it that way in my early releases on my discord.compress2
error is fixed with DumpAll i'm pretty sure which is why we need to just release the API with it enabled. I have been providing it that way in my early releases on my discord. compress2
error is fixed with DumpAll i'm pretty sure which is why we need to just release the API with it enabled. I have been providing it that way in my early releases on my discord. typedef std::tuple<const char*, int> CCEntry_t;
typedef std::unique_ptr<CCEntry_t> CCEntryptr_t;
typedef std::vector<CCEntryptr_t> CCVec_t; // contains the console commands along with their luareg index
(edited)auto Singleton = (UPrimalGlobals*)Globals::GEngine()()->GameSingletonField();
auto GameData = Singleton->PrimalGameDataOverrideField() ? Singleton->PrimalGameDataOverrideField() : Singleton->PrimalGameDataField();
auto EngramClasses = GameData->EngramBlueprintEntriesField();
(edited)auto Singleton = (UPrimalGlobals*)Globals::GEngine()()->GameSingletonField();
auto GameData = Singleton->PrimalGameDataOverrideField() ? Singleton->PrimalGameDataOverrideField() : Singleton->PrimalGameDataField();
auto EngramClasses = GameData->EngramBlueprintEntriesField();
for (auto x : EngramClasses)
{
auto sub = x->BluePrintEntryField().uClass->GetDefaultObject();
auto casted = static_cast<UPrimalItem*>(sub);
float damage = casted->GetWeaponTemplateMeleeDamageAmount();
}
struct EngramEntry
{
FString name;
TSubclassOf<UPrimalItem>* engram;
int level{};
};
extern TMap<FString, EngramEntry> g_EngramMap;
TMap<FString, FString, FDefaultSetAllocator, TDefaultMapKeyFuncs<FString, FString, 0> >
struct FMyStruct
{
// String which identifies our key
FString UniqueID;
// Some state which doesn't affect struct identity
float SomeFloat;
explicit FMyStruct(float InFloat)
:UniqueID (FGuid::NewGuid().ToString())
, SomeFloat(InFloat)
{
}
};
template <typename ValueType>
struct TMyStructMapKeyFuncs :
BaseKeyFuncs<
TPair<FMyStruct, ValueType>,
FString
>
{
private:
typedef BaseKeyFuncs<
TPair<FMyStruct, ValueType>,
FString
> Super;
public:
typedef typename Super::ElementInitType ElementInitType;
typedef typename Super::KeyInitType KeyInitType;
static KeyInitType GetSetKey(ElementInitType Element)
{
return Element.Key.UniqueID;
}
static bool Matches(KeyInitType A, KeyInitType B)
{
return A.Compare(B, ESearchCase::CaseSensitive) == 0;
}
static uint32 GetKeyHash(KeyInitType Key)
{
return FCrc::StrCrc32(*Key);
}
};
struct FStringStruct
{
// String which identifies our key
FString UniqueID;
// Some state which doesn't affect struct identity
float SomeFloat;
explicit FStringStruct(float InFloat)
:UniqueID(FGuid::NewGuid().ToString())
, SomeFloat(InFloat)
{
}
};
struct MyStruct
{
FString a;
void* whateveryouwant;
}
map<std::string, MyStruct> myMap
//#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
// #define USE_TUPLE_AUTO_RETURN_TYPES (PLATFORM_COMPILER_HAS_AUTO_RETURN_TYPES && USING_CODE_ANALYSIS)
//#else
#define USE_TUPLE_AUTO_RETURN_TYPES 1
//#endif
(edited)#define TUPLES_USE_DEFAULTED_FUNCTIONS 1
?version\Core\Public\API\UE\Containers\../Windows/MicrosoftPlatformString.h(24): error C2664: 'errno_t strcpy_s(char *,rsize_t,const char *)': cannot convert argument 1 from 'WIDECHAR *' to 'char *'
version\Core\Public\API\UE\Containers\../Windows/MicrosoftPlatformString.h(24): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt\string.h(32): note: see declaration of 'strcpy_s'
It seems UE/BasicTypes is including headers that, at least on my system, contradicts each other. Has anyone encountered this before?item->DescriptiveNameBaseField() = "Trophy";
item->UpdatedItem(false);
Log::GetLog()->warn(item->DescriptiveNameBaseField().ToString());
AttackerShooterController->GetPlayerInventory()->AddItemObject(item);
This gives the actual item i want to, the log shows the name ive given it but the client doesnt see itactor->MulticastProperty(FName(L"varNameWithoutField", EFindName::FName_Add, false));
item->OwnerInventoryField()->RemoveItem(&item->ItemIDField(), false, false, true, true);
item->OwnerInventoryField()->IncrementItemTemplateQuantity(item->ClassField(), -1, true, false, nullptr, nullptr, false, false, false, false, true, false, true);
item->OwnerInventoryField()->RemoveItem(&item->ItemIDField(), false, false, true, true);
FCustomItemData cdata;
cdata.CustomDataName = FName("Alpha Trophy1", EFindName::FNAME_Add);
alphatrophyitem->CustomItemNameField() = L"Alpha Trophy";
alphatrophyitem->SetCustomItemData(&cdata);
alphatrophyitem->UpdatedItem(false);
static_cast<APrimalStructureItemContainer*>(Stand)->MyInventoryComponentField()->AddItemObject(alphatrophyitem);
c++
DECLARE_HOOK(UPrimalItem_BeginDestroy, void, UPrimalItem*);
void Hook_UPrimalItem_BeginDestroy(UPrimalItem* _this)
{
UPrimalItem_BeginDestroy_original(_this);
}
ArkApi::GetHooks().SetHook("UPrimalItem.BeginDestroy", &Hook_UPrimalItem_BeginDestroy, &UPrimalItem_BeginDestroy_original);
ArkApi::GetHooks().DisableHook("UPrimalItem.BeginDestroy", &Hook_UPrimalItem_BeginDestroy);
(edited)TWeakObjectPtr<UPrimalItem> item_ptr = GetWeakReference(item);
item_ptr.Get()
if (item_ptr.Get() != nullptr)
inline AActor* BPSpawnActor(UWorld* uworld, FString blueprint, FVector* location, FRotator* rotation, bool do_begin_play)
{
//auto* world = ArkApi::GetApiUtils().GetWorld();
if (!uworld) {
return nullptr;
}
UClass* object_class = UVictoryCore::BPLoadClass(&blueprint);
if (!object_class) {
return nullptr;
}
FActorSpawnParameters new_actor_spawn_params;
new_actor_spawn_params.bDeferBeginPlay = true;
auto* actor = uworld->SpawnActor(object_class, location, rotation, &new_actor_spawn_params);
if (actor) {
if (do_begin_play) {
actor->BeginPlay();
actor->ForceReplicateNow(false, false);
}
return actor;
}
return nullptr;
}
auto* world = ArkApi::GetApiUtils().GetWorld();
auto character = player_controller->GetPlayerCharacter();
auto location = character->RootComponentField()->RelativeLocationField();
FString blueprint = "Blueprint'/Game/PrimalEarth/Structures/StorageBox_Small.StorageBox_Small'";
auto* actor = BPSpawnActor(uworld, blueprint, &location,
UWorld* world = ArkApi::GetApiUtils().GetWorld();
FString tek_path = FString("Blueprint'/Game/PrimalEarth/Structures/StorageBox_TekShield.StorageBox_TekShield'");
UClass* structure_class = UVictoryCore::BPLoadClass(&tek_path);
if (!structure_class)
Log::GetLog()->critical("There was an error while processing new structures");
AActor* new_actor = world->SpawnActor(structure_class, &loc, &rot, ¶ms);
if (new_actor && new_actor->IsA(APrimalStructureItemContainer::GetPrivateStaticClass()))
spoling_time - GetWorld()->GetTimeSeconds()
Structure->ForceReplicateNow(false, false);
or
Structure->MulticastProperty(FName("bIsLocked", EFindName::FNAME_Add));
(edited)if (ArkApi::GetApiUtils().GetStatus() == ArkApi::ServerStatus::Ready)
{
// code...
}
here->bForceNoPinLocking();
here->bIsLocked() = false;
here->bIsPinLocked() = false;
primal_structure->bBPOverrideAllowStructureAccess() = true;
here->ForceReplicateNow(false, false);
here->MulticastProperty(FName("bIsLocked", EFindName::FNAME_Add));
auto actor = world->SpawnActor(structure_class, &location, rotation, ¶ms);
auto* primal_structure = static_cast<APrimalStructure*>(actor);
primal_structure->HealthField() = primal_structure->MaxHealthField();
primal_structure->StructureIDField() = 10 + 1;
primal_structure->TargetingTeamField() = database->getServerTribeID();
if (primal_structure->IsA(APrimalStructureItemContainer::GetPrivateStaticClass())) {
APrimalStructureItemContainer* here = static_cast<APrimalStructureItemContainer*>(primal_structure);
here->bForceNoPinLocking();
here->bIsLocked() = false;
here->bIsPinLocked() = false;
here->ForceReplicateNow(false, false);
here->MulticastProperty(FName("bIsLocked", EFindName::FNAME_Add));
}
if
condition bellow, and sometimes it does not: std::wstring blueprint = L"/Game/PrimalEarth/CoreBlueprints/Weapons/PrimalItem_WeaponMetalHatchet.PrimalItem_WeaponMetalHatchet_C";
UObject* object = Globals::StaticLoadObject(UObject::StaticClass(), nullptr, blueprint.c_str(), nullptr, 0, 0, true);
if (!object)
// Error
It seems like I need to wait for the garbage collector or something in the background to happen before I can call this code again. If I call it two times in a row without waiting a little the second call returns NULL.
I don't know what is happening exactly and I'm searching a way to always be able to load the blueprint object.
Any help appreciated thank you.if
condition bellow, and sometimes it does not: std::wstring blueprint = L"/Game/PrimalEarth/CoreBlueprints/Weapons/PrimalItem_WeaponMetalHatchet.PrimalItem_WeaponMetalHatchet_C";
UObject* object = Globals::StaticLoadObject(UObject::StaticClass(), nullptr, blueprint.c_str(), nullptr, 0, 0, true);
if (!object)
// Error
It seems like I need to wait for the garbage collector or something in the background to happen before I can call this code again. If I call it two times in a row without waiting a little the second call returns NULL.
I don't know what is happening exactly and I'm searching a way to always be able to load the blueprint object.
Any help appreciated thank you. static bool MySpawnDrop(unsigned long long steamId, const wchar_t* blueprint, int amount, float item_quality, bool force_blueprint, float min_random_quality, float life_span, float offsetX, float offsetY)
{
ArkApi::IApiUtils& utils = ArkApi::GetApiUtils();
AShooterPlayerController* aShooterPC = utils.FindPlayerFromSteamId(steamId);
if (!aShooterPC)
return false;
FVector pos = utils.GetPosition(aShooterPC);
pos.X += offsetX;
pos.Y += offsetY;
UObject* object = Globals::StaticLoadObject(UObject::StaticClass(), nullptr, blueprint, nullptr, 0, 0, true);
if (object == nullptr)
return false;
TSubclassOf<UPrimalItem> archetype;
archetype.uClass = reinterpret_cast<UClass*>(object);
UPrimalItem* item = UPrimalItem::AddNewItem(archetype, nullptr, false, false, item_quality, false, amount, force_blueprint, 0.0F, false, nullptr, min_random_quality);
if (!item)
return false;
FItemNetInfo* info = static_cast<FItemNetInfo*>(FMemory::Malloc(0x400));
RtlSecureZeroMemory(info, 0x400);
item->GetItemNetInfo(info, false);
TSubclassOf<ADroppedItem> archetype_dropped;
archetype_dropped.uClass = reinterpret_cast<UClass*>(object);
FVector zero_vector{ 0.0F, 0.0F, 0.0F };
FRotator rot{ 0.0F, 0.0F, 0.0F };
ADroppedItem* dropped = UPrimalInventoryComponent::StaticDropItem(aShooterPC, info, archetype_dropped, &rot, true, &pos, &rot, true, false, false, true, nullptr, &zero_vector, nullptr, life_span);
FMemory::Free(info);
if (!dropped)
return false;
return true;
}
if (object == nullptr)
return false;
sometimesstatic bool MySpawnDrop(unsigned long long steamId, FString* blueprint, int amount, float item_quality, bool force_blueprint, float min_random_quality, float life_span)
{
ArkApi::IApiUtils& utils = ArkApi::GetApiUtils();
AShooterPlayerController* aShooterPC = utils.FindPlayerFromSteamId(steamId);
if (!aShooterPC)
return false;
UClass* bpUClass = UVictoryCore::BPLoadClass(blueprint);
if (!bpUClass)
return false;
TSubclassOf<UPrimalItem> archetype = TSubclassOf<UPrimalItem>(bpUClass);
UPrimalItem* item = UPrimalItem::AddNewItem(archetype, nullptr, false, false, item_quality, false, amount, force_blueprint, 0.0F, false, nullptr, min_random_quality);
if (!item)
return false;
ADroppedItem* dropped = NULL;
FVector zero_vector{ 0.0F, 0.0F, 0.0F };
FRotator rot{ 0.0F, 0.0F, 0.0F };
FVector pos = utils.GetPosition(aShooterPC);
FItemNetInfo* info = static_cast<FItemNetInfo*>(FMemory::Malloc(0x400));
if (!info)
return MyRemoveItem(&item);
try
{
RtlSecureZeroMemory(info, 0x400);
item->GetItemNetInfo(info, false);
TSubclassOf<ADroppedItem> archetype_dropped = TSubclassOf<ADroppedItem>(bpUClass);
dropped = UPrimalInventoryComponent::StaticDropNewItemWithInfo(aShooterPC, info, archetype_dropped, &rot, true, &pos, &rot, true, false, false, true, nullptr, zero_vector, nullptr, life_span);
}
catch (...) {}
FMemory::Free(info);
if (dropped == NULL)
return MyRemoveItem(&item);
return true;
}
(edited)static FORCEINLINE bool MySpawnInInventory(unsigned long long steamId, FString* blueprint, int amount, float item_quality, bool force_blueprint, float min_random_quality)
{
UClass* bpUClass = UVictoryCore::BPLoadClass(blueprint);
if (!bpUClass)
return false;
AShooterPlayerController* aShooterPC = ArkApi::GetApiUtils().FindPlayerFromSteamId(steamId);
if (!aShooterPC)
return false;
AShooterCharacter* aShooterCharacter = static_cast<AShooterCharacter*>(aShooterPC->CharacterField());
if (!aShooterCharacter)
return false;
UPrimalInventoryComponent* inventoryComponent = aShooterCharacter->MyInventoryComponentField();
if (!inventoryComponent)
return false;
// Probably some cleaner way to check if item is stackable here:
UPrimalItem* tmp = (UPrimalItem*)(bpUClass);
UPrimalItem* tmpB = (UPrimalItem*)(bpUClass);
int quantityOverride = 2;
bool canStack = (inventoryComponent->bAllowItemStacking()() && tmp && tmpB && tmp->CanStackWithItem(tmpB, &quantityOverride));
TSubclassOf<UPrimalItem> archetype = TSubclassOf<UPrimalItem>(bpUClass);
UPrimalItem* item = UPrimalItem::AddNewItem(archetype, nullptr, false, !canStack, item_quality, false, amount, force_blueprint, 0.0F, false, nullptr, min_random_quality);
if (!item)
return false;
bool isUsableConsumable = item->IsUsableConsumable();
try
{
UPrimalItem* item2 = inventoryComponent->AddItemObjectEx(item, false, false, !canStack, true, !isUsableConsumable, false, aShooterCharacter, false, nullptr, false);
if (item2 == NULL)
return MyRemoveItem(&item);
}
catch (...)
{
return MyRemoveItem(&item);
}
return true;
}
MySpawnDrop()
function. On the first call I enter the if (dropped == NULL)
return MyRemoveItem(&item);
but on second call it worksstatic FORCEINLINE bool MyRemoveItem(UPrimalItem** item)
{
// Probably some cleaner way to make sure item has been removed from game here:
try
{
if ((*item)->bAddedToWorldItemMap()())
(*item)->RemoveFromWorldItemMap();
(*item)->ConditionalBeginDestroy();
(*item) = NULL;
}
catch (...) {}
return false;
}
UPrimalItem* tmp = (UPrimalItem*)(bpUClass);
UPrimalItem* tmpB = (UPrimalItem*)(bpUClass);
I'd use (UPrimalItem*)(bpUClass->GetDefaultObject(true));
AShooterCharacter* aShooterCharacter = static_cast<AShooterCharacter*>(aShooterPC->CharacterField());
Also this will get the dino pawn (and thus cast is null) if riding dino. You can use aShooterPc->GetPlayerCharacter() as a more reliable way to get the player characterbool RemoveItem(FItemNetID * itemID, bool bDoDrop, bool bSecondryAction, bool bForceRemoval, bool showHUDMessage)
(*item)->ConditionalBeginDestroy();
(*item) = NULL;
This tells GC I'm done with it, if I'm correct (edited)bAddedToWorldItemMap()
RemoveFromWorldItemMap()
so I added them tooUPrimalItem::RemoveFromWorldItemMap()
this call could be a bad thing or the thing saving me from segfault, I don't know what it does actually (edited)if
condition yet). (edited)AddNewItem()
function is responsible for generating these IDs auto actor = world->SpawnActor(structure_class, &location, rotation, ¶ms);
auto* primal_structure = static_cast<APrimalStructure*>(actor);
primal_structure->HealthField() = primal_structure->MaxHealthField();
primal_structure->TargetingTeamField() = database.get()->getServerTribeID();
if (primal_structure->IsA(APrimalStructureItemContainer::GetPrivateStaticClass())) {
APrimalStructureItemContainer* here = static_cast<APrimalStructureItemContainer*>(primal_structure);
here->BeginPlay();
here->bIsLocked() = false;
here->ForceReplicateNow(false, false);
here->MulticastProperty(FName("bIsLocked", EFindName::FNAME_Add));
}
FString classname = FString(TrophyBPPath);
UObject* trophyclass = UVictoryCore::BPLoadClass(&classname)->GetDefaultObject(true);
UPrimalItem* alphatrophyitem = static_cast<UPrimalItem*>(trophyclass);
if (alphatrophyitem) {
alphatrophyitem->NextSpoilingTimeField() = ArkApi::GetApiUtils().GetWorld()->TimeSecondsField() + 3600;
alphatrophyitem->UpdatedItem(false);
static_cast<APrimalStructureItemContainer*>(Stand)->MyInventoryComponentField()->AddItemObject(alphatrophyitem);
alphatrophyitem->AddToSlot(-1, true);
alphatrophyitem->AddToSlot(-1, true);
ServerAddItemToSlot
or ServerAddItemToSlot_Implementation
might do the trickstatic bool MyGiveItemNum(unsigned long long steamId, int itemNumId, int quantity, float quality, bool forceBlueprint)
{
ArkApi::IApiUtils& utils = ArkApi::GetApiUtils();
AShooterPlayerController* aShooterPC = utils.FindPlayerFromSteamId(steamId);
if (!aShooterPC)
return false;
UShooterCheatManager* cheatManager = utils.GetCheatManager(); // I tried with "GetCheatManagerByPC(aShooterPC);" it doesn't work either
if (!cheatManager)
return false;
cheatManager->GiveItemNumToPlayer(aShooterPC->GetLinkedPlayerID(), itemNumId, quantity, quality, forceBlueprint);
return true;
}
It works as expected on first call, but on subsequent calls nothing happens.
If I drop the item obtained with first call and call my function again it is now working, but item I receive is the same item that I just dropped (if I pick the dropped item it vanishes as it is already in my inventory).PC->GiveItem(&SpawnedItems, &fBlueprint, Amount, Quality, IsBlueprint, false, 0);
!aShooterPC
condition)static bool MyGiveItemNum(unsigned long long steamId, FString* blueprint, int quantity, float quality, bool forceBlueprint)
{
ArkApi::IApiUtils& utils = ArkApi::GetApiUtils();
AShooterPlayerController* aShooterPC = utils.FindPlayerFromSteamId(steamId);
if (!aShooterPC)
return false;
TArray<UPrimalItem*> spawnedItems;
if (!aShooterPC->GiveItem(&spawnedItems, blueprint, quantity, quality, forceBlueprint, false, 0))
return false;
return true;
}
First call works but subsequent call nothing happens (well actually I think I know what happens, it gives me the same item but the anti-dupe check is preventing the same item from getting added again) (edited)!aShooterPC->GiveItem(
False condition on the 2nd call (edited)static bool MyGiveItemNum(unsigned long long steamId, FString* blueprint, int quantity, float quality, bool forceBlueprint)
{
ArkApi::IApiUtils& utils = ArkApi::GetApiUtils();
AShooterPlayerController* aShooterPC = utils.FindPlayerFromSteamId(steamId);
if (!aShooterPC)
return false;
TArray<UPrimalItem*> spawnedItems;
if (!aShooterPC->GiveItem(&spawnedItems, blueprint, quantity, quality, forceBlueprint, false, 0))
return false;
return true;
}
First call works but subsequent call nothing happens (well actually I think I know what happens, it gives me the same item but the anti-dupe check is preventing the same item from getting added again) (edited)if
condition, and what is weird now if I call it a third time it works againif
condition before next call is workingbool ChatMessageCallback(AShooterPlayerController* _AShooterPlayerController, FString* Message, EChatSendMode::Type Mode, bool spam_check, bool command_executed)
{
// here
}
ArkApi::GetCommands().AddChatCommand("/bp", &GetIP);
void GetIP(AShooterPlayerController* PC, FString* message, int mode)
void SetItemStatValue(UPrimalItem* item, EPrimalItemStat::Type item_stat_type, const float new_value)
{
float newStat = 0.f;
if (item_stat_type == EPrimalItemStat::Armor || item_stat_type == EPrimalItemStat::MaxDurability)
{
item->ItemStatValuesField()()[item_stat_type] = 0;
float old_stat_modifier = item->GetItemStatModifier(item_stat_type);
item->ItemStatValuesField()()[item_stat_type] = 1;
newStat = (new_value - old_stat_modifier) / (item->GetItemStatModifier(item_stat_type) - old_stat_modifier);
}
else if (item_stat_type == EPrimalItemStat::WeaponDamagePercent)
{
item->ItemStatValuesField()()[item_stat_type] = 0;
float min_damage = item->GetItemStatModifier(item_stat_type);
item->ItemStatValuesField()()[item_stat_type] = 65535;
float max_damage = item->GetItemStatModifier(item_stat_type);
float diff = max_damage - min_damage;
float multiplier = 65535 / diff;
newStat = new_value / 100.f - min_damage;
newStat *= multiplier;
newStat += 1.f;
}
if (newStat >= 65536.f)
newStat = 65535;
item->ItemStatValuesField()()[item_stat_type] = newStat;
if (item_stat_type == EPrimalItemStat::MaxDurability)
{
if (item->bUseItemDurability()())
item->ItemDurabilityField() = item->GetItemStatModifier(item_stat_type);
}
#ifdef Ark
item->UpdatedItem(false);
#endif
#ifdef Atlas
item->UpdatedItem();
#endif
}
catch (...) { /*doNothing*/ }
like me ^^ (edited)catch (...) { /*doNothing*/ }
(but this one is the worst) (edited)static bool MyGiveItem(uint64 targetSteamId, FString* blueprintPath, int quantity, float quality, bool forceBlueprint, float minRandomQuality)
{
// Get target player
AShooterPlayerController* target = ArkApi::GetApiUtils().FindPlayerFromSteamId(targetSteamId);
if (!target)
return false;
// Get target player's inventory
UPrimalInventoryComponent* targetInventory = target->GetPlayerInventoryComponent();
if (!targetInventory)
return false;
// Get target player character
AShooterCharacter* targetCharacter = target->GetPlayerCharacter();
if (!targetCharacter)
return false;
// Get item class
UClass* bpUClass = UVictoryCore::BPLoadClass(blueprintPath);
if (!bpUClass)
return false;
// Is item stackable?
UPrimalItem* defaultItem = (UPrimalItem*)(bpUClass->GetDefaultObject(true));
int quantityOverride = 2;
bool canStack = (targetInventory->bAllowItemStacking()() && defaultItem && defaultItem->CanStackWithItem(defaultItem, &quantityOverride));
// Create the item
UPrimalItem* item = UPrimalItem::AddNewItem(TSubclassOf<UPrimalItem>(bpUClass), nullptr, false, !canStack, quality, false, quantity, forceBlueprint, 0.0F, false, nullptr, minRandomQuality);
if (!item)
return false;
// Add the item to target's inventory
if (!targetInventory->AddItemObjectEx(item, false, false, !canStack, true, !item->IsUsableConsumable(), false, targetCharacter, false, nullptr, false))
return false;
// Return success
return true;
}
(edited) // Is item stackable?
UPrimalItem* cdo = (UPrimalItem*)(bpUClass->GetDefaultObject(true)); //(UPrimalItem*)(bpUClass);
int quantityOverride = 2;
bool canStack = (targetInventory->bAllowItemStacking()() && cdo && cdo->CanStackWithItem(cdo, &quantityOverride));
bpUClass->GetDefaultObject(true)
should be returning the same pointer anyways for tmp
and tmpB
(edited)