Skip to content

Commit

Permalink
Teleport to Madam Nazar, Moonshine Shack. More recovery options. Stat…
Browse files Browse the repository at this point in the history
…ic call for ScriptFunction
  • Loading branch information
tuyilmaz authored and tuyilmaz committed Jul 24, 2024
1 parent 094174a commit d7bb2de
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 18 deletions.
22 changes: 22 additions & 0 deletions src/game/features/self/TpToMadamNazar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "core/commands/Command.hpp"
#include "game/backend/Self.hpp"
#include "game/rdr/ScriptGlobal.hpp"
#include "util/teleport.hpp"

namespace YimMenu::Features
{

class TpToNazar : public Command
{
using Command::Command;
static constexpr auto NazarLocation = ScriptGlobal(1051832).At(4681);

virtual void OnCall() override
{
if (NazarLocation.CanAccess())
YimMenu::Teleport::TeleportEntity(Self::GetPed().GetHandle(), *NazarLocation.As<Vector3*>(), true);
}
};

static TpToNazar _TpToNazar{"tptonazar", "Teleport To Madam Nazar", "Teleport to Madam Nazar's current location"};
}
34 changes: 34 additions & 0 deletions src/game/features/self/TpToMoonshineShack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "core/commands/Command.hpp"
#include "core/frontend/Notifications.hpp"
#include "game/backend/Self.hpp"
#include "game/rdr/ScriptGlobal.hpp"
#include "util/teleport.hpp"

namespace YimMenu::Features
{

class TpToMoonshineShack : public Command
{
using Command::Command;
static constexpr auto ShackBlip = ScriptGlobal(1297441).At(128);

virtual void OnCall() override
{
if (ShackBlip.CanAccess())
{
Blip Shack = *ShackBlip.As<Blip*>();
if (MAP::DOES_BLIP_EXIST(Shack))
{
Vector3 ShackCoords = MAP::GET_BLIP_COORDS(Shack);
YimMenu::Teleport::TeleportEntity(Self::GetPed().GetHandle(), ShackCoords, true);
}
else
{
Notifications::Show("Moonshine Shack", "Unable to find moonshine shack blip", NotificationType::Error);
}
}
}
};

static TpToMoonshineShack _TpToMoonshineShack{"tptomoonshineshack", "Teleport To Moonshine Shack", "Teleport to your moonshine shack"};
}
26 changes: 25 additions & 1 deletion src/game/frontend/submenus/Recovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,31 @@ namespace YimMenu::Submenus
if (recoveryCommand->GetState())
{
static Rewards::eRewardType selected{};
std::map<Rewards::eRewardType, std::string> reward_translations = {{Rewards::eRewardType::HEIRLOOMS, "Heirlooms"}, {Rewards::eRewardType::COINS, "Coins"}, {Rewards::eRewardType::ALCBOTTLES, "Alcohol Bottles"}, {Rewards::eRewardType::ARROWHEADS, "Arrowheads"}, {Rewards::eRewardType::BRACELETS, "Bracelets"}, {Rewards::eRewardType::EARRINGS, "Earrings"}, {Rewards::eRewardType::NECKLACES, "Necklaces"}, {Rewards::eRewardType::RINGS, "Rings"}, {Rewards::eRewardType::TAROTCARDS_CUPS, "Tarot Cards - Cups"}, {Rewards::eRewardType::TAROTCARDS_PENTACLES, "Tarot Cards - Pentacles"}, {Rewards::eRewardType::TAROTCARDS_SWORDS, "Tarot Cards - Swords"}, {Rewards::eRewardType::TAROTCARDS_WANDS, "Tarot Cards - Wands"}};
std::map<Rewards::eRewardType, std::string> reward_translations = {
{Rewards::eRewardType::HEIRLOOMS, "Heirlooms"},
{Rewards::eRewardType::COINS, "Coins"},
{Rewards::eRewardType::ALCBOTTLES, "Alcohol Bottles"},
{Rewards::eRewardType::ARROWHEADS, "Arrowheads"},
{Rewards::eRewardType::BRACELETS, "Bracelets"},
{Rewards::eRewardType::EARRINGS, "Earrings"},
{Rewards::eRewardType::NECKLACES, "Necklaces"},
{Rewards::eRewardType::RINGS, "Rings"},
{Rewards::eRewardType::TAROTCARDS_CUPS, "Tarot Cards - Cups"},
{Rewards::eRewardType::TAROTCARDS_PENTACLES, "Tarot Cards - Pentacles"},
{Rewards::eRewardType::TAROTCARDS_SWORDS, "Tarot Cards - Swords"},
{Rewards::eRewardType::TAROTCARDS_WANDS, "Tarot Cards - Wands"},
{Rewards::eRewardType::FOSSILS, "Fossils"},
{Rewards::eRewardType::EGGS, "Eggs"},
{Rewards::eRewardType::HERBS, "Herbs"},
{Rewards::eRewardType::TREASURE, "Treasure Reward"},
{Rewards::eRewardType::CAPITALE, "Capitale"},
{Rewards::eRewardType::XP, "25K XP"},
{Rewards::eRewardType::MOONSHINERXP, "200 Moonshiner XP"},
{Rewards::eRewardType::TRADERXP, "200 Trader XP"},
{Rewards::eRewardType::COLLECTORXP, "200 Collector XP"},
{Rewards::eRewardType::NATURALISTXP, "300 Naturalist XP"},
{Rewards::eRewardType::BOUNTYHUNTERXP, "200 Bounty Hunter XP"},
};

if (ImGui::BeginCombo("Rewards", reward_translations[selected].c_str()))
{
Expand Down
2 changes: 2 additions & 0 deletions src/game/frontend/submenus/Teleport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ namespace YimMenu::Submenus
miscGroup->AddItem(std::make_shared<CommandItem>("tptowaypoint"_J));
miscGroup->AddItem(std::make_shared<CommandItem>("tptomount"_J));
miscGroup->AddItem(std::make_shared<CommandItem>("tptotraintrack"_J));
miscGroup->AddItem(std::make_shared<CommandItem>("tptomoonshineshack"_J));
miscGroup->AddItem(std::make_shared<CommandItem>("tptonazar"_J));

main->AddItem(miscGroup);

Expand Down
61 changes: 46 additions & 15 deletions src/game/rdr/ScriptFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,32 +61,63 @@ namespace YimMenu
{
}

void ScriptFunction::Call(const std::vector<uint64_t>& args)
void ScriptFunction::RunScript(rage::scrThread* thread, rage::scrProgram* program, const std::vector<uint64_t>& args)
{
auto pc = GetPC();
auto thread = Scripts::FindScriptThread(m_Hash);
auto program = Scripts::FindScriptProgram(m_Hash);

const auto globals_initialized = std::vector<std::uint8_t>(50, true); // std::vector<bool> does weird stuff so we aren't using that

if (!pc || !thread || !program)
return;

auto old_thread = *Pointers.CurrentScriptThread;
auto old_thread = *Pointers.CurrentScriptThread;
auto old_thread_running = rage::tlsContext::Get()->m_RunningScript;
auto stack = reinterpret_cast<uint64_t*>(thread->m_Stack);
auto context = thread->m_Context;
auto stack = reinterpret_cast<uint64_t*>(thread->m_Stack);
auto context = thread->m_Context;

for (auto& arg : args)
stack[context.m_StackPointer++] = arg;

stack[context.m_StackPointer++] = 0; // return address
context.m_ProgramCounter = pc.value();
context.m_State = rage::eThreadState::idle;
context.m_ProgramCounter = m_Pc.value();
context.m_State = rage::eThreadState::idle;

Pointers.ScriptVM(stack, Pointers.ScriptGlobals, reinterpret_cast<bool*>(const_cast<uint8_t*>(globals_initialized.data())), program, &context);
Pointers.ScriptVM(stack,
Pointers.ScriptGlobals,
reinterpret_cast<bool*>(const_cast<uint8_t*>(globals_initialized.data())),
program,
&context);

rage::tlsContext::Get()->m_RunningScript = old_thread_running;
*Pointers.CurrentScriptThread = old_thread;
*Pointers.CurrentScriptThread = old_thread;
}

void ScriptFunction::StaticCall(const std::vector<uint64_t>& args)
{
auto pc = GetPC();
auto program = Scripts::FindScriptProgram(m_Hash);

if (!pc || !program)
return;

rage::scrThread* thread = (rage::scrThread*)new uint8_t[sizeof(rage::scrThread)];
memcpy(thread, *Pointers.CurrentScriptThread, sizeof(rage::scrThread));

void* stack = new uint64_t[25000];
thread->m_Stack = stack;
thread->m_Context.m_StackSize = 25000;
thread->m_Context.m_StackPointer = 1;

RunScript(thread, program, args);

delete[] stack;
delete[] (uint8_t*)thread;
}

void ScriptFunction::Call(const std::vector<uint64_t>& args)
{
auto pc = GetPC();
auto thread = Scripts::FindScriptThread(m_Hash);
auto program = Scripts::FindScriptProgram(m_Hash);

if (!pc || !thread || !program)
return;

RunScript(thread, program, args);
}
}
29 changes: 27 additions & 2 deletions src/game/rdr/ScriptFunction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,40 @@
#include "core/memory/Pattern.hpp"
#include "util/Joaat.hpp"

namespace rage
{
class scrThread;
class scrProgram;
}

namespace YimMenu
{
class ScriptFunction
{
private:
joaat_t m_Hash;
SimplePattern m_Pattern;
std::optional<std::int32_t> m_Pc;

std::optional<std::int32_t> GetPC();

void RunScript(rage::scrThread* thread, rage::scrProgram* program, const std::vector<uint64_t>& args);

void Call(const std::vector<uint64_t>& args);

void StaticCall(const std::vector<uint64_t>& args);
public:
ScriptFunction(joaat_t hash, SimplePattern pattern);

// TODO: add static_call and return value support
// TODO: return value support

void Call(const std::vector<uint64_t>& args);
template<typename... Args>
void StaticCall(Args... args)
{
std::vector<uint64_t> params;
(params.push_back(static_cast<std::uint64_t>(args)), ...);
StaticCall(params);
}

template<typename... Args>
void operator()(Args... args)
Expand All @@ -26,4 +45,10 @@ namespace YimMenu
Call(params);
}
};

namespace ScriptFunctions
{
static inline ScriptFunction GiveItemDatabaseAward("interactive_campfire"_J, "22 05 24");
static inline ScriptFunction GiveLootTableAward("interactive_campfire"_J, "22 02 14 00 00 2F");
}
}
84 changes: 84 additions & 0 deletions src/util/Rewards.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "Rewards.hpp"
#include "game/backend/ScriptMgr.hpp"
#include "game/pointers/Pointers.hpp"
#include "game/rdr/Natives.hpp"
#include "game/rdr/ScriptFunction.hpp"
#include <event/CEventGroup.hpp>
#include <event/CEventInventoryItemPickedUp.hpp>

Expand All @@ -12,6 +15,21 @@ namespace YimMenu::Rewards
(*Pointers.EventGroupNetwork)->AddEvent(&event, false);
};

void GiveScriptReward(const RewardInfo& info, bool loottable)
{
if (!SCRIPTS::HAS_SCRIPT_WITH_NAME_HASH_LOADED("interactive_campfire"_J))
{
SCRIPTS::REQUEST_SCRIPT_WITH_NAME_HASH("interactive_campfire"_J);
for (int i = 0; i < 150 && !SCRIPTS::HAS_SCRIPT_WITH_NAME_HASH_LOADED("interactive_campfire"_J); i++)
ScriptMgr::Yield(10ms);
}

if (loottable)
ScriptFunctions::GiveLootTableAward.StaticCall(info.reward_hash, 0);
else
ScriptFunctions::GiveItemDatabaseAward.StaticCall(info.reward_hash, false, 255, 0, false);
}

void GiveRequestedRewards(std::vector<eRewardType> rewards)
{
for (auto& reward : rewards)
Expand Down Expand Up @@ -97,6 +115,72 @@ namespace YimMenu::Rewards
GiveReward(card);
}
break;
case eRewardType::FOSSILS:
for (const auto& fossil : Fossils)
{
GiveScriptReward(fossil);
}
break;
case eRewardType::EGGS:
for (const auto& egg : Eggs)
{
GiveScriptReward(egg);
}
break;
case eRewardType::HERBS:
for (const auto& herb : Herbs)
{
GiveScriptReward(herb);
}
break;
case eRewardType::TREASURE:
for (const auto& treasure : TreasureReward)
{
GiveScriptReward(treasure);
}
break;
case eRewardType::CAPITALE:
for (const auto& capitale : CapitaleReward)
{
GiveScriptReward(capitale);
}
break;
case eRewardType::XP:
for (const auto& xp : RegularXP)
{
GiveScriptReward(xp, false);
}
break;
case eRewardType::MOONSHINERXP:
for (const auto& xp : MoonshinerXP)
{
GiveScriptReward(xp, false);
}
break;
case eRewardType::TRADERXP:
for (const auto& xp : TraderXP)
{
GiveScriptReward(xp, false);
}
break;
case eRewardType::COLLECTORXP:
for (const auto& xp : CollectorXP)
{
GiveScriptReward(xp, false);
}
break;
case eRewardType::NATURALISTXP:
for (const auto& xp : NaturalistXP)
{
GiveScriptReward(xp, false);
}
break;
case eRewardType::BOUNTYHUNTERXP:
for (const auto& xp : BountyHunterXP)
{
GiveScriptReward(xp, false);
}
break;
}
}
};
Expand Down
34 changes: 34 additions & 0 deletions src/util/Rewards.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@ namespace YimMenu::Rewards

inline const RewardInfo TarotCards_Wands[]{{"MP005_S_CARDT_2W"_J, "DOCUMENT_CARD_TWO_WANDS"_J, "2 of Wands"}, {"MP005_S_CARDT_3W"_J, "DOCUMENT_CARD_THREE_WANDS"_J, "3 of Wands"}, {"MP005_S_CARDT_4W"_J, "DOCUMENT_CARD_FOUR_WANDS"_J, "4 of Wands"}, {"MP005_S_CARDT_5W"_J, "DOCUMENT_CARD_FIVE_WANDS"_J, "5 of Wands"}, {"MP005_S_CARDT_6W"_J, "DOCUMENT_CARD_SIX_WANDS"_J, "6 of Wands"}, {"MP005_S_CARDT_7W"_J, "DOCUMENT_CARD_SEVEN_WANDS"_J, "7 of Wands"}, {"MP005_S_CARDT_8W"_J, "DOCUMENT_CARD_EIGHT_WANDS"_J, "8 of Wands"}, {"MP005_S_CARDT_9W"_J, "DOCUMENT_CARD_NINE_WANDS"_J, "9 of Wands"}, {"MP005_S_CARDT_10W"_J, "DOCUMENT_CARD_TEN_WANDS"_J, "10 of Wands"}, {"MP005_S_CARDT_ACW"_J, "DOCUMENT_CARD_ACE_WANDS"_J, "Ace of Wands"}, {"MP005_S_CARDT_KIW"_J, "DOCUMENT_CARD_KING_WANDS"_J, "King of Wands"}, {"MP005_S_CARDT_KNW"_J, "DOCUMENT_CARD_KNIGHT_WANDS"_J, "Knight of Wands"}, {"MP005_S_CARDT_PAW"_J, "DOCUMENT_CARD_PAGE_WANDS"_J, "Page of Wands"}, {"MP005_S_CARDT_QUW"_J, "DOCUMENT_CARD_QUEEN_WANDS"_J, "Queen of Wands"}};

inline const RewardInfo Fossils[]{{0, "COLLECTIBLE_FOSSIL_CORAL"_J, ""}, {0, "COLLECTIBLE_FOSSIL_BIVALVE"_J, ""}, {0, "COLLECTIBLE_FOSSIL_BRACHIOPOD"_J, ""}, {0, "COLLECTIBLE_FOSSIL_BROW_HORN"_J, ""}, {0, "COLLECTIBLE_FOSSIL_CEPHALOPOD"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TRILOBITE_CRYPTO"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TRILOBITE_ISO"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TOOTH_MEGA"_J, ""}, {0, "COLLECTIBLE_FOSSIL_NEO"_J, ""}, {0, "COLLECTIBLE_FOSSIL_STONE"_J, ""}, {0, "COLLECTIBLE_FOSSIL_PET_WOOD"_J, ""}, {0, "COLLECTIBLE_FOSSIL_PET_WOOD_RAINBOW"_J, ""}, {0, "COLLECTIBLE_FOSSIL_SEA_LILY"_J, ""}, {0, "COLLECTIBLE_FOSSIL_SEA_SCORPION"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TOOTH_SERRATED"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TAIL_SPIKE"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TOE_CLAW"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TOOTH_TREX"_J, ""}, {0, "COLLECTIBLE_FOSSIL_TULLY_MONSTER"_J, ""}, {0, "COLLECTIBLE_FOSSIL_PET_WOOD_YELLOW"_J, ""}};

inline const RewardInfo Eggs[]{{0, "COLLECTIBLE_EGG_VULTURE"_J, ""}, {0, "COLLECTIBLE_EGG_LOON"_J, ""}, {0, "COLLECTIBLE_EGG_DUCK"_J, ""}, {0, "COLLECTIBLE_EGG_GOOSE"_J, ""}, {0, "COLLECTIBLE_EGG_HERON"_J, ""}, {0, "COLLECTIBLE_EGG_EGRET"_J, ""}, {0, "COLLECTIBLE_EGG_EAGLE"_J, ""}, {0, "COLLECTIBLE_EGG_HAWK"_J, ""}, {0, "COLLECTIBLE_EGG_SPOONBILL"_J, ""}, {0, "COLLECTIBLE_EGG_CONDOR"_J, ""}};

inline const RewardInfo Herbs[]{{0, "HERB_LOOT_ALASKAN_GINSENG"_J, "Alaskan Ginseng"}, {0, "HERB_LOOT_AMERICAN_GINSENG"_J, "American Ginseng"}, {0, "HERB_LOOT_BAY_BOLETE"_J, "Bay Bolete"}, {0, "HERB_LOOT_BLACK_BERRY"_J, "Black Berry"}, {0, "HERB_LOOT_BLACK_CURRANT"_J, "Black Currant"}, {0, "HERB_LOOT_BURDOCK_ROOT"_J, "Burdock Root"}, {0, "HERB_LOOT_CHANTERELLES"_J, "Chanterelles"}, {0, "HERB_LOOT_COMMON_BULRUSH"_J, "Common Bulrush"}, {0, "HERB_LOOT_CREEPING_THYME"_J, "Creeping Thyme"}, {0, "HERB_LOOT_DESERT_SAGE"_J, "Desert Sage"}, {0, "HERB_LOOT_ENGLISH_MACE"_J, "English Mace"}, {0, "HERB_LOOT_EVERGREEN_HUCKLEBERRY"_J, "Evergreen Huckleberry"}, {0, "HERB_LOOT_GOLDEN_CURRANT"_J, "Golden Currant"}, {0, "HERB_LOOT_HUMMINGBIRD_SAGE"_J, "Hummingbird Sage"}, {0, "HERB_LOOT_INDIAN_TOBACCO"_J, "Indian Tobacco"}, {0, "HERB_LOOT_MILKWEED"_J, "Milkweed"}, {0, "HERB_LOOT_OLEANDER_SAGE"_J, "Oleander Sage"}, {0, "HERB_LOOT_OREGANO"_J, "Oregano"}, {0, "HERB_LOOT_PARASOL_MUSHROOM"_J, "Parasol Mushroom"}, {0, "HERB_LOOT_PRAIRIE_POPPY"_J, "Prairie Poppy"}, {0, "HERB_LOOT_RAMS_HEAD"_J, "Rams Head"}, {0, "HERB_LOOT_RED_RASPBERRY"_J, "Red Raspberry"}, {0, "HERB_LOOT_RED_SAGE"_J, "Red Sage"}, {0, "HERB_LOOT_VANILLA_FLOWER"_J, "Vanilla Flower"}, {0, "HERB_LOOT_VIOLET_SNOWDROP"_J, "Violet Snowdrop"}, {0, "HERB_LOOT_WILD_CARROTS"_J, "Wild Carrots"}, {0, "HERB_LOOT_WILD_FEVERFEW"_J, "Wild Feverfew"}, {0, "HERB_LOOT_WILD_MINT"_J, "Wild Mint"}, {0, "HERB_LOOT_WINTERGREEN_BERRY"_J, "Wintergreen Berry"}, {0, "HERB_LOOT_YARROW"_J, "Yarrow"}, {0, "HERB_LOOT_AGARITA"_J, "Agarita"}, {0, "HERB_LOOT_BITTERWEED"_J, "Bitterweed"}, {0, "HERB_LOOT_BLUE_BONNET"_J, "Blue Bonnet"}, {0, "HERB_LOOT_BLOOD_FLOWER"_J, "Blood Flower"}, {0, "HERB_LOOT_CARDINAL_FLOWER"_J, "Cardinal Flower"}, {0, "HERB_LOOT_CHOCOLATE_DAISY"_J, "Chocolate Daisy"}, {0, "HERB_LOOT_CREEK_PLUM"_J, "Creek Plum"}, {0, "HERB_LOOT_RHUBARB"_J, "Rhubarb"}, {0, "HERB_LOOT_WISTERIA"_J, "Wisteria"}, {0, "HERB_LOOT_HARRIETUM"_J, "Harrietum"}};

inline const RewardInfo TreasureReward[]{{0, "REWARD_ABANDONED_LOOT_MALE"_J, "Treasure Reward"}};

inline const RewardInfo CapitaleReward[]{{0, "REWARD_CAPITALE_CHEST_LARGE"_J, "Capitale Reward"}};

inline const RewardInfo RegularXP[]{{0, "AWARD_XP_MISSION_COMPLETE_REWARD_XXL"_J, "25K XP Reward"}};

inline const RewardInfo MoonshinerXP[]{{0, 0xCBA92A55, "Moonshine XP Reward"}};

inline const RewardInfo TraderXP[]{{0, 0xB11109AB, "Trader XP Reward"}};

inline const RewardInfo CollectorXP[]{{0, 0xA64F15F2, "Collector XP Reward"}};

inline const RewardInfo NaturalistXP[]{{0, 0x05839847, "Naturalist XP Reward"}};

inline const RewardInfo BountyHunterXP[]{{0, 0x5424CC1A, "Bounty Hunter XP Reward"}};

enum class eRewardType : int
{
// GOLD_REWARDS,
Expand All @@ -53,8 +75,20 @@ namespace YimMenu::Rewards
TAROTCARDS_PENTACLES,
TAROTCARDS_SWORDS,
TAROTCARDS_WANDS,
FOSSILS,
EGGS,
HERBS,
TREASURE,
CAPITALE,
XP,
MOONSHINERXP,
TRADERXP,
COLLECTORXP,
NATURALISTXP,
BOUNTYHUNTERXP,
};

void GiveRequestedRewards(std::vector<eRewardType> rewards);
void GiveReward(const RewardInfo& info);
void GiveScriptReward(const RewardInfo& info, bool loottable = true);
}

0 comments on commit d7bb2de

Please sign in to comment.