├── LunkyBox ├── Memory │ ├── Memory.cpp │ ├── Memory.h │ ├── Offsets.h │ └── Offsets.cpp ├── Spelunky │ ├── ITEM_CLASS.cpp │ ├── ENTITY_CLASS.cpp │ ├── ITEM_CLASS.h │ ├── Entity.h │ ├── Player.h │ ├── Spelunky.h │ ├── Entity.cpp │ ├── Player.cpp │ ├── Spelunky.cpp │ └── ENTITY_CLASS.h ├── Vector2.cpp ├── Vector2.h ├── packages.config ├── Input │ ├── KeyState.cpp │ ├── KeyState.h │ ├── Input.h │ └── Input.cpp ├── Module.h ├── Main.h ├── Config │ ├── Config.h │ └── Config.cpp ├── Module.cpp ├── Window │ ├── Window.h │ └── Window.cpp ├── Mod │ ├── BoolMenuItem.h │ ├── IntMenuItem.h │ ├── MenuItem.h │ ├── BoolMenuItem.cpp │ ├── Mod.h │ ├── MenuItem.cpp │ ├── Menu.h │ ├── IntMenuItem.cpp │ ├── Menu.cpp │ └── Mod.cpp ├── .gitattributes ├── Drawing │ ├── Drawing.h │ └── Drawing.cpp ├── Main.cpp ├── D3d9.h ├── D3d9.cpp ├── LunkyBox.vcxproj.filters └── LunkyBox.vcxproj ├── LunkyBoxInjector ├── packages.config ├── Main.h ├── LunkyBoxInjector.vcxproj.filters ├── Main.cpp └── LunkyBoxInjector.vcxproj ├── config.txt ├── .gitattributes ├── LunkyBox.sln ├── README.md └── .gitignore /LunkyBox/Memory/Memory.cpp: -------------------------------------------------------------------------------- 1 | #include "Memory.h" 2 | 3 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/ITEM_CLASS.cpp: -------------------------------------------------------------------------------- 1 | #include "ITEM_CLASS.h" 2 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/ENTITY_CLASS.cpp: -------------------------------------------------------------------------------- 1 | #include "ENTITY_CLASS.h" 2 | -------------------------------------------------------------------------------- /LunkyBox/Vector2.cpp: -------------------------------------------------------------------------------- 1 | #include "Vector2.h" 2 | 3 | 4 | Vector2::Vector2(float x, float y) 5 | { 6 | this->x = x; 7 | this->y = y; 8 | } 9 | -------------------------------------------------------------------------------- /LunkyBox/Vector2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | class Vector2 5 | { 6 | public: 7 | float x; 8 | float y; 9 | 10 | Vector2(float x, float y); 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /LunkyBox/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /LunkyBox/Input/KeyState.cpp: -------------------------------------------------------------------------------- 1 | #include "KeyState.h" 2 | 3 | 4 | namespace Input 5 | { 6 | KeyState::KeyState() 7 | { 8 | state = false; 9 | oldState = false; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /LunkyBoxInjector/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /LunkyBox/Module.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; 8 | 9 | 10 | std::string GetModuleDirectory(); 11 | -------------------------------------------------------------------------------- /LunkyBox/Main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "D3d9.h" 6 | #include "Mod/Mod.h" 7 | 8 | 9 | bool APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved); 10 | -------------------------------------------------------------------------------- /config.txt: -------------------------------------------------------------------------------- 1 | input_toggle_menu=0x74 2 | input_select=0x65 3 | input_back=0x60 4 | input_up=0x68 5 | input_down=0x62 6 | input_left=0x64 7 | input_right=0x66 8 | 9 | menu_x=10 10 | menu_y=10 11 | menu_width=300 12 | menu_items_per_page=7 13 | menu_sounds=on 14 | menu_layout=single_page -------------------------------------------------------------------------------- /LunkyBox/Config/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Config 8 | { 9 | bool Parse(std::string fileName); 10 | 11 | std::string GetText(std::string key); 12 | 13 | int GetNumber(std::string key); 14 | 15 | bool GetBool(std::string key); 16 | } 17 | -------------------------------------------------------------------------------- /LunkyBox/Module.cpp: -------------------------------------------------------------------------------- 1 | #include "Module.h" 2 | 3 | using namespace std; 4 | 5 | 6 | string GetModuleDirectory() 7 | { 8 | char path[MAX_PATH] = {0}; 9 | GetModuleFileName((HINSTANCE)&__ImageBase, path, _countof(path)); 10 | 11 | string::size_type pos = string(path).find_last_of("\\/"); 12 | 13 | return string(path).substr(0, pos); 14 | } 15 | -------------------------------------------------------------------------------- /LunkyBox/Window/Window.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Vector2.h" 5 | 6 | 7 | namespace Window 8 | { 9 | HWND FindMainWindow(unsigned long process_id); 10 | 11 | BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam); 12 | 13 | BOOL IsMainWindow(HWND handle); 14 | 15 | Vector2 GetRelativeCursorPosition(); 16 | } 17 | -------------------------------------------------------------------------------- /LunkyBox/Input/KeyState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Input 7 | { 8 | class KeyState 9 | { 10 | public: 11 | bool state; 12 | bool oldState; 13 | std::chrono::time_point firstPressedTime; 14 | std::chrono::time_point pressedTime; 15 | 16 | KeyState(); 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /LunkyBox/Mod/BoolMenuItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MenuItem.h" 4 | 5 | 6 | namespace Mod 7 | { 8 | class BoolMenuItem : public MenuItem 9 | { 10 | public: 11 | bool isOn; 12 | 13 | BoolMenuItem(Menu* parentMenu, std::string name, bool isOn = false); 14 | 15 | virtual void Update(); 16 | 17 | virtual void Draw(LPDIRECT3DDEVICE9 deviceInterface, int menuItemIndex); 18 | 19 | virtual void Select(); 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /LunkyBox/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /LunkyBoxInjector/Main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | const char* TITLE = "LunkyBox Injector"; 8 | const char* DLL_NAME = "LunkyBox.dll"; 9 | const char* PROCESS_NAME = "Spelunky.exe"; 10 | 11 | 12 | int main(); 13 | 14 | DWORD GetProcess(std::string processName); 15 | 16 | bool InjectDLL(DWORD ProcessID, std::string dllName); 17 | 18 | std::string GetModuleDirectory(HMODULE hModule); 19 | 20 | void ConsoleTitle(); 21 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/ITEM_CLASS.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Spelunky 5 | { 6 | enum class ITEM_CLASS 7 | { 8 | ANKH = 124, 9 | BOOK_OF_THE_DEAD = 123, 10 | HEDJET = 121, 11 | UDJAT_EYE = 122, 12 | CLIMBING_GLOVES = 115, 13 | COMPASS = 112, 14 | CRYSKNIFE = 128, 15 | KAPALA = 120, 16 | PARACHUTE = 113, 17 | PASTE = 125, 18 | PITCHERS_MITT = 116, 19 | SPECTACLES = 119, 20 | SPIKE_SHOES = 118, 21 | SPRING_SHOES = 117, 22 | VLADS_AMULET = 129 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /LunkyBox/Drawing/Drawing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #pragma comment(lib, "d3d9.lib") 5 | 6 | #include 7 | #pragma comment(lib, "d3dx9.lib") 8 | 9 | #include "../Vector2.h" 10 | 11 | 12 | namespace Drawing 13 | { 14 | void DrawRectangle(LPDIRECT3DDEVICE9 deviceInterface, int x, int y, int width, int height, D3DCOLOR color); 15 | 16 | void DrawText(LPD3DXFONT font, LPCSTR text, int x, int y, int width, int height, D3DCOLOR color); 17 | 18 | int GetTextWidth(LPD3DXFONT font, LPCSTR text); 19 | } 20 | -------------------------------------------------------------------------------- /LunkyBox/Mod/IntMenuItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MenuItem.h" 4 | 5 | 6 | namespace Mod 7 | { 8 | class IntMenuItem : public MenuItem 9 | { 10 | public: 11 | std::function OnValueChanged; 12 | bool isEditing; 13 | bool skipNextUpdate; 14 | int value; 15 | int minValue; 16 | int maxValue; 17 | int bigValueAdd; 18 | 19 | IntMenuItem(Menu* parentMenu, std::string name, int value = 0, int minValue = 0, int maxValue = 100, int bigValueAdd = 10); 20 | 21 | virtual void Update(); 22 | 23 | virtual void Draw(LPDIRECT3DDEVICE9 deviceInterface, int menuItemIndex); 24 | 25 | virtual void Select(); 26 | 27 | void SetIsEditing(bool isEditing); 28 | 29 | void ValueAdd(int value); 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /LunkyBox/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.h" 2 | 3 | 4 | bool APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved) 5 | { 6 | switch(reason) 7 | { 8 | case DLL_PROCESS_ATTACH: 9 | { 10 | //Create new thread for mod 11 | 12 | CreateThread(NULL, 0, &Mod::Start, NULL, NULL, NULL); 13 | 14 | 15 | //Direct X hooking 16 | 17 | DisableThreadLibraryCalls(hModule); 18 | 19 | if(Direct3DCreate9_VMTable() != D3D_OK) 20 | { 21 | return false; 22 | } 23 | 24 | break; 25 | } 26 | 27 | case DLL_PROCESS_DETACH: 28 | { 29 | break; 30 | } 31 | 32 | case DLL_THREAD_ATTACH: 33 | { 34 | break; 35 | } 36 | 37 | case DLL_THREAD_DETACH: 38 | { 39 | break; 40 | } 41 | } 42 | 43 | return true; 44 | } 45 | -------------------------------------------------------------------------------- /LunkyBox/D3d9.h: -------------------------------------------------------------------------------- 1 | //Thanks to Roverturbo | www.unknowncheats.me for this d3d9 code 2 | 3 | 4 | #pragma once 5 | 6 | #include 7 | #pragma comment(lib, "d3d9.lib") 8 | 9 | #include 10 | #pragma comment(lib, "d3dx9.lib") 11 | 12 | #include 13 | #include 14 | #include "Main.h" 15 | #include "Mod/Mod.h" 16 | 17 | 18 | HRESULT WINAPI Direct3DCreate9_VMTable(); 19 | HRESULT WINAPI CreateDevice_Detour(LPDIRECT3D9, UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE9*); 20 | HRESULT WINAPI Reset_Detour(LPDIRECT3DDEVICE9, D3DPRESENT_PARAMETERS*); 21 | HRESULT WINAPI EndScene_Detour(LPDIRECT3DDEVICE9); 22 | HRESULT WINAPI DrawIndexedPrimitive_Detour(LPDIRECT3DDEVICE9, D3DPRIMITIVETYPE, INT, UINT, UINT, UINT, UINT); 23 | -------------------------------------------------------------------------------- /LunkyBox/Input/Input.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "KeyState.h" 6 | 7 | 8 | namespace Input 9 | { 10 | const long long TIME_FIRST_PRESS = 500; 11 | const long long TIME_PRESS = 50; 12 | 13 | enum class INPUT_MODE 14 | { 15 | //Triggers all the time 16 | NORMAL, 17 | //Only triggers the first time. 18 | ONCE, 19 | //Only triggers the first time and on a interval after a small time. This is basicly like a textbox input. 20 | CONTINUOUS 21 | }; 22 | 23 | 24 | extern std::map keyStates; 25 | 26 | void AddKeyState(int vKey); 27 | 28 | 29 | //Called every tick 30 | void Update(); 31 | 32 | //Is a key pressed? 33 | bool IsKeyPressed(int vKey, INPUT_MODE inputMode); 34 | 35 | //Is a key released? 36 | bool IsKeyReleased(int vKey, INPUT_MODE inputMode); 37 | } 38 | -------------------------------------------------------------------------------- /LunkyBox/Mod/MenuItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #pragma comment(lib, "d3d9.lib") 5 | 6 | #include 7 | #pragma comment(lib, "d3dx9.lib") 8 | 9 | #include 10 | #include 11 | #include "Menu.h" 12 | #include "../Drawing/Drawing.h" 13 | 14 | 15 | namespace Mod 16 | { 17 | class Menu; 18 | 19 | class MenuItem 20 | { 21 | public: 22 | Menu* parentMenu; 23 | std::string name; 24 | std::function OnSelect; 25 | std::function OnUpdate; 26 | std::function OnDraw; 27 | bool hasSound; 28 | 29 | MenuItem(Menu* parentMenu, std::string name); 30 | 31 | virtual void Update(); 32 | 33 | virtual void Draw(LPDIRECT3DDEVICE9 deviceInterface, int menuItemIndex); 34 | 35 | virtual void Select(); 36 | 37 | bool IsInFocus(); 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/Entity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "../Vector2.h" 6 | 7 | 8 | namespace Spelunky 9 | { 10 | const std::vector ENTITY_POSITION_X_OFFSETS = {0x30}; 11 | const std::vector ENTITY_POSITION_Y_OFFSETS = {0x34}; 12 | const std::vector ENTITY_VELOCITY_X_OFFSETS = {0x244}; 13 | const std::vector ENTITY_VELOCITY_Y_OFFSETS = {0x248}; 14 | const std::vector ENTITY_IS_FLIPPED_OFFSETS = {0x9D}; 15 | 16 | class Entity 17 | { 18 | public: 19 | DWORD address; 20 | 21 | 22 | Entity(DWORD address); 23 | 24 | void SetPosition(Vector2 position); 25 | 26 | Vector2 GetPosition(); 27 | 28 | void SetVelocity(Vector2 velocity); 29 | 30 | Vector2 GetVelocity(); 31 | 32 | void SetIsFlipped(bool isFlipped); 33 | 34 | bool IsFlipped(); 35 | 36 | void PlaySound(const char* sound); 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /LunkyBox/Drawing/Drawing.cpp: -------------------------------------------------------------------------------- 1 | #include "Drawing.h" 2 | 3 | 4 | namespace Drawing 5 | { 6 | void DrawRectangle(LPDIRECT3DDEVICE9 deviceInterface, int x, int y, int width, int height, D3DCOLOR color) 7 | { 8 | D3DRECT rect = { 9 | x, 10 | y, 11 | x + width, 12 | y + height 13 | }; 14 | 15 | deviceInterface->Clear(1, &rect, D3DCLEAR_TARGET | D3DCLEAR_TARGET, color, 0, 0); 16 | } 17 | 18 | void DrawText(LPD3DXFONT font, LPCSTR text, int x, int y, int width, int height, D3DCOLOR color) 19 | { 20 | RECT rect; 21 | rect.left = x; 22 | rect.top = y; 23 | rect.right = x + width; 24 | rect.bottom = y + height; 25 | 26 | font->DrawText(NULL, text, -1, &rect, 0, color); 27 | } 28 | 29 | int GetTextWidth(LPD3DXFONT font, LPCSTR text) 30 | { 31 | RECT rect = {0, 0, 0, 0}; 32 | 33 | if(font) 34 | { 35 | // calculate required rect 36 | font->DrawText(NULL, text, -1, &rect, DT_CALCRECT, D3DCOLOR_XRGB(0, 0, 0)); 37 | } 38 | 39 | // return width 40 | return rect.right - rect.left; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LunkyBox/Mod/BoolMenuItem.cpp: -------------------------------------------------------------------------------- 1 | #include "BoolMenuItem.h" 2 | #include "../Config/Config.h" 3 | 4 | 5 | namespace Mod 6 | { 7 | BoolMenuItem::BoolMenuItem(Menu* parentMenu, std::string name, bool isOn) : MenuItem(parentMenu, name) 8 | { 9 | this->isOn = isOn; 10 | } 11 | 12 | void BoolMenuItem::Update() 13 | { 14 | MenuItem::Update(); 15 | } 16 | 17 | void BoolMenuItem::Draw(LPDIRECT3DDEVICE9 deviceInterface, int menuItemIndex) 18 | { 19 | MenuItem::Draw(deviceInterface, menuItemIndex); 20 | 21 | LPCSTR onOffText = isOn ? "ON" : "OFF"; 22 | int textWidth = Drawing::GetTextWidth(fontMenuItem, onOffText); 23 | 24 | Drawing::DrawText(fontMenuItem, onOffText, Config::GetNumber("menu_x") + Config::GetNumber("menu_width") - textWidth - 4, Config::GetNumber("menu_y") + TITLE_BOX_HEIGHT + 6 + (ITEM_HEIGHT + MENU_MARGIN) * menuItemIndex, Config::GetNumber("menu_width") - MENU_MARGIN, ITEM_HEIGHT - MENU_MARGIN, IsInFocus() ? color2 : color1); 25 | } 26 | 27 | void BoolMenuItem::Select() 28 | { 29 | isOn = !isOn; 30 | 31 | MenuItem::Select(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LunkyBox/Mod/Mod.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #pragma comment(lib, "d3d9.lib") 5 | 6 | #include 7 | #pragma comment(lib, "d3dx9.lib") 8 | 9 | #include "Menu.h" 10 | #include "../Spelunky/Spelunky.h" 11 | #include "../Spelunky/Player.h" 12 | #include "../Memory/Offsets.h" 13 | 14 | 15 | namespace Mod 16 | { 17 | const char* const TITLE = "LunkyBox v1.4"; 18 | const char* const FONT = "Arial"; 19 | const char* const CONFIG_FILE = "config.txt"; 20 | 21 | extern Spelunky::Player player; 22 | extern LPD3DXFONT fontMenuTitle; 23 | extern LPD3DXFONT fontMenuPageNumber; 24 | extern LPD3DXFONT fontMenuItem; 25 | extern D3DCOLOR color1; 26 | extern D3DCOLOR color2; 27 | 28 | 29 | DWORD WINAPI Start(LPVOID param); 30 | 31 | void Update(); 32 | 33 | void D3D9Reset(LPDIRECT3DDEVICE9 deviceInterface, D3DPRESENT_PARAMETERS* presentationParameters); 34 | 35 | void D3D9EndScene(LPDIRECT3DDEVICE9 deviceInterface); 36 | 37 | void MenuUpdate(); 38 | 39 | void InfiniteStatsUpdate(); 40 | 41 | void FrozenTimeUpdate(); 42 | 43 | void CreateFonts(LPDIRECT3DDEVICE9 deviceInterface); 44 | 45 | void CreateMenus(); 46 | } 47 | -------------------------------------------------------------------------------- /LunkyBox/Memory/Memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Memory 8 | { 9 | //Read from a address with offsets 10 | template 11 | T Read(DWORD baseAddress, const std::vector offsets) 12 | { 13 | DWORD address = baseAddress; 14 | unsigned int offsetsSize = offsets.size(); 15 | 16 | for(unsigned int i = 0; i < offsetsSize - 1; i++) 17 | { 18 | if(address != NULL) 19 | { 20 | address = *(DWORD*)(address + offsets[i]); 21 | } 22 | } 23 | 24 | return address == NULL ? NULL : *(T*)(address + offsets[offsetsSize - 1]); 25 | } 26 | 27 | //Write to a address with offsets 28 | template 29 | void Write(DWORD baseAddress, const std::vector offsets, T value) 30 | { 31 | DWORD address = baseAddress; 32 | unsigned int offsetsSize = offsets.size(); 33 | 34 | for(unsigned int i = 0; i < offsetsSize - 1; i++) 35 | { 36 | if(address != NULL) 37 | { 38 | address = *(DWORD*)(address + offsets[i]); 39 | } 40 | } 41 | 42 | if(address != NULL) 43 | { 44 | *(T*)(address + offsets[offsetsSize - 1]) = value; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LunkyBox/Window/Window.cpp: -------------------------------------------------------------------------------- 1 | #include "Window.h" 2 | 3 | 4 | namespace Window 5 | { 6 | struct HandleData 7 | { 8 | unsigned long processID; 9 | HWND bestHandle; 10 | }; 11 | 12 | HWND FindMainWindow(DWORD processID) 13 | { 14 | HandleData data; 15 | data.processID = processID; 16 | data.bestHandle = 0; 17 | EnumWindows(EnumWindowsCallback, (LPARAM)&data); 18 | return data.bestHandle; 19 | } 20 | 21 | BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM param) 22 | { 23 | HandleData& data = *(HandleData*)param; 24 | DWORD processID = 0; 25 | 26 | GetWindowThreadProcessId(handle, &processID); 27 | 28 | if(data.processID != processID || !IsMainWindow(handle)) 29 | { 30 | return TRUE; 31 | } 32 | 33 | data.bestHandle = handle; 34 | 35 | return FALSE; 36 | } 37 | 38 | BOOL IsMainWindow(HWND handle) 39 | { 40 | return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle); 41 | } 42 | 43 | Vector2 GetRelativeCursorPosition() 44 | { 45 | POINT point; 46 | HWND window = FindMainWindow(GetCurrentProcessId()); 47 | 48 | if(GetCursorPos(&point) && ScreenToClient(window, &point)) 49 | { 50 | return Vector2((float)point.x, (float)point.y); 51 | } 52 | 53 | return Vector2(0, 0); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /LunkyBoxInjector/LunkyBoxInjector.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/Player.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "Spelunky.h" 6 | #include "Entity.h" 7 | #include "ITEM_CLASS.h" 8 | #include "../Vector2.h" 9 | #include "../Memory/Offsets.h" 10 | 11 | 12 | namespace Spelunky 13 | { 14 | const std::vector PLAYER_HAS_ITEM_OFFSETS = {0x280}; 15 | const std::vector PLAYER_GOLD_OFFSETS = {0x280, 0x5298}; 16 | const std::vector PLAYER_HEARTS_OFFSETS = {0x140}; 17 | const std::vector PLAYER_BOMBS_OFFSETS = {0x280, 0x10}; 18 | const std::vector PLAYER_ROPES_OFFSETS = {0x280, 0x14}; 19 | const std::vector PLAYER_FAVOR_OFFSETS = {0x280, 0x529C}; 20 | 21 | 22 | class Player : public Entity 23 | { 24 | public: 25 | static Player GetLocal(); 26 | 27 | Player(DWORD address); 28 | 29 | //Fancy version of SetPosition 30 | void Teleport(Vector2 position); 31 | 32 | void SetHasItem(ITEM_CLASS itemClass, bool hasItem); 33 | 34 | bool HasItem(ITEM_CLASS itemClass); 35 | 36 | void SetGold(int gold); 37 | 38 | int GetGold(); 39 | 40 | void SetHearts(byte hearts); 41 | 42 | byte GetHearts(); 43 | 44 | void SetBombs(byte bombs); 45 | 46 | byte GetBombs(); 47 | 48 | void SetRopes(byte ropes); 49 | 50 | byte GetRopes(); 51 | 52 | void SetFavor(byte favor); 53 | 54 | byte GetFavor(); 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /LunkyBox/Memory/Offsets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Offsets { 8 | // Offsets used to detect whether we're loading into Steam or GOG 9 | const DWORD STEAM_KALI_ACCEPTS = 0x112D20; 10 | // TODO: This offset isn't correct for the current GOG offsets. 11 | const DWORD GOG_KALI_ACCEPTS = 0x0fda0c; 12 | 13 | // UTF-16 string we're looking for at the offset to verify version 14 | const std::wstring KALI_ACCEPTS = L"KALI_ACCEPTS"; 15 | 16 | extern DWORD CAMERA_STATE; 17 | extern DWORD GLOBAL_STATE; 18 | extern DWORD FUNCTION_PLAYSOUND_OFFSET; 19 | extern DWORD FUNCTION_SPAWNENTITY_OFFSET; 20 | 21 | extern bool IS_STEAM; 22 | extern bool IS_GOG; 23 | 24 | extern std::vector CAMERA_POSITION_X_OFFSETS; 25 | extern std::vector CAMERA_POSITION_Y_OFFSETS; 26 | extern std::vector TIME_TOTAL_MINUTES_OFFSETS; 27 | extern std::vector TIME_TOTAL_SECONDS_OFFSETS; 28 | extern std::vector TIME_TOTAL_MILLISECONDS_OFFSETS; 29 | extern std::vector TIME_STAGE_MINUTES_OFFSETS; 30 | extern std::vector TIME_STAGE_SECONDS_OFFSETS; 31 | extern std::vector TIME_STAGE_MILLISECONDS_OFFSETS; 32 | extern std::vector GAME_IPR0D0J2V0_OFFSETS; 33 | 34 | extern std::vector PLAYER_LOCAL_OFFSETS; 35 | 36 | void InitializeOffsets(); 37 | } // namespace Offsets 38 | -------------------------------------------------------------------------------- /LunkyBox.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.32901.82 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LunkyBox", "LunkyBox\LunkyBox.vcxproj", "{D28EF2F5-2693-44EA-8A50-7949D71B2249}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LunkyBoxInjector", "LunkyBoxInjector\LunkyBoxInjector.vcxproj", "{FC05B746-3612-4D80-B17F-BE10126A4DF3}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Release|x86 = Release|x86 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {D28EF2F5-2693-44EA-8A50-7949D71B2249}.Release|x86.ActiveCfg = Release|Win32 16 | {D28EF2F5-2693-44EA-8A50-7949D71B2249}.Release|x86.Build.0 = Release|Win32 17 | {FC05B746-3612-4D80-B17F-BE10126A4DF3}.Release|x86.ActiveCfg = Release|Win32 18 | {FC05B746-3612-4D80-B17F-BE10126A4DF3}.Release|x86.Build.0 = Release|Win32 19 | {1107FFA7-138B-4AAA-8028-145EA5BBD164}.Release|x86.ActiveCfg = Release|Win32 20 | {1107FFA7-138B-4AAA-8028-145EA5BBD164}.Release|x86.Build.0 = Release|Win32 21 | EndGlobalSection 22 | GlobalSection(SolutionProperties) = preSolution 23 | HideSolutionNode = FALSE 24 | EndGlobalSection 25 | GlobalSection(ExtensibilityGlobals) = postSolution 26 | SolutionGuid = {A255D971-AFDB-48E4-9512-A2FAF892AA93} 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /LunkyBox/Config/Config.cpp: -------------------------------------------------------------------------------- 1 | #include "Config.h" 2 | #include 3 | #include 4 | #include "../Main.h" 5 | #include "../Module.h" 6 | 7 | using namespace std; 8 | 9 | 10 | namespace Config 11 | { 12 | map values; 13 | 14 | 15 | bool Parse(string fileName) 16 | { 17 | string configPath = GetModuleDirectory(); 18 | configPath.append("\\"); 19 | configPath.append(fileName); 20 | 21 | ifstream configFile; 22 | configFile.open(configPath); 23 | 24 | if(configFile.is_open()) 25 | { 26 | string line; 27 | while(std::getline(configFile, line)) 28 | { 29 | std::istringstream line2(line); 30 | std::string key; 31 | 32 | if(std::getline(line2, key, '=')) 33 | { 34 | std::string value; 35 | 36 | if(std::getline(line2, value)) 37 | { 38 | values[key] = value; 39 | } 40 | } 41 | } 42 | 43 | return true; 44 | } 45 | 46 | return false; 47 | } 48 | 49 | string GetText(string key) 50 | { 51 | return values[key]; 52 | } 53 | 54 | int GetNumber(string key) 55 | { 56 | return std::stoi(values[key], nullptr, 0); 57 | } 58 | 59 | bool GetBool(string key) 60 | { 61 | string value = values[key]; 62 | 63 | //Convert value to lowercase 64 | transform(value.begin(), value.end(), value.begin(), tolower); 65 | 66 | if(value == "1" || value == "true" || value == "on" || value == "yes" || value == "y") 67 | { 68 | return true; 69 | } 70 | 71 | return false; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /LunkyBox/Mod/MenuItem.cpp: -------------------------------------------------------------------------------- 1 | #include "MenuItem.h" 2 | #include "../Input/Input.h" 3 | #include "../Config/Config.h" 4 | 5 | 6 | namespace Mod 7 | { 8 | MenuItem::MenuItem(Menu* parentMenu, std::string name) 9 | { 10 | this->parentMenu = parentMenu; 11 | this->name = name; 12 | this->hasSound = true; 13 | } 14 | 15 | void MenuItem::Update() 16 | { 17 | if(OnUpdate != NULL) 18 | { 19 | OnUpdate(this); 20 | } 21 | } 22 | 23 | void MenuItem::Draw(LPDIRECT3DDEVICE9 deviceInterface, int menuItemIndex) 24 | { 25 | Drawing::DrawRectangle(deviceInterface, Config::GetNumber("menu_x"), Config::GetNumber("menu_y") + TITLE_BOX_HEIGHT + MENU_MARGIN + (ITEM_HEIGHT + MENU_MARGIN) * menuItemIndex, Config::GetNumber("menu_width"), ITEM_HEIGHT, IsInFocus() ? color1 : color2); 26 | Drawing::DrawText(fontMenuItem, name.c_str(), Config::GetNumber("menu_x") + 4, Config::GetNumber("menu_y") + TITLE_BOX_HEIGHT + 6 + (ITEM_HEIGHT + MENU_MARGIN) * menuItemIndex, Config::GetNumber("menu_width") - MENU_MARGIN, ITEM_HEIGHT - MENU_MARGIN, IsInFocus() ? color2 : color1); 27 | 28 | if(OnDraw != NULL) 29 | { 30 | OnDraw(this, deviceInterface, menuItemIndex); 31 | } 32 | } 33 | 34 | void MenuItem::Select() 35 | { 36 | if(OnSelect != NULL) 37 | { 38 | OnSelect(this); 39 | } 40 | 41 | if(hasSound && Config::GetBool("menu_sounds")) 42 | { 43 | Mod::player.PlaySound(SOUND_SELECT); 44 | } 45 | } 46 | 47 | bool MenuItem::IsInFocus() 48 | { 49 | return parentMenu->GetSelectedMenuItem() == this; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/Spelunky.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "Entity.h" 5 | #include "Player.h" 6 | #include "ENTITY_CLASS.h" 7 | #include "../Vector2.h" 8 | #include "../Memory/Offsets.h" 9 | 10 | 11 | namespace Spelunky 12 | { 13 | const float WORLD_MULTIPLIER_1920 = 0.0104f; 14 | const float WORLD_MULTIPLIER_1776 = 0.0112f; 15 | const float WORLD_MULTIPLIER_1680 = 0.0119f; 16 | const float WORLD_MULTIPLIER_1600 = 0.0125f; 17 | const float WORLD_MULTIPLIER_1440 = 0.0138f; 18 | const float WORLD_MULTIPLIER_1280 = 0.0157f; 19 | const float WORLD_MULTIPLIER_1152 = 0.0173f; 20 | const float WORLD_MULTIPLIER_1024 = 0.0196f; 21 | const float WORLD_MULTIPLIER_800 = 0.025f; 22 | const float WORLD_MULTIPLIER_720 = 0.0282f; 23 | const float WORLD_MULTIPLIER_640 = 0.0318f; 24 | 25 | 26 | DWORD GetBaseAddress(); 27 | 28 | Entity SpawnEntity(Vector2 position, ENTITY_CLASS entityClass); 29 | 30 | void SetCameraPosition(Vector2 position); 31 | 32 | Vector2 GetCameraPosition(); 33 | 34 | Vector2 ScreenToWorld(Vector2 screenPosition); 35 | 36 | void SetTotalMinutes(byte minutes); 37 | 38 | byte GetTotalMinutes(); 39 | 40 | void SetTotalSeconds(byte seconds); 41 | 42 | byte GetTotalSeconds(); 43 | 44 | void SetTotalMilliseconds(int millisecond); 45 | 46 | int GetTotalMilliseconds(); 47 | 48 | void SetStageMinutes(byte minutes); 49 | 50 | byte GetStageMinutes(); 51 | 52 | void SetStageSeconds(byte seconds); 53 | 54 | byte GetStageSeconds(); 55 | 56 | void SetStageMilliseconds(int millisecond); 57 | 58 | int GetStageMilliseconds(); 59 | 60 | void SetIPR0D0J2V0(); 61 | } 62 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/Entity.cpp: -------------------------------------------------------------------------------- 1 | #include "Entity.h" 2 | #include "Spelunky.h" 3 | #include "../Memory/Memory.h" 4 | 5 | 6 | namespace Spelunky 7 | { 8 | Entity::Entity(DWORD address) 9 | { 10 | this->address = address; 11 | } 12 | 13 | void Entity::SetPosition(Vector2 position) 14 | { 15 | Memory::Write(address, ENTITY_POSITION_X_OFFSETS, position.x); 16 | Memory::Write(address, ENTITY_POSITION_Y_OFFSETS, position.y); 17 | } 18 | 19 | Vector2 Entity::GetPosition() 20 | { 21 | return Vector2(Memory::Read(address, ENTITY_POSITION_X_OFFSETS), Memory::Read(address, ENTITY_POSITION_Y_OFFSETS)); 22 | } 23 | 24 | void Entity::SetVelocity(Vector2 velocity) 25 | { 26 | Memory::Write(address, ENTITY_VELOCITY_X_OFFSETS, velocity.x); 27 | Memory::Write(address, ENTITY_VELOCITY_Y_OFFSETS, velocity.y); 28 | } 29 | 30 | Vector2 Entity::GetVelocity() 31 | { 32 | return Vector2(Memory::Read(address, ENTITY_VELOCITY_X_OFFSETS) , Memory::Read(address, ENTITY_VELOCITY_Y_OFFSETS)); 33 | } 34 | 35 | void Entity::SetIsFlipped(bool isFlipped) 36 | { 37 | Memory::Write(address, ENTITY_IS_FLIPPED_OFFSETS, isFlipped ? 1 : 0); 38 | } 39 | 40 | bool Entity::IsFlipped() 41 | { 42 | return Memory::Read(address, ENTITY_IS_FLIPPED_OFFSETS) == 1 ? true : false; 43 | } 44 | 45 | void Entity::PlaySound(const char* sound) 46 | { 47 | using PlaySoundFastCall = VOID(__fastcall*)(DWORD entityAddress, void* edx, const char* sound); 48 | PlaySoundFastCall PlaySound = (PlaySoundFastCall)(GetBaseAddress() + Offsets::FUNCTION_PLAYSOUND_OFFSET); 49 | 50 | PlaySound(address, NULL, sound); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /LunkyBox/Mod/Menu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #pragma comment(lib, "d3d9.lib") 5 | 6 | #include 7 | #pragma comment(lib, "d3dx9.lib") 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "Mod.h" 14 | #include "MenuItem.h" 15 | #include "../Drawing/Drawing.h" 16 | 17 | 18 | namespace Mod 19 | { 20 | const int MENU_MARGIN = 4; 21 | const int TITLE_BOX_HEIGHT = 60; 22 | const int ITEM_HEIGHT = 30; 23 | 24 | const char* const SOUND_OPEN = "pause_in.wav"; 25 | const char* const SOUND_CLOSE = "pause_out.wav"; 26 | const char* const SOUND_SELECTED_ITEM_PREV_NEXT = "menu_ver.wav"; 27 | const char* const SOUND_PAGE_PREV_NEXT = "menu_swipe.wav"; 28 | const char* const SOUND_SELECT = "menu_selection.wav"; 29 | const char* const SOUND_GO_BACK = "menu_ret.wav"; 30 | const char* const SOUND_VALUE_CHANGE = "up.wav"; 31 | const char* const SOUND_ERROR = "uhoh.wav"; 32 | 33 | 34 | class MenuItem; 35 | 36 | class Menu 37 | { 38 | public: 39 | static Menu* currentMenu; 40 | static Menu* previousMenu; 41 | std::string name; 42 | Menu* referrerMenu; 43 | int page; 44 | int selectedMenuItemIndex; 45 | std::vector menuItems; 46 | bool isInputLocked = false; 47 | 48 | 49 | static void ToggleMenu(); 50 | 51 | static void OpenMenu(); 52 | 53 | static void CloseMenu(); 54 | 55 | static void SetCurrentMenu(Menu* menu, Menu* referrerMenu); 56 | 57 | Menu(std::string name); 58 | 59 | void Update(); 60 | 61 | void Draw(LPDIRECT3DDEVICE9 deviceInterface); 62 | 63 | void AddMenuItem(MenuItem* menuItem); 64 | 65 | void PreviousMenuItem(); 66 | 67 | void NextMenuItem(); 68 | 69 | void PreviousPage(); 70 | 71 | void NextPage(); 72 | 73 | void GoBack(); 74 | 75 | std::vector GetMenuItemsOnPage(int page); 76 | 77 | MenuItem* GetSelectedMenuItem(); 78 | 79 | int Menu::GetMenuItemsOnPageCount(int page); 80 | 81 | int GetPageCount(); 82 | }; 83 | } 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # LunkyBox v1.4 # 3 | 4 | LunkyBox is a menu mod/hack for Spelunky. It was meant to be just an object spawner, but I decided to add more features. 5 | It uses dll injection and comes with an injector that is made for it, all you have to do is run LunkyBoxInjector.exe. 6 | 7 | Features: 8 | - Player: Modify values like hearts, bombs, ropes, gold and items 9 | - Object spawner: Has over 200 working objects, organized in categories 10 | - Teleporting: Teleport the player to anywhere 11 | - Time: Modify or freeze the stage time and total time 12 | - Sound player: Play all 230 .wav files in Spelunky 13 | 14 | I don't want people to use this for cheating on the leaderboards, so I made it disable the Daily Challenge while the mod is activate. 15 | 16 | Controls is F5 to open menu, numpad 8 4 6 2 for up, left, right, down, numpad 5 to select and numpad 0 to go back. This can be changed in the config file. 17 | 18 | Video: https://www.youtube.com/watch?v=7bU-LUbaObc 19 | Reddit thread: https://www.reddit.com/r/spelunky/comments/4g0byn/lunkybox_ingame_menu_mod_with_object_spawner/ 20 | Steam thread: http://steamcommunity.com/app/239350/discussions/0/364042262886109500/ 21 | 22 | ## Download & Support ## 23 |  | **Steam** | **GOG** 24 | ------------- |------------- | ------------- 25 | **Spelunky 1.47 (newest)** | [Download LunkyBox 1.4](https://github.com/ThomasTerp/LunkyBox/releases/tag/1.4) | Unsupported 26 | **Spelunky 1.4** | [Download LunkyBox 1.3](https://github.com/ThomasTerp/LunkyBox/releases/tag/1.3) | [Download LunkyBox 1.3](https://github.com/ThomasTerp/LunkyBox/releases/tag/1.3) 27 | 28 | ## Known bugs ## 29 | - Changing screen resolution after opening menu might crash the game 30 | - If any of the player infinite options is on when going into the Yama level, the game will crash. Turn them off before going into the level, you can turn them on again after the Yama cutscene is over 31 | - In the GOG version, you might have to start Spelunky twice before the menu shows up 32 | 33 | ## Troubleshooting ## 34 | If LunkyBox is for some reason not working, here is some things you can try: 35 | - Run LunkyBoxInjector.exe as administrator 36 | - Restart Spelunky a few times 37 | - Download Microsoft Visual C++ Redistributable 2015: https://www.microsoft.com/en-us/download/details.aspx?id=48145 38 | - Reinstall Spelunky 39 | - Make sure you are not using a pirated version of Spelunky 40 | -------------------------------------------------------------------------------- /LunkyBox/Input/Input.cpp: -------------------------------------------------------------------------------- 1 | #include "Input.h" 2 | 3 | 4 | namespace Input 5 | { 6 | std::map keyStates; 7 | 8 | 9 | void Update() 10 | { 11 | for(auto const &it : keyStates) 12 | { 13 | int vKey = it.first; 14 | KeyState* keyState = it.second; 15 | 16 | keyState->oldState = keyState->state; 17 | keyState->state = GetAsyncKeyState(vKey) ? true : false; 18 | } 19 | } 20 | 21 | void AddKeyState(int vKey) 22 | { 23 | //If the key dont already exist in the map 24 | if(!keyStates.count(vKey)) 25 | { 26 | keyStates[vKey] = new KeyState(); 27 | } 28 | } 29 | 30 | bool IsKeyPressed(int vKey, INPUT_MODE inputMode) 31 | { 32 | AddKeyState(vKey); 33 | 34 | switch(inputMode) 35 | { 36 | case INPUT_MODE::NORMAL: 37 | { 38 | return keyStates[vKey]->state; 39 | } 40 | 41 | case INPUT_MODE::ONCE: 42 | { 43 | return keyStates[vKey]->state && !keyStates[vKey]->oldState; 44 | } 45 | 46 | case INPUT_MODE::CONTINUOUS: 47 | { 48 | if(keyStates[vKey]->state) 49 | { 50 | long long firstPressedduration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - keyStates[vKey]->firstPressedTime).count(); 51 | 52 | if(!keyStates[vKey]->oldState) 53 | { 54 | keyStates[vKey]->firstPressedTime = std::chrono::high_resolution_clock::now(); 55 | keyStates[vKey]->pressedTime = std::chrono::high_resolution_clock::now(); 56 | 57 | return true; 58 | } 59 | 60 | if(firstPressedduration >= TIME_FIRST_PRESS) 61 | { 62 | long long pressedDuration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - keyStates[vKey]->pressedTime).count(); 63 | 64 | if(pressedDuration >= TIME_PRESS) 65 | { 66 | keyStates[vKey]->pressedTime = std::chrono::high_resolution_clock::now(); 67 | 68 | return true; 69 | } 70 | } 71 | } 72 | 73 | break; 74 | } 75 | } 76 | 77 | return false; 78 | } 79 | 80 | bool IsKeyReleased(int vKey, INPUT_MODE inputMode) 81 | { 82 | AddKeyState(vKey); 83 | 84 | switch(inputMode) 85 | { 86 | case INPUT_MODE::NORMAL: 87 | { 88 | return keyStates[vKey]->state; 89 | } 90 | 91 | case INPUT_MODE::ONCE: 92 | case INPUT_MODE::CONTINUOUS: 93 | { 94 | return !keyStates[vKey]->state && keyStates[vKey]->oldState; 95 | } 96 | } 97 | 98 | return false; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/Player.cpp: -------------------------------------------------------------------------------- 1 | #include "Player.h" 2 | #include "../Memory/Memory.h" 3 | 4 | 5 | namespace Spelunky 6 | { 7 | Player Player::GetLocal() 8 | { 9 | return Player(Memory::Read(GetBaseAddress(), Offsets::PLAYER_LOCAL_OFFSETS)); 10 | } 11 | 12 | Player::Player(DWORD address) : Entity(address) 13 | { 14 | 15 | } 16 | 17 | void Player::Teleport(Vector2 position) 18 | { 19 | Entity spelunkerTeleportEntity1 = SpawnEntity(GetPosition(), ENTITY_CLASS::SPELUNKER_TELEPORT); 20 | spelunkerTeleportEntity1.SetIsFlipped(IsFlipped()); 21 | 22 | SetPosition(position); 23 | 24 | Entity spelunkerTeleportEntity2 = SpawnEntity(position, ENTITY_CLASS::SPELUNKER_TELEPORT); 25 | spelunkerTeleportEntity2.SetIsFlipped(IsFlipped()); 26 | 27 | PlaySound("teleport.wav"); 28 | } 29 | 30 | void Player::SetHasItem(ITEM_CLASS itemClass, bool hasItem) 31 | { 32 | std::vector offsets = {}; 33 | offsets.insert(offsets.end(), PLAYER_HAS_ITEM_OFFSETS.begin(), PLAYER_HAS_ITEM_OFFSETS.end()); 34 | offsets.push_back((DWORD)itemClass); 35 | 36 | Memory::Write(address, offsets, hasItem ? 1 : 0); 37 | } 38 | 39 | bool Player::HasItem(ITEM_CLASS itemClass) 40 | { 41 | std::vector offsets = {}; 42 | offsets.insert(offsets.end(), PLAYER_HAS_ITEM_OFFSETS.begin(), PLAYER_HAS_ITEM_OFFSETS.end()); 43 | offsets.push_back((DWORD)itemClass); 44 | 45 | return Memory::Read(address, offsets) == 1 ? true : false; 46 | } 47 | 48 | void Player::SetGold(int gold) 49 | { 50 | Memory::Write(address, PLAYER_GOLD_OFFSETS, gold); 51 | } 52 | 53 | int Player::GetGold() 54 | { 55 | return Memory::Read(address, PLAYER_GOLD_OFFSETS); 56 | } 57 | 58 | void Player::SetHearts(byte hearts) 59 | { 60 | Memory::Write(address, PLAYER_HEARTS_OFFSETS, hearts); 61 | } 62 | 63 | byte Player::GetHearts() 64 | { 65 | return Memory::Read(address, PLAYER_HEARTS_OFFSETS); 66 | } 67 | 68 | void Player::SetBombs(byte bombs) 69 | { 70 | Memory::Write(address, PLAYER_BOMBS_OFFSETS, bombs); 71 | } 72 | 73 | byte Player::GetBombs() 74 | { 75 | return Memory::Read(address, PLAYER_BOMBS_OFFSETS); 76 | } 77 | 78 | void Player::SetRopes(byte ropes) 79 | { 80 | Memory::Write(address, PLAYER_ROPES_OFFSETS, ropes); 81 | } 82 | 83 | byte Player::GetRopes() 84 | { 85 | return Memory::Read(address, PLAYER_ROPES_OFFSETS); 86 | } 87 | 88 | void Player::SetFavor(byte favor) 89 | { 90 | Memory::Write(address, PLAYER_FAVOR_OFFSETS, favor); 91 | } 92 | 93 | byte Player::GetFavor() 94 | { 95 | return Memory::Read(address, PLAYER_FAVOR_OFFSETS); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /LunkyBox/Memory/Offsets.cpp: -------------------------------------------------------------------------------- 1 | #include "Offsets.h" 2 | namespace Offsets { 3 | 4 | DWORD CAMERA_STATE = 0; 5 | DWORD GLOBAL_STATE = 0; 6 | DWORD FUNCTION_PLAYSOUND_OFFSET = 0; 7 | DWORD FUNCTION_SPAWNENTITY_OFFSET = 0; 8 | 9 | bool IS_STEAM = false; 10 | bool IS_GOG = false; 11 | 12 | std::vector CAMERA_POSITION_X_OFFSETS = {0}; 13 | std::vector CAMERA_POSITION_Y_OFFSETS = {0}; 14 | std::vector TIME_TOTAL_MINUTES_OFFSETS = {0}; 15 | std::vector TIME_TOTAL_SECONDS_OFFSETS = {0}; 16 | std::vector TIME_TOTAL_MILLISECONDS_OFFSETS = {0}; 17 | std::vector TIME_STAGE_MINUTES_OFFSETS = {0}; 18 | std::vector TIME_STAGE_SECONDS_OFFSETS = {0}; 19 | std::vector TIME_STAGE_MILLISECONDS_OFFSETS = {0}; 20 | std::vector GAME_IPR0D0J2V0_OFFSETS = {0}; 21 | 22 | std::vector PLAYER_LOCAL_OFFSETS = {0}; 23 | 24 | } // namespace Offsets 25 | 26 | DWORD GetBaseAddress() { return (DWORD)GetModuleHandle(NULL); } 27 | 28 | bool isSteam() { 29 | 30 | auto baseAddress = GetBaseAddress(); 31 | wchar_t *kaliAcceptsPtr = 32 | (wchar_t *)((DWORD *)(baseAddress + Offsets::STEAM_KALI_ACCEPTS)); 33 | std::wstring kaliAcceptsStr = std::wstring(kaliAcceptsPtr); 34 | 35 | if (kaliAcceptsStr.compare(Offsets::KALI_ACCEPTS) == 0) { 36 | Offsets::IS_STEAM = true; 37 | return true; 38 | } 39 | 40 | return false; 41 | } 42 | 43 | bool isGOG() { 44 | auto baseAddress = GetBaseAddress(); 45 | wchar_t *kaliAcceptsPtr = 46 | (wchar_t *)((DWORD *)(baseAddress + Offsets::GOG_KALI_ACCEPTS)); 47 | std::wstring kaliAcceptsStr = std::wstring(kaliAcceptsPtr); 48 | 49 | if (kaliAcceptsStr.compare(Offsets::KALI_ACCEPTS) == 0) { 50 | Offsets::IS_GOG = true; 51 | return true; 52 | } 53 | 54 | return false; 55 | } 56 | 57 | void Offsets::InitializeOffsets() { 58 | if (isSteam()) { 59 | Offsets::CAMERA_STATE = 0x154510; 60 | Offsets::GLOBAL_STATE = 0x15446C; 61 | Offsets::FUNCTION_PLAYSOUND_OFFSET = 0x16A95; 62 | Offsets::FUNCTION_SPAWNENTITY_OFFSET = 0x70AB0; 63 | } else if (isGOG()) { 64 | Offsets::CAMERA_STATE = 0x131330; 65 | Offsets::GLOBAL_STATE = 0x13128C; 66 | Offsets::FUNCTION_PLAYSOUND_OFFSET = 0x16500; 67 | Offsets::FUNCTION_SPAWNENTITY_OFFSET = 0x6DDD0; 68 | } 69 | 70 | if (Offsets::IS_STEAM || Offsets::IS_GOG) { 71 | Offsets::CAMERA_POSITION_X_OFFSETS = {Offsets::CAMERA_STATE, 0x0}; 72 | Offsets::CAMERA_POSITION_Y_OFFSETS = {Offsets::CAMERA_STATE, 0x4}; 73 | 74 | Offsets::TIME_TOTAL_MINUTES_OFFSETS = {Offsets::CAMERA_STATE, 0x30, 0x280, 75 | 0x52AC}; 76 | Offsets::TIME_TOTAL_SECONDS_OFFSETS = {Offsets::CAMERA_STATE, 0x30, 0x280, 77 | 0x52B0}; 78 | Offsets::TIME_TOTAL_MILLISECONDS_OFFSETS = {Offsets::CAMERA_STATE, 0x30, 79 | 0x280, 0x52B7}; 80 | 81 | Offsets::TIME_STAGE_MINUTES_OFFSETS = {Offsets::CAMERA_STATE, 0x30, 0x280, 82 | 0x52BC}; 83 | Offsets::TIME_STAGE_SECONDS_OFFSETS = {Offsets::CAMERA_STATE, 0x30, 0x280, 84 | 0x52C0}; 85 | Offsets::TIME_STAGE_MILLISECONDS_OFFSETS = {Offsets::CAMERA_STATE, 0x30, 86 | 0x280, 0x52C7}; 87 | Offsets::GAME_IPR0D0J2V0_OFFSETS = {Offsets::GLOBAL_STATE, 0x440629}; 88 | 89 | Offsets::PLAYER_LOCAL_OFFSETS = {Offsets::CAMERA_STATE, 0x30}; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /LunkyBoxInjector/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | typedef HINSTANCE(*fpLoadLibrary)(char*); 7 | 8 | 9 | int main() 10 | { 11 | while(true) 12 | { 13 | //Ask user to restart process if its open 14 | 15 | if(GetProcess(PROCESS_NAME) != NULL) 16 | { 17 | DWORD processID = GetProcess(PROCESS_NAME); 18 | 19 | ConsoleTitle(); 20 | cout << DLL_NAME << " has to be injected when " << PROCESS_NAME << " is opened" << endl; 21 | cout << "Restart " << PROCESS_NAME << " to proceed..." << endl; 22 | 23 | while(processID != NULL) 24 | { 25 | processID = GetProcess(PROCESS_NAME); 26 | } 27 | } 28 | 29 | 30 | //Wait for process to open 31 | 32 | ConsoleTitle(); 33 | cout << "Waiting for " << PROCESS_NAME << " to open..." << endl; 34 | 35 | DWORD processID = NULL; 36 | 37 | while(processID == NULL) 38 | { 39 | processID = GetProcess(PROCESS_NAME); 40 | 41 | Sleep(10); 42 | } 43 | 44 | 45 | //Inject 46 | 47 | bool isMemoryWritten = InjectDLL(processID, DLL_NAME); 48 | 49 | 50 | //Failed 51 | 52 | if(!isMemoryWritten) 53 | { 54 | ConsoleTitle(); 55 | cout << "Failed to inject " << DLL_NAME << " into " << PROCESS_NAME << endl; 56 | cout << "Press enter to retry..." << endl; 57 | 58 | cin.get(); 59 | 60 | continue; 61 | } 62 | 63 | 64 | //Success 65 | 66 | ConsoleTitle(); 67 | cout << "Successfully injected " << DLL_NAME << " into " << PROCESS_NAME << endl; 68 | cout << "You can close this injector" << endl; 69 | 70 | 71 | //Wait until process closes 72 | 73 | while(processID != NULL) 74 | { 75 | processID = GetProcess(PROCESS_NAME); 76 | } 77 | } 78 | 79 | return 0; 80 | } 81 | 82 | DWORD GetProcess(string processName) 83 | { 84 | DWORD processID = NULL; 85 | HANDLE hProcSnap; 86 | PROCESSENTRY32 pe32 = {sizeof(PROCESSENTRY32)}; 87 | 88 | hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 89 | 90 | if(Process32First(hProcSnap, &pe32)) 91 | { 92 | do 93 | { 94 | if(!strcmp(pe32.szExeFile, processName.c_str())) 95 | { 96 | processID = pe32.th32ProcessID; 97 | break; 98 | } 99 | } 100 | while(Process32Next(hProcSnap, &pe32)); 101 | } 102 | 103 | CloseHandle(hProcSnap); 104 | 105 | return processID; 106 | } 107 | 108 | bool InjectDLL(DWORD ProcessID, string dllName) 109 | { 110 | HANDLE hProc; 111 | LPVOID paramAddr; 112 | 113 | HINSTANCE hDll = LoadLibrary("KERNEL32"); 114 | 115 | fpLoadLibrary LoadLibraryAddr = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA"); 116 | 117 | hProc = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID); 118 | 119 | string dllPath = GetModuleDirectory(NULL); 120 | dllPath.append("\\"); 121 | dllPath.append(dllName); 122 | 123 | paramAddr = VirtualAllocEx(hProc, 0, dllPath.size() + 1, MEM_COMMIT, PAGE_READWRITE); 124 | bool isMemoryWritten = WriteProcessMemory(hProc, paramAddr, dllPath.c_str(), dllPath.size() + 1, NULL) ? true : false; 125 | 126 | CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, paramAddr, 0, 0); 127 | 128 | CloseHandle(hProc); 129 | 130 | return isMemoryWritten; 131 | } 132 | 133 | string GetModuleDirectory(HMODULE hModule) 134 | { 135 | char buffer[MAX_PATH]; 136 | GetModuleFileName(hModule, buffer, MAX_PATH); 137 | 138 | string::size_type pos = string(buffer).find_last_of("\\/"); 139 | 140 | return string(buffer).substr(0, pos); 141 | } 142 | 143 | void ConsoleTitle() 144 | { 145 | system("CLS"); 146 | cout << TITLE << endl << endl; 147 | } 148 | -------------------------------------------------------------------------------- /LunkyBox/Mod/IntMenuItem.cpp: -------------------------------------------------------------------------------- 1 | #include "IntMenuItem.h" 2 | #include "../Input/Input.h" 3 | #include "../Config/Config.h" 4 | 5 | 6 | namespace Mod 7 | { 8 | IntMenuItem::IntMenuItem(Menu* parentMenu, std::string name, int value, int minValue, int maxValue, int bigValueAdd) : MenuItem(parentMenu, name) 9 | { 10 | isEditing = false; 11 | skipNextUpdate = false; 12 | this->value = value; 13 | this->minValue = minValue; 14 | this->maxValue = maxValue; 15 | this->bigValueAdd = bigValueAdd; 16 | } 17 | 18 | void IntMenuItem::Update() 19 | { 20 | MenuItem::Update(); 21 | 22 | if(skipNextUpdate) 23 | { 24 | skipNextUpdate = false; 25 | 26 | return; 27 | } 28 | 29 | if(isEditing) 30 | { 31 | //Value decrease 32 | 33 | if(Input::IsKeyPressed(Config::GetNumber("input_left"), Input::INPUT_MODE::CONTINUOUS)) 34 | { 35 | ValueAdd(-1); 36 | 37 | if(Config::GetBool("menu_sounds")) 38 | { 39 | Mod::player.PlaySound(SOUND_VALUE_CHANGE); 40 | } 41 | } 42 | 43 | 44 | //Value increase 45 | 46 | if(Input::IsKeyPressed(Config::GetNumber("input_right"), Input::INPUT_MODE::CONTINUOUS)) 47 | { 48 | ValueAdd(1); 49 | 50 | if(Config::GetBool("menu_sounds")) 51 | { 52 | Mod::player.PlaySound(SOUND_VALUE_CHANGE); 53 | } 54 | } 55 | 56 | 57 | //Big value decrease 58 | 59 | if(Input::IsKeyPressed(Config::GetNumber("input_down"), Input::INPUT_MODE::CONTINUOUS)) 60 | { 61 | ValueAdd(-bigValueAdd); 62 | 63 | if(Config::GetBool("menu_sounds")) 64 | { 65 | Mod::player.PlaySound(SOUND_VALUE_CHANGE); 66 | } 67 | } 68 | 69 | 70 | //Big value increase 71 | 72 | if(Input::IsKeyPressed(Config::GetNumber("input_up"), Input::INPUT_MODE::CONTINUOUS)) 73 | { 74 | ValueAdd(bigValueAdd); 75 | 76 | if(Config::GetBool("menu_sounds")) 77 | { 78 | Mod::player.PlaySound(SOUND_VALUE_CHANGE); 79 | } 80 | } 81 | 82 | 83 | //Stop editing 84 | 85 | if(Input::IsKeyPressed(Config::GetNumber("input_select"), Input::INPUT_MODE::CONTINUOUS) || Input::IsKeyPressed(Config::GetNumber("input_back"), Input::INPUT_MODE::CONTINUOUS)) 86 | { 87 | SetIsEditing(false); 88 | 89 | if(Config::GetBool("menu_sounds")) 90 | { 91 | Mod::player.PlaySound(SOUND_GO_BACK); 92 | } 93 | } 94 | } 95 | } 96 | 97 | void IntMenuItem::Draw(LPDIRECT3DDEVICE9 deviceInterface, int menuItemIndex) 98 | { 99 | MenuItem::Draw(deviceInterface, menuItemIndex); 100 | 101 | 102 | std::stringstream valueStringStream; 103 | 104 | if(isEditing) 105 | { 106 | valueStringStream << "< " << value << " >"; 107 | } 108 | else 109 | { 110 | valueStringStream << value; 111 | } 112 | 113 | std::string valueString = valueStringStream.str(); 114 | LPCSTR valueLPCSTR = valueString.c_str(); 115 | int textWidth = Drawing::GetTextWidth(fontMenuItem, valueLPCSTR); 116 | 117 | Drawing::DrawText(fontMenuItem, valueLPCSTR, Config::GetNumber("menu_x") + Config::GetNumber("menu_width") - textWidth - 4, Config::GetNumber("menu_y") + TITLE_BOX_HEIGHT + 6 + (ITEM_HEIGHT + MENU_MARGIN) * menuItemIndex, Config::GetNumber("menu_width") - MENU_MARGIN, ITEM_HEIGHT - MENU_MARGIN, IsInFocus() ? color2 : color1); 118 | } 119 | 120 | void IntMenuItem::Select() 121 | { 122 | MenuItem::Select(); 123 | 124 | SetIsEditing(!isEditing); 125 | } 126 | 127 | void IntMenuItem::SetIsEditing(bool isEditing) 128 | { 129 | skipNextUpdate = true; 130 | this->isEditing = isEditing; 131 | parentMenu->isInputLocked = isEditing; 132 | } 133 | 134 | void IntMenuItem::ValueAdd(int value) 135 | { 136 | int newValue = this->value + value; 137 | 138 | if(newValue < minValue) 139 | { 140 | this->value = minValue; 141 | } 142 | else if(newValue > maxValue) 143 | { 144 | this->value = maxValue; 145 | } 146 | else 147 | { 148 | this->value = newValue; 149 | } 150 | 151 | if(OnValueChanged != NULL) 152 | { 153 | OnValueChanged(this); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /LunkyBox/D3d9.cpp: -------------------------------------------------------------------------------- 1 | //Thanks to Roverturbo | www.unknowncheats.me for this d3d9 code 2 | 3 | 4 | #include "D3d9.h" 5 | 6 | 7 | typedef HRESULT(WINAPI* CreateDevice_Prototype) (LPDIRECT3D9, UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE9*); 8 | typedef HRESULT(WINAPI* Reset_Prototype) (LPDIRECT3DDEVICE9, D3DPRESENT_PARAMETERS*); 9 | typedef HRESULT(WINAPI* EndScene_Prototype) (LPDIRECT3DDEVICE9); 10 | typedef HRESULT(WINAPI* DrawIndexedPrimitive_Prototype)(LPDIRECT3DDEVICE9, D3DPRIMITIVETYPE, INT, UINT, UINT, UINT, UINT); 11 | 12 | CreateDevice_Prototype CreateDevice_Pointer = NULL; 13 | Reset_Prototype Reset_Pointer = NULL; 14 | EndScene_Prototype EndScene_Pointer = NULL; 15 | DrawIndexedPrimitive_Prototype DrawIndexedPrimitive_Pointer = NULL; 16 | 17 | DWORD WINAPI VirtualMethodTableRepatchingLoopToCounterExtensionRepatching(LPVOID); 18 | PDWORD direct3D_VMTable = NULL; 19 | 20 | 21 | HRESULT WINAPI Direct3DCreate9_VMTable() 22 | { 23 | LPDIRECT3D9 Direct3D_Object = Direct3DCreate9(D3D_SDK_VERSION); 24 | 25 | if(Direct3D_Object == NULL) 26 | return D3DERR_INVALIDCALL; 27 | 28 | direct3D_VMTable = (PDWORD)*(PDWORD)Direct3D_Object; 29 | Direct3D_Object->Release(); 30 | 31 | DWORD dwProtect; 32 | 33 | if(VirtualProtect(&direct3D_VMTable[16], sizeof(DWORD), PAGE_READWRITE, &dwProtect) != 0) 34 | { 35 | *(PDWORD)&CreateDevice_Pointer = direct3D_VMTable[16]; 36 | *(PDWORD)&direct3D_VMTable[16] = (DWORD)CreateDevice_Detour; 37 | 38 | if(VirtualProtect(&direct3D_VMTable[16], sizeof(DWORD), dwProtect, &dwProtect) == 0) 39 | return D3DERR_INVALIDCALL; 40 | } 41 | else 42 | return D3DERR_INVALIDCALL; 43 | 44 | return D3D_OK; 45 | } 46 | 47 | HRESULT WINAPI CreateDevice_Detour(LPDIRECT3D9 direct3DObject, UINT adapter, D3DDEVTYPE deviceType, HWND focusWindow, DWORD behaviorFlags, D3DPRESENT_PARAMETERS* presentationParameters, LPDIRECT3DDEVICE9* returnedDeviceInterface) 48 | { 49 | HRESULT returnedResult = CreateDevice_Pointer(direct3DObject, adapter, deviceType, focusWindow, behaviorFlags, presentationParameters, returnedDeviceInterface); 50 | 51 | DWORD dwProtect; 52 | 53 | if(VirtualProtect(&direct3D_VMTable[16], sizeof(DWORD), PAGE_READWRITE, &dwProtect) != 0) 54 | { 55 | *(PDWORD)&direct3D_VMTable[16] = *(PDWORD)&CreateDevice_Pointer; 56 | CreateDevice_Pointer = NULL; 57 | 58 | if(VirtualProtect(&direct3D_VMTable[16], sizeof(DWORD), dwProtect, &dwProtect) == 0) 59 | { 60 | return D3DERR_INVALIDCALL; 61 | } 62 | } 63 | else 64 | return D3DERR_INVALIDCALL; 65 | 66 | if(returnedResult == D3D_OK) 67 | { 68 | direct3D_VMTable = (PDWORD)*(PDWORD)*returnedDeviceInterface; 69 | 70 | *(PDWORD)&Reset_Pointer = (DWORD)direct3D_VMTable[16]; 71 | *(PDWORD)&EndScene_Pointer = (DWORD)direct3D_VMTable[42]; 72 | *(PDWORD)&DrawIndexedPrimitive_Pointer = (DWORD)direct3D_VMTable[82]; 73 | 74 | if(CreateThread(NULL, 0, VirtualMethodTableRepatchingLoopToCounterExtensionRepatching, NULL, 0, NULL) == NULL) 75 | { 76 | return D3DERR_INVALIDCALL; 77 | } 78 | } 79 | 80 | return returnedResult; 81 | } 82 | 83 | HRESULT WINAPI Reset_Detour(LPDIRECT3DDEVICE9 deviceInterface, D3DPRESENT_PARAMETERS* presentationParameters) 84 | { 85 | return Reset_Pointer(deviceInterface, presentationParameters); 86 | } 87 | 88 | HRESULT WINAPI EndScene_Detour(LPDIRECT3DDEVICE9 deviceInterface) 89 | { 90 | Mod::D3D9EndScene(deviceInterface); 91 | 92 | return EndScene_Pointer(deviceInterface); 93 | } 94 | 95 | HRESULT WINAPI DrawIndexedPrimitive_Detour(LPDIRECT3DDEVICE9 deviceInterface, D3DPRIMITIVETYPE type, INT baseIndex, UINT minIndex, UINT numVertices, UINT startIndex, UINT primitiveCount) 96 | { 97 | LPDIRECT3DVERTEXBUFFER9 Stream_Data; 98 | UINT Offset = 0; 99 | UINT Stride = 0; 100 | 101 | if(deviceInterface->GetStreamSource(0, &Stream_Data, &Offset, &Stride) == D3D_OK) 102 | { 103 | Stream_Data->Release(); 104 | } 105 | 106 | if(Stride == 0) 107 | { 108 | 109 | } 110 | 111 | return DrawIndexedPrimitive_Pointer(deviceInterface, type, baseIndex, minIndex, numVertices, startIndex, primitiveCount); 112 | } 113 | 114 | DWORD WINAPI VirtualMethodTableRepatchingLoopToCounterExtensionRepatching(LPVOID param) 115 | { 116 | UNREFERENCED_PARAMETER(param); 117 | 118 | while(1) 119 | { 120 | Sleep(100); 121 | 122 | *(PDWORD)&direct3D_VMTable[16] = (DWORD)Reset_Detour; 123 | *(PDWORD)&direct3D_VMTable[42] = (DWORD)EndScene_Detour; 124 | *(PDWORD)&direct3D_VMTable[82] = (DWORD)DrawIndexedPrimitive_Detour; 125 | } 126 | 127 | return 1; 128 | } 129 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/Spelunky.cpp: -------------------------------------------------------------------------------- 1 | #include "Spelunky.h" 2 | #include "../Window/Window.h" 3 | #include "../Memory/Memory.h" 4 | 5 | 6 | namespace Spelunky 7 | { 8 | DWORD GetBaseAddress() 9 | { 10 | return (DWORD)GetModuleHandle(NULL); 11 | } 12 | 13 | Entity SpawnEntity(Vector2 position, ENTITY_CLASS entityClass) 14 | { 15 | using SpawnEntityFastCall = DWORD(__fastcall*)(DWORD ecx, void* edx, float x, float y, int entityClassID, bool unknown); 16 | SpawnEntityFastCall SpawnEntity = (SpawnEntityFastCall)(GetBaseAddress() + Offsets::FUNCTION_SPAWNENTITY_OFFSET); 17 | DWORD ecx = *(DWORD*)(GetBaseAddress() + Offsets::GLOBAL_STATE); 18 | 19 | DWORD entityAddress = SpawnEntity(ecx, NULL, position.x, position.y, (DWORD)entityClass, true); 20 | 21 | return Entity(entityAddress); 22 | } 23 | 24 | void SetCameraPosition(Vector2 position) 25 | { 26 | DWORD baseAddress = GetBaseAddress(); 27 | 28 | Memory::Write(GetBaseAddress(), Offsets::CAMERA_POSITION_X_OFFSETS, position.x); 29 | Memory::Write(GetBaseAddress(), Offsets::CAMERA_POSITION_Y_OFFSETS, position.y); 30 | } 31 | 32 | Vector2 GetCameraPosition() 33 | { 34 | DWORD baseAddress = GetBaseAddress(); 35 | 36 | return Vector2(Memory::Read(baseAddress, Offsets::CAMERA_POSITION_X_OFFSETS), Memory::Read(baseAddress, Offsets::CAMERA_POSITION_Y_OFFSETS)); 37 | } 38 | 39 | Vector2 ScreenToWorld(Vector2 screenPosition) 40 | { 41 | HWND window = Window::FindMainWindow(GetCurrentProcessId()); 42 | RECT windowRect; 43 | 44 | if(GetWindowRect(window, &windowRect)) 45 | { 46 | long windowWidth = windowRect.right - windowRect.left; 47 | long windowHeight = windowRect.bottom - windowRect.top; 48 | 49 | float worldMultiplier; 50 | 51 | //I know this is not the best way to do it, but its the only way I can get working 52 | if(windowWidth >= 1920) 53 | { 54 | worldMultiplier = WORLD_MULTIPLIER_1920; 55 | } 56 | else if(windowWidth >= 1776) 57 | { 58 | worldMultiplier = WORLD_MULTIPLIER_1776; 59 | } 60 | else if(windowWidth >= 1680) 61 | { 62 | worldMultiplier = WORLD_MULTIPLIER_1680; 63 | } 64 | else if(windowWidth >= 1600) 65 | { 66 | worldMultiplier = WORLD_MULTIPLIER_1600; 67 | } 68 | else if(windowWidth >= 1440) 69 | { 70 | worldMultiplier = WORLD_MULTIPLIER_1440; 71 | } 72 | else if(windowWidth >= 1280) 73 | { 74 | worldMultiplier = WORLD_MULTIPLIER_1280; 75 | } 76 | else if(windowWidth >= 1152) 77 | { 78 | worldMultiplier = WORLD_MULTIPLIER_1152; 79 | } 80 | else if(windowWidth >= 1024) 81 | { 82 | worldMultiplier = WORLD_MULTIPLIER_1024; 83 | } 84 | else if(windowWidth >= 800) 85 | { 86 | worldMultiplier = WORLD_MULTIPLIER_800; 87 | } 88 | else if(windowWidth >= 720) 89 | { 90 | worldMultiplier = WORLD_MULTIPLIER_720; 91 | } 92 | else 93 | { 94 | worldMultiplier = WORLD_MULTIPLIER_640; 95 | } 96 | 97 | Vector2 position = GetCameraPosition(); 98 | position.x += (screenPosition.x - (windowWidth * 0.5f)) * worldMultiplier; 99 | position.y -= (screenPosition.y - (windowHeight * 0.5f)) * worldMultiplier; 100 | 101 | return position; 102 | } 103 | 104 | return Vector2(0, 0); 105 | } 106 | 107 | void SetTotalMinutes(byte minutes) 108 | { 109 | Memory::Write(GetBaseAddress(), Offsets::TIME_TOTAL_MINUTES_OFFSETS, minutes); 110 | } 111 | 112 | byte GetTotalMinutes() 113 | { 114 | return Memory::Read(GetBaseAddress(), Offsets::TIME_TOTAL_MINUTES_OFFSETS); 115 | } 116 | 117 | void SetTotalSeconds(byte seconds) 118 | { 119 | Memory::Write(GetBaseAddress(), Offsets::TIME_TOTAL_SECONDS_OFFSETS, seconds); 120 | } 121 | 122 | byte GetTotalSeconds() 123 | { 124 | return Memory::Read(GetBaseAddress(), Offsets::TIME_TOTAL_SECONDS_OFFSETS); 125 | } 126 | 127 | void SetTotalMilliseconds(int millisecond) 128 | { 129 | Memory::Write(GetBaseAddress(), Offsets::TIME_TOTAL_MILLISECONDS_OFFSETS, millisecond); 130 | } 131 | 132 | int GetTotalMilliseconds() 133 | { 134 | return Memory::Read(GetBaseAddress(), Offsets::TIME_TOTAL_MILLISECONDS_OFFSETS); 135 | } 136 | 137 | void SetStageMinutes(byte minutes) 138 | { 139 | Memory::Write(GetBaseAddress(), Offsets::TIME_STAGE_MINUTES_OFFSETS, minutes); 140 | } 141 | 142 | byte GetStageMinutes() 143 | { 144 | return Memory::Read(GetBaseAddress(), Offsets::TIME_STAGE_MINUTES_OFFSETS); 145 | } 146 | 147 | void SetStageSeconds(byte seconds) 148 | { 149 | Memory::Write(GetBaseAddress(), Offsets::TIME_STAGE_SECONDS_OFFSETS, seconds); 150 | } 151 | 152 | byte GetStageSeconds() 153 | { 154 | return Memory::Read(GetBaseAddress(), Offsets::TIME_STAGE_SECONDS_OFFSETS); 155 | } 156 | 157 | void SetStageMilliseconds(int millisecond) 158 | { 159 | Memory::Write(GetBaseAddress(), Offsets::TIME_STAGE_MILLISECONDS_OFFSETS, millisecond); 160 | } 161 | 162 | int GetStageMilliseconds() 163 | { 164 | return Memory::Read(GetBaseAddress(), Offsets::TIME_STAGE_MILLISECONDS_OFFSETS); 165 | } 166 | 167 | void SetIPR0D0J2V0() 168 | { 169 | if (Offsets::IS_STEAM) { 170 | Memory::Write(GetBaseAddress(), Offsets::GAME_IPR0D0J2V0_OFFSETS, 0); 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /LunkyBox/Spelunky/ENTITY_CLASS.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace Spelunky 8 | { 9 | enum class ENTITY_CLASS 10 | { 11 | CHEST = 100, 12 | CRATE = 101, 13 | GOLD_BAR = 102, 14 | STACK_OF_GOLD_BARS = 103, 15 | LARGE_EMERALD = 104, 16 | LARGE_SAPPHIRE = 105, 17 | LARGE_RUBY = 106, 18 | LIVE_BOMB = 107, 19 | ATTACHED_ROPE = 108, 20 | BLOOD = 110, 21 | DIRT_BREAK = 111, 22 | STONE = 112, 23 | POT = 113, 24 | SKULL = 114, 25 | SPIDER_WEB = 115, 26 | HONEY = 116, 27 | SHOTGUN_SHOT = 117, 28 | LARGE_GOLD_NUGGET = 118, 29 | BOULDER = 120, 30 | PUSHABLE_STONE_BLOCK = 121, 31 | ARROW = 122, 32 | SMALL_GOLD_NUGGET = 124, 33 | SMALL_EMERALD = 125, 34 | SMALL_SAPPHIRE = 126, 35 | SMALL_RUBY = 127, 36 | SPIDER_WEB_SHOT = 142, 37 | GOLD_CHEST = 153, 38 | GOLD_KEY = 154, 39 | USED_PARACHUTE = 156, 40 | SCRATCH = 158, 41 | ALIEN_SHOT = 159, 42 | UFO_SHOT = 160, 43 | FALLING_PLATFORM = 161, 44 | LAMP = 162, 45 | FLARE = 163, 46 | SNOWBALL = 164, 47 | FLY = 165, 48 | BLACK_BOX = 166, 49 | SPRITESHEET_1 = 167, 50 | FLYING_TRAP_BLOCK = 168, 51 | FLYING_LAVA = 169, 52 | WIN_GAME = 170, 53 | WHITE_FLAG = 171, 54 | FISH_SKELETON = 172, 55 | NATURAL_DIAMOND = 173, 56 | WORM_ENTRANCE = 174, 57 | WORM_ACTIVATED = 175, 58 | IMP_COULDRON = 176, 59 | BRIGHT_LIGHT = 177, 60 | SPIKE_BALL = 178, 61 | METAL_BREAK = 179, 62 | JOURNAL = 180, 63 | PAPER = 181, 64 | WORM_BLOCK = 182, 65 | ICE_PLATFORM = 183, 66 | LEAF = 184, 67 | STATIC_CHEST = 187, 68 | PRIZE_WHEEL = 188, 69 | PRIZE_WHEEL_FLIPPER = 189, 70 | PRIZE_DOOR = 190, 71 | ACID_BOBBLE = 192, 72 | ACID_DROP = 193, 73 | FALLING_ICE = 194, 74 | ICE_BREAK = 195, 75 | SMOKE_1 = 196, 76 | FORCE_FIELD = 197, 77 | FORCE_FIELD_BEAM = 198, 78 | ICE_ENERGY_SHOT = 203, 79 | BROKEN_MATTOCK = 210, 80 | COFFIN = 211, 81 | UNKNOWN_1 = 212, 82 | TURRET_SHOT = 213, 83 | SPACESHIP_PLATFORM = 214, 84 | SPACESHIP_ELEVATOR = 215, 85 | BROKEN_ARROW = 216, 86 | OLMEC_ORB = 217, 87 | FALLING_WATER = 218, 88 | BLACK_BOX_ACCESSORY = 219, 89 | BLACK_BOX_PICKUP = 219, 90 | CHAIN_BALL = 220, 91 | SMOKE_2 = 221, 92 | OLMEC_INTRO = 223, 93 | CAMEL = 224, 94 | ALIEN_TARGET = 225, 95 | ALIEN_TARGET_SHOT = 226, 96 | SPACESHIP_LIGHT = 227, 97 | SPIDER_WEB_BALL = 228, 98 | ANKH_RESPAWN = 229, 99 | ANKH_GLOW = 230, 100 | BEE_PARTS = 232, 101 | FIRE = 233, 102 | ANUBIS_II = 234, 103 | POWDER_BOX = 235, 104 | STRING = 236, 105 | SMALL_SPIDER_WEB = 237, 106 | SPRITESHEET_2 = 238, 107 | YANG = 239, 108 | COIN = 240, 109 | FIREWORK = 242, 110 | BLACK_BOX_ROPE = 244, 111 | UNLIT_WALL_TORCH = 245, 112 | UNLIT_TORCH = 246, 113 | ALIEN_QUEEN_RING = 247, 114 | MYSTERY_BOX = 248, 115 | INVISABLE_BLOCK = 249, 116 | SKULL_CROWN = 250, 117 | SPRITESHEET_3 = 251, 118 | EGGPLANT = 252, 119 | BALLOON = 253, 120 | EXPLOSION = 301, 121 | RED_BALL = 302, 122 | TINY_FIRE = 303, 123 | SPRING_RINGS = 304, 124 | SPELUNKER_TELEPORT = 305, 125 | TORCH_FIRE = 306, 126 | SMALL_FIRE = 307, 127 | GLASS_BLOCK = 455, 128 | ROPES = 500, 129 | BOMB_BAG = 501, 130 | BOMB_BOX = 502, 131 | SPECTACLE = 503, 132 | CLIMBING_GLOVES = 504, 133 | PITCHERS_MITT = 505, 134 | SPRING_SHOES = 506, 135 | SPIKE_SHOES = 507, 136 | BOMB_PASTE = 508, 137 | COMPASS = 509, 138 | MATTOCK = 510, 139 | BOOMERANG = 511, 140 | MACHETE = 512, 141 | CRYSKNIFE = 513, 142 | WEB_GUN = 514, 143 | SHOTGUN = 515, 144 | FREEZE_RAY = 516, 145 | PLASMA_CANNON = 517, 146 | CAMERA = 518, 147 | TELEPORTER = 519, 148 | PARACHUTE = 520, 149 | CAPE = 521, 150 | JETPACK = 522, 151 | SHIELD = 523, 152 | ROYAL_JELLY = 524, 153 | IDOL = 525, 154 | KAPALA = 526, 155 | UDJAT_EYE = 527, 156 | ANKH = 528, 157 | HEDJET = 529, 158 | SCEPTER = 530, 159 | BOOK_OF_THE_DEAD = 531, 160 | VLADS_CAPE = 532, 161 | VLADS_AMULET = 533, 162 | SNAKE = 1001, 163 | SPIDER = 1002, 164 | BAT = 1003, 165 | CAVEMAN = 1004, 166 | DAMSEL = 1005, 167 | SHOPKEEPER = 1006, 168 | FROG = 1007, 169 | MANTRAP = 1008, 170 | YETI = 1009, 171 | UFO = 1010, 172 | HAWK_MAN = 1011, 173 | SKELETON = 1012, 174 | PIRANHA = 1013, 175 | MUMMY = 1014, 176 | MONKEY = 1015, 177 | ALIEN_LORD = 1016, 178 | GHOST = 1017, 179 | GIANT_SPIDER = 1018, 180 | JIAN_SHI = 1019, 181 | VAMPIRE = 1020, 182 | FIRE_FROG = 1021, 183 | TUNNEL_MAN = 1022, 184 | OLD_BITEY = 1023, 185 | SCARAB = 1024, 186 | YETI_KING = 1025, 187 | ALIEN = 1026, 188 | UNKNOWN_2 = 1027, 189 | VLAD = 1028, 190 | SCORPION = 1029, 191 | IMP = 1030, 192 | DEVIL = 1031, 193 | BEE = 1032, 194 | ANUBIS = 1033, 195 | QUEEN_BEE = 1034, 196 | BACTERIUM = 1035, 197 | COBRA = 1036, 198 | SPINNER_SPIDER = 1037, 199 | GIANT_FROG = 1038, 200 | MAMMOTH = 1039, 201 | ALIEN_TANK = 1040, 202 | TIKI_MAN = 1041, 203 | SCORPION_FLY = 1042, 204 | SNAIL = 1043, 205 | CROC_MAN = 1044, 206 | GREEN_KNIGHT = 1045, 207 | WORM_EGG = 1046, 208 | WORM_BABY = 1047, 209 | ALIEN_QUEEN = 1048, 210 | THE_BLACK_KNIGHT = 1049, 211 | GOLDEN_MONKEY = 1050, 212 | SUCCUBUS = 1051, 213 | HORSE_HEAD = 1052, 214 | OX_FACE = 1053, 215 | OLMEC = 1055, 216 | KING_YAMA = 1056, 217 | KING_YAMAS_HAND = 1057, 218 | TURRET = 1058, 219 | BABY_FROG = 1059, 220 | WATCHING_BALL = 1060, 221 | SPIDERLING = 1061, 222 | FISH = 1062, 223 | RAT = 1063, 224 | PENGUIN = 1064, 225 | BACKGROUND_ALIEN = 1065, 226 | LOCUST = 1067, 227 | MAGGOT = 1068 228 | }; 229 | } 230 | -------------------------------------------------------------------------------- /LunkyBox/LunkyBox.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 7 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 8 | 9 | 10 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 11 | h;hh;hpp;hxx;hm;inl;inc;xsd 12 | 13 | 14 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 15 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 16 | 17 | 18 | 19 | 20 | Source Files 21 | 22 | 23 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | Source Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | Source Files 45 | 46 | 47 | Source Files 48 | 49 | 50 | Source Files 51 | 52 | 53 | Source Files 54 | 55 | 56 | Source Files 57 | 58 | 59 | Source Files 60 | 61 | 62 | Source Files 63 | 64 | 65 | Source Files 66 | 67 | 68 | Source Files 69 | 70 | 71 | Source Files 72 | 73 | 74 | Source Files 75 | 76 | 77 | Source Files 78 | 79 | 80 | Source Files 81 | 82 | 83 | 84 | 85 | Header Files 86 | 87 | 88 | Header Files 89 | 90 | 91 | Header Files 92 | 93 | 94 | Header Files 95 | 96 | 97 | Header Files 98 | 99 | 100 | Header Files 101 | 102 | 103 | Header Files 104 | 105 | 106 | Header Files 107 | 108 | 109 | Header Files 110 | 111 | 112 | Header Files 113 | 114 | 115 | Header Files 116 | 117 | 118 | Header Files 119 | 120 | 121 | Header Files 122 | 123 | 124 | Header Files 125 | 126 | 127 | Header Files 128 | 129 | 130 | Header Files 131 | 132 | 133 | Header Files 134 | 135 | 136 | Header Files 137 | 138 | 139 | Header Files 140 | 141 | 142 | Header Files 143 | 144 | 145 | Header Files 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml -------------------------------------------------------------------------------- /LunkyBox/Mod/Menu.cpp: -------------------------------------------------------------------------------- 1 | #include "Menu.h" 2 | #include "../Input/Input.h" 3 | #include "../Config/Config.h" 4 | 5 | //This code is made with the classic menu_layout in mind. If you are going to try and make sense of this code, set menu_layout to classic in config.txt and see how that works ingame. 6 | 7 | namespace Mod 8 | { 9 | Menu* Menu::currentMenu = NULL; 10 | Menu* Menu::previousMenu = NULL; 11 | 12 | 13 | void Menu::ToggleMenu() 14 | { 15 | if(Menu::currentMenu == NULL) 16 | { 17 | OpenMenu(); 18 | } 19 | else 20 | { 21 | CloseMenu(); 22 | } 23 | } 24 | 25 | void Menu::OpenMenu() 26 | { 27 | if(Menu::currentMenu == NULL) 28 | { 29 | Menu::currentMenu = Menu::previousMenu; 30 | 31 | if(Config::GetBool("menu_sounds")) 32 | { 33 | Mod::player.PlaySound(SOUND_OPEN); 34 | } 35 | } 36 | } 37 | 38 | void Menu::CloseMenu() 39 | { 40 | if(Menu::currentMenu != NULL) 41 | { 42 | Menu::previousMenu = Menu::currentMenu; 43 | Menu::currentMenu = NULL; 44 | 45 | if(Config::GetBool("menu_sounds")) 46 | { 47 | Mod::player.PlaySound(SOUND_CLOSE); 48 | } 49 | } 50 | } 51 | 52 | void Menu::SetCurrentMenu(Menu* menu, Menu* referrerMenu) 53 | { 54 | Menu::currentMenu = menu; 55 | menu->referrerMenu = referrerMenu; 56 | } 57 | 58 | Menu::Menu(std::string name) 59 | { 60 | this->name = name; 61 | page = 0; 62 | selectedMenuItemIndex = 0; 63 | } 64 | 65 | void Menu::Update() 66 | { 67 | if(!isInputLocked) 68 | { 69 | //Select previous MenuItem 70 | 71 | if(Input::IsKeyPressed(Config::GetNumber("input_up"), Input::INPUT_MODE::CONTINUOUS)) 72 | { 73 | PreviousMenuItem(); 74 | 75 | if(Config::GetBool("menu_sounds")) 76 | { 77 | Mod::player.PlaySound(SOUND_SELECTED_ITEM_PREV_NEXT); 78 | } 79 | } 80 | 81 | 82 | //Select next MenuItem 83 | 84 | if(Input::IsKeyPressed(Config::GetNumber("input_down"), Input::INPUT_MODE::CONTINUOUS)) 85 | { 86 | NextMenuItem(); 87 | 88 | if(Config::GetBool("menu_sounds")) 89 | { 90 | Mod::player.PlaySound(SOUND_SELECTED_ITEM_PREV_NEXT); 91 | } 92 | } 93 | 94 | if(Config::GetText("menu_layout") == "classic") 95 | { 96 | //previous page 97 | 98 | if(Input::IsKeyPressed(Config::GetNumber("input_left"), Input::INPUT_MODE::CONTINUOUS)) 99 | { 100 | PreviousPage(); 101 | 102 | if(Config::GetBool("menu_sounds")) 103 | { 104 | Mod::player.PlaySound(SOUND_PAGE_PREV_NEXT); 105 | } 106 | } 107 | 108 | 109 | //Next page 110 | 111 | if(Input::IsKeyPressed(Config::GetNumber("input_right"), Input::INPUT_MODE::CONTINUOUS)) 112 | { 113 | NextPage(); 114 | 115 | if(Config::GetBool("menu_sounds")) 116 | { 117 | Mod::player.PlaySound(SOUND_PAGE_PREV_NEXT); 118 | } 119 | } 120 | } 121 | 122 | //Select 123 | 124 | if(Input::IsKeyPressed(Config::GetNumber("input_select"), Input::INPUT_MODE::CONTINUOUS)) 125 | { 126 | GetSelectedMenuItem()->Select(); 127 | } 128 | 129 | 130 | //Go back 131 | 132 | if(Input::IsKeyPressed(Config::GetNumber("input_back"), Input::INPUT_MODE::CONTINUOUS)) 133 | { 134 | GoBack(); 135 | 136 | if(currentMenu != NULL && Config::GetBool("menu_sounds")) 137 | { 138 | Mod::player.PlaySound(SOUND_GO_BACK); 139 | } 140 | } 141 | } 142 | 143 | 144 | //Go back if this menu contains no MenuItem's 145 | 146 | if(menuItems.size() == 0) 147 | { 148 | GoBack(); 149 | 150 | Mod::player.PlaySound(SOUND_ERROR); 151 | } 152 | 153 | 154 | //Fix selected selectedMenuItemIndex being outside the menu 155 | 156 | int menuItemsOnPageCount = GetMenuItemsOnPageCount(page); 157 | 158 | if(selectedMenuItemIndex >= menuItemsOnPageCount) 159 | { 160 | selectedMenuItemIndex = menuItemsOnPageCount - 1; 161 | } 162 | 163 | 164 | //Call OnUpdate on all MenuItem's 165 | 166 | std::vector menuItemsOnPage = GetMenuItemsOnPage(page); 167 | 168 | for(int menuItemIndex = 0; menuItemIndex < (int)menuItemsOnPage.size(); menuItemIndex++) 169 | { 170 | MenuItem* menuItem = menuItemsOnPage[menuItemIndex]; 171 | 172 | menuItem->Update(); 173 | } 174 | } 175 | 176 | void Menu::Draw(LPDIRECT3DDEVICE9 deviceInterface) 177 | { 178 | //Draw title box 179 | 180 | int pageCount = GetPageCount(); 181 | 182 | Drawing::DrawRectangle(deviceInterface, Config::GetNumber("menu_x"), Config::GetNumber("menu_y"), Config::GetNumber("menu_width"), TITLE_BOX_HEIGHT, color1); 183 | Drawing::DrawText(fontMenuTitle, name.c_str(), Config::GetNumber("menu_x") + MENU_MARGIN, Config::GetNumber("menu_y") + 4, Config::GetNumber("menu_width") - MENU_MARGIN, TITLE_BOX_HEIGHT - MENU_MARGIN, color2); 184 | 185 | if(Config::GetText("menu_layout") == "classic") 186 | { 187 | if(pageCount > 1) 188 | { 189 | std::stringstream pageNumberText; 190 | pageNumberText << "Page " << page + 1 << " of " << pageCount; 191 | 192 | Drawing::DrawText(fontMenuPageNumber, pageNumberText.str().c_str(), Config::GetNumber("menu_x") + MENU_MARGIN, Config::GetNumber("menu_y") + 38, Config::GetNumber("menu_width") - MENU_MARGIN, TITLE_BOX_HEIGHT - MENU_MARGIN, color2); 193 | } 194 | } 195 | else if(Config::GetText("menu_layout") == "single_page") 196 | { 197 | std::stringstream indexText; 198 | indexText << Config::GetNumber("menu_items_per_page") * page + selectedMenuItemIndex + 1 << " / " << menuItems.size(); 199 | 200 | Drawing::DrawText(fontMenuPageNumber, indexText.str().c_str(), Config::GetNumber("menu_x") + MENU_MARGIN + 2, Config::GetNumber("menu_y") + 38, Config::GetNumber("menu_width") - MENU_MARGIN, TITLE_BOX_HEIGHT - MENU_MARGIN, color2); 201 | } 202 | 203 | 204 | //Draw items 205 | 206 | std::vector menuItemsOnPage = GetMenuItemsOnPage(page); 207 | 208 | for(int menuItemIndex = 0; menuItemIndex < (int)menuItemsOnPage.size(); menuItemIndex++) 209 | { 210 | MenuItem* menuItem = menuItemsOnPage[menuItemIndex]; 211 | 212 | menuItem->Draw(deviceInterface, menuItemIndex); 213 | } 214 | } 215 | 216 | void Menu::AddMenuItem(MenuItem* menuItem) 217 | { 218 | menuItems.push_back(menuItem); 219 | } 220 | 221 | void Menu::PreviousMenuItem() 222 | { 223 | 224 | if(selectedMenuItemIndex <= 0) 225 | { 226 | PreviousPage(); 227 | selectedMenuItemIndex = GetMenuItemsOnPageCount(page) - 1; 228 | } 229 | else 230 | { 231 | selectedMenuItemIndex -= 1; 232 | } 233 | } 234 | 235 | void Menu::NextMenuItem() 236 | { 237 | if(selectedMenuItemIndex >= GetMenuItemsOnPageCount(page) - 1) 238 | { 239 | NextPage(); 240 | selectedMenuItemIndex = 0; 241 | } 242 | else 243 | { 244 | selectedMenuItemIndex += 1; 245 | } 246 | } 247 | 248 | void Menu::PreviousPage() 249 | { 250 | if(page <= 0) 251 | { 252 | page = GetPageCount() - 1; 253 | } 254 | else 255 | { 256 | page -= 1; 257 | } 258 | } 259 | 260 | void Menu::NextPage() 261 | { 262 | if(page >= GetPageCount() -1) 263 | { 264 | page = 0; 265 | } 266 | else 267 | { 268 | page += 1; 269 | } 270 | } 271 | 272 | void Menu::GoBack() 273 | { 274 | if(referrerMenu == NULL) 275 | { 276 | CloseMenu(); 277 | } 278 | else 279 | { 280 | currentMenu = referrerMenu; 281 | } 282 | } 283 | 284 | std::vector Menu::GetMenuItemsOnPage(int page) 285 | { 286 | std::vector menuItemsOnPage; 287 | 288 | if(Config::GetText("menu_layout") == "classic") 289 | { 290 | for(int menuItemIndex = Config::GetNumber("menu_items_per_page") * page; menuItemIndex < min((int)menuItems.size(), Config::GetNumber("menu_items_per_page") * (page + 1)); menuItemIndex++) 291 | { 292 | MenuItem* menuItem = menuItems[menuItemIndex]; 293 | menuItemsOnPage.push_back(menuItem); 294 | } 295 | } 296 | else if(Config::GetText("menu_layout") == "single_page") 297 | { 298 | int index = Config::GetNumber("menu_items_per_page") * page + selectedMenuItemIndex; 299 | int halfOfPage = (int)round(Config::GetNumber("menu_items_per_page") * 0.5); 300 | 301 | for( 302 | int menuItemIndex = max(0, index - halfOfPage + 1 - max(0, index + halfOfPage - (int)menuItems.size())); 303 | menuItemIndex < min((int)menuItems.size(), index + halfOfPage - min(0, index - halfOfPage + 1)); 304 | menuItemIndex++ 305 | ) 306 | { 307 | MenuItem* menuItem = menuItems[menuItemIndex]; 308 | menuItemsOnPage.push_back(menuItem); 309 | } 310 | } 311 | 312 | return menuItemsOnPage; 313 | } 314 | 315 | MenuItem* Menu::GetSelectedMenuItem() 316 | { 317 | return menuItems[Config::GetNumber("menu_items_per_page") * page + selectedMenuItemIndex]; 318 | } 319 | 320 | int Menu::GetMenuItemsOnPageCount(int page) 321 | { 322 | return min((int)menuItems.size(), Config::GetNumber("menu_items_per_page") * (page + 1)) - (Config::GetNumber("menu_items_per_page") * page); 323 | } 324 | 325 | int Menu::GetPageCount() 326 | { 327 | return (int)ceil((menuItems.size() - 1) / Config::GetNumber("menu_items_per_page")) + 1; 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /LunkyBoxInjector/LunkyBoxInjector.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Debug 7 | Win32 8 | 9 | 10 | Release 11 | Win32 12 | 13 | 14 | Debug 15 | x64 16 | 17 | 18 | Release 19 | x64 20 | 21 | 22 | 23 | {FC05B746-3612-4D80-B17F-BE10126A4DF3} 24 | Win32Proj 25 | LunkyBoxInjector 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | MultiByte 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | MultiByte 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | MultiThreadedDebugDLL 94 | 95 | 96 | Console 97 | true 98 | 99 | 100 | 101 | 102 | 103 | 104 | Level3 105 | Disabled 106 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 107 | true 108 | 109 | 110 | Console 111 | true 112 | 113 | 114 | 115 | 116 | Level3 117 | 118 | 119 | MaxSpeed 120 | true 121 | true 122 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 123 | true 124 | MultiThreaded 125 | 126 | 127 | Console 128 | true 129 | true 130 | true 131 | 132 | 133 | 134 | 135 | Level3 136 | 137 | 138 | MaxSpeed 139 | true 140 | true 141 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 142 | true 143 | 144 | 145 | Console 146 | true 147 | true 148 | true 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /LunkyBox/LunkyBox.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Debug 7 | Win32 8 | 9 | 10 | Release 11 | Win32 12 | 13 | 14 | Debug 15 | x64 16 | 17 | 18 | Release 19 | x64 20 | 21 | 22 | 23 | {D28EF2F5-2693-44EA-8A50-7949D71B2249} 24 | Win32Proj 25 | LunkyBox 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | MultiByte 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | MultiByte 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | D:\Program Files %28x86%29\Microsoft DirectX SDK %28August 2009%29\Include;$(IncludePath) 76 | D:\Program Files %28x86%29\Microsoft DirectX SDK %28August 2009%29\Lib\x86;$(LibraryPath) 77 | 78 | 79 | true 80 | 81 | 82 | false 83 | D:\Program Files %28x86%29\Microsoft DirectX SDK %28August 2009%29\Include;$(IncludePath) 84 | D:\Program Files %28x86%29\Microsoft DirectX SDK %28August 2009%29\Lib\x86;$(LibraryPath) 85 | 86 | 87 | false 88 | 89 | 90 | 91 | 92 | 93 | Level3 94 | Disabled 95 | WIN32;_DEBUG;_WINDOWS;_USRDLL;LUNKYBOX_EXPORTS;%(PreprocessorDefinitions) 96 | true 97 | MultiThreadedDebugDLL 98 | 99 | 100 | Windows 101 | true 102 | 103 | 104 | 105 | 106 | 107 | 108 | Level3 109 | Disabled 110 | _DEBUG;_WINDOWS;_USRDLL;LUNKYBOX_EXPORTS;%(PreprocessorDefinitions) 111 | true 112 | 113 | 114 | Windows 115 | true 116 | 117 | 118 | 119 | 120 | Level3 121 | 122 | 123 | MaxSpeed 124 | true 125 | true 126 | WIN32;NDEBUG;_WINDOWS;_USRDLL;LUNKYBOX_EXPORTS;%(PreprocessorDefinitions) 127 | true 128 | MultiThreaded 129 | 130 | 131 | Windows 132 | true 133 | true 134 | true 135 | 136 | 137 | 138 | 139 | Level3 140 | 141 | 142 | MaxSpeed 143 | true 144 | true 145 | NDEBUG;_WINDOWS;_USRDLL;LUNKYBOX_EXPORTS;%(PreprocessorDefinitions) 146 | true 147 | 148 | 149 | Windows 150 | true 151 | true 152 | true 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /LunkyBox/Mod/Mod.cpp: -------------------------------------------------------------------------------- 1 | #include "Mod.h" 2 | #include 3 | #include 4 | #include "Memory.h" 5 | #include "MenuItem.h" 6 | #include "BoolMenuItem.h" 7 | #include "IntMenuItem.h" 8 | #include "../Vector2.h" 9 | #include "../Window/Window.h" 10 | #include "../Input/Input.h" 11 | #include "../Spelunky/ITEM_CLASS.h" 12 | #include "../Spelunky/ENTITY_CLASS.h" 13 | #include "../Config/Config.h" 14 | 15 | 16 | namespace Mod 17 | { 18 | bool isFontsCreated = false; 19 | bool isMenusCreated = false; 20 | 21 | Spelunky::Player player = NULL; 22 | bool hasInfiniteHearts = false; 23 | bool hasInfiniteBombs = false; 24 | bool hasInfiniteRopes = false; 25 | bool hasInfiniteAnkhs = false; 26 | bool hasInfiniteParachutes = false; 27 | bool isTotalTimeFrozen = false; 28 | bool isStageTimeFrozen = false; 29 | byte frozenTotalMinutes = 0; 30 | byte frozenTotalSeconds = 0; 31 | byte frozenStageMinutes = 0; 32 | byte frozenStageSeconds = 0; 33 | LPD3DXFONT fontMenuTitle = NULL; 34 | LPD3DXFONT fontMenuPageNumber = NULL; 35 | LPD3DXFONT fontMenuItem = NULL; 36 | D3DCOLOR color1 = D3DCOLOR_ARGB(255, 244, 244, 244); 37 | D3DCOLOR color2 = D3DCOLOR_ARGB(255, 26, 26, 26); 38 | 39 | 40 | //Called when the dll is injected 41 | DWORD WINAPI Start(LPVOID param) 42 | { 43 | //Read config 44 | 45 | if(!Config::Parse(CONFIG_FILE)) 46 | { 47 | MessageBox(NULL, "Failed to parse config file.", TITLE, NULL); 48 | 49 | return NULL; 50 | } 51 | 52 | Offsets::InitializeOffsets(); 53 | if (!Offsets::IS_STEAM && !Offsets::IS_GOG) 54 | { 55 | MessageBox(NULL, "Could not determine if Steam or GOG release of Spelunky.", TITLE, NULL); 56 | 57 | return NULL; 58 | } 59 | 60 | //Create main loop 61 | 62 | while(true) 63 | { 64 | Update(); 65 | } 66 | 67 | return NULL; 68 | } 69 | 70 | //Called every tick 71 | void Update() 72 | { 73 | Spelunky::SetIPR0D0J2V0(); 74 | 75 | player = Spelunky::Player::GetLocal(); 76 | 77 | CreateMenus(); 78 | 79 | Input::Update(); 80 | InfiniteStatsUpdate(); 81 | FrozenTimeUpdate(); 82 | MenuUpdate(); 83 | } 84 | 85 | void D3D9Reset(LPDIRECT3DDEVICE9 deviceInterface, D3DPRESENT_PARAMETERS* presentationParameters) 86 | { 87 | 88 | } 89 | 90 | //Called every frame 91 | void D3D9EndScene(LPDIRECT3DDEVICE9 deviceInterface) 92 | { 93 | CreateFonts(deviceInterface); 94 | 95 | if(player.address != NULL && Menu::currentMenu != NULL) 96 | { 97 | Menu::currentMenu->Draw(deviceInterface); 98 | } 99 | } 100 | 101 | void MenuUpdate() 102 | { 103 | if(player.address != NULL) 104 | { 105 | if(Input::IsKeyPressed(Config::GetNumber("input_toggle_menu"), Input::INPUT_MODE::CONTINUOUS)) 106 | { 107 | Menu::ToggleMenu(); 108 | } 109 | 110 | if(Menu::currentMenu != NULL) 111 | { 112 | Menu::currentMenu->Update(); 113 | } 114 | } 115 | } 116 | 117 | void InfiniteStatsUpdate() 118 | { 119 | if(hasInfiniteHearts) 120 | { 121 | player.SetHearts(99); 122 | } 123 | 124 | if(hasInfiniteBombs) 125 | { 126 | player.SetBombs(99); 127 | } 128 | 129 | if(hasInfiniteRopes) 130 | { 131 | player.SetRopes(99); 132 | } 133 | 134 | if(hasInfiniteAnkhs) 135 | { 136 | player.SetHasItem(Spelunky::ITEM_CLASS::ANKH, true); 137 | } 138 | 139 | if(hasInfiniteParachutes) 140 | { 141 | player.SetHasItem(Spelunky::ITEM_CLASS::PARACHUTE, true); 142 | } 143 | } 144 | 145 | void FrozenTimeUpdate() 146 | { 147 | if(isTotalTimeFrozen) 148 | { 149 | Spelunky::SetTotalMinutes(frozenTotalMinutes); 150 | Spelunky::SetTotalSeconds(frozenTotalSeconds); 151 | Spelunky::SetTotalMilliseconds(0); 152 | } 153 | 154 | if(isStageTimeFrozen) 155 | { 156 | Spelunky::SetStageMinutes(frozenStageMinutes); 157 | Spelunky::SetStageSeconds(frozenStageSeconds); 158 | Spelunky::SetStageMilliseconds(0); 159 | } 160 | } 161 | 162 | void CreateFonts(LPDIRECT3DDEVICE9 deviceInterface) 163 | { 164 | if(!isFontsCreated) 165 | { 166 | isFontsCreated = true; 167 | 168 | D3DXCreateFont(deviceInterface, 32, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT(FONT), &fontMenuTitle); 169 | D3DXCreateFont(deviceInterface, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT(FONT), &fontMenuPageNumber); 170 | D3DXCreateFont(deviceInterface, 26, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT(FONT), &fontMenuItem); 171 | } 172 | } 173 | 174 | void CreateMenus() 175 | { 176 | if(!isMenusCreated) 177 | { 178 | isMenusCreated = true; 179 | 180 | 181 | //Add a MenuItem for going to another menu 182 | std::function AddLinkMenuItem = [](Menu* menu, std::string name, Menu* destinationMenu) 183 | { 184 | MenuItem* linkMenuItem = new MenuItem(menu, name); 185 | linkMenuItem->OnSelect = [menu, destinationMenu](MenuItem* menuItem) 186 | { 187 | Menu::SetCurrentMenu(destinationMenu, menu); 188 | }; 189 | menu->AddMenuItem(linkMenuItem); 190 | }; 191 | 192 | 193 | //Add a BoolMenuItem for turning a player item on/off 194 | std::function AddItemBoolMenuItem = [](Menu* menu, std::string name, Spelunky::ITEM_CLASS itemClass) 195 | { 196 | BoolMenuItem* itemBoolMenuItem = new BoolMenuItem(menu, name); 197 | itemBoolMenuItem->OnSelect = [itemClass](MenuItem* menuItem) 198 | { 199 | BoolMenuItem* itemBoolMenuItem = (BoolMenuItem*)menuItem; 200 | 201 | player.SetHasItem(itemClass, itemBoolMenuItem->isOn); 202 | }; 203 | itemBoolMenuItem->OnUpdate = [itemClass](MenuItem* menuItem) 204 | { 205 | BoolMenuItem* itemBoolMenuItem = (BoolMenuItem*)menuItem; 206 | 207 | itemBoolMenuItem->isOn = player.HasItem(itemClass); 208 | }; 209 | menu->AddMenuItem(itemBoolMenuItem); 210 | }; 211 | 212 | 213 | //Add a BoolMenuItem for turning all player items to one state 214 | std::function AddAllItemsMenuItem = [](Menu* menu, std::string name, bool hasItem) 215 | { 216 | MenuItem* allItemsBoolMenuItem = new MenuItem(menu, name); 217 | allItemsBoolMenuItem->OnSelect = [hasItem](MenuItem* menuItem) 218 | { 219 | player.SetHasItem(Spelunky::ITEM_CLASS::ANKH, hasItem); 220 | player.SetHasItem(Spelunky::ITEM_CLASS::BOOK_OF_THE_DEAD, hasItem); 221 | player.SetHasItem(Spelunky::ITEM_CLASS::HEDJET, hasItem); 222 | player.SetHasItem(Spelunky::ITEM_CLASS::UDJAT_EYE, hasItem); 223 | player.SetHasItem(Spelunky::ITEM_CLASS::CLIMBING_GLOVES, hasItem); 224 | player.SetHasItem(Spelunky::ITEM_CLASS::COMPASS, hasItem); 225 | player.SetHasItem(Spelunky::ITEM_CLASS::CRYSKNIFE, hasItem); 226 | player.SetHasItem(Spelunky::ITEM_CLASS::KAPALA, hasItem); 227 | player.SetHasItem(Spelunky::ITEM_CLASS::PARACHUTE, hasItem); 228 | player.SetHasItem(Spelunky::ITEM_CLASS::PASTE, hasItem); 229 | player.SetHasItem(Spelunky::ITEM_CLASS::PITCHERS_MITT, hasItem); 230 | player.SetHasItem(Spelunky::ITEM_CLASS::SPECTACLES, hasItem); 231 | player.SetHasItem(Spelunky::ITEM_CLASS::SPIKE_SHOES, hasItem); 232 | player.SetHasItem(Spelunky::ITEM_CLASS::SPRING_SHOES, hasItem); 233 | player.SetHasItem(Spelunky::ITEM_CLASS::VLADS_AMULET, hasItem); 234 | }; 235 | menu->AddMenuItem(allItemsBoolMenuItem); 236 | }; 237 | 238 | 239 | float* moveDistance = new float(1); 240 | 241 | //Add a MenuItem for teleporting relative to the player 242 | std::function AddRelativeMoveMenuItem = [moveDistance](Menu* menu, std::string name, Vector2 relativePosition) 243 | { 244 | MenuItem* relativeMoveMenuItem = new MenuItem(menu, name); 245 | relativeMoveMenuItem->OnSelect = [moveDistance, relativePosition](MenuItem* menuItem) 246 | { 247 | float moveDistanceValue = *moveDistance; 248 | 249 | Vector2 newPosition = player.GetPosition(); 250 | newPosition.x += relativePosition.x * moveDistanceValue; 251 | newPosition.y += relativePosition.y * moveDistanceValue; 252 | 253 | player.Teleport(newPosition); 254 | }; 255 | menu->AddMenuItem(relativeMoveMenuItem); 256 | }; 257 | 258 | 259 | bool* isCursorControlled = new bool(true); 260 | bool* useCursorVelocity = new bool(false); 261 | Vector2* pressedPosition = new Vector2(0, 0); 262 | 263 | //Add a MenuItem for spawning an entity 264 | std::function AddSpawnEntityMenuItem = [isCursorControlled, useCursorVelocity, pressedPosition](Menu* menu, std::string name, Spelunky::ENTITY_CLASS entityClass) 265 | { 266 | std::stringstream nameStream; 267 | nameStream << (DWORD)entityClass << " " << name; 268 | 269 | MenuItem* spawnEntityMenuItem = new MenuItem(menu, nameStream.str()); 270 | spawnEntityMenuItem->OnUpdate = [isCursorControlled, useCursorVelocity, pressedPosition, entityClass](MenuItem* menuItem) 271 | { 272 | if(*isCursorControlled && menuItem->IsInFocus()) 273 | { 274 | Vector2 cursorPosition = Spelunky::ScreenToWorld(Window::GetRelativeCursorPosition()); 275 | 276 | if(*useCursorVelocity) 277 | { 278 | if(Input::IsKeyPressed(VK_LBUTTON, Input::INPUT_MODE::ONCE)) 279 | { 280 | (*pressedPosition).x = cursorPosition.x; 281 | (*pressedPosition).y = cursorPosition.y; 282 | } 283 | 284 | if(Input::IsKeyReleased(VK_LBUTTON, Input::INPUT_MODE::ONCE)) 285 | { 286 | Vector2 velocity = Vector2( 287 | (cursorPosition.x - (*pressedPosition).x) * 0.1f, 288 | (cursorPosition.y - (*pressedPosition).y) * 0.1f 289 | ); 290 | 291 | Spelunky::Entity entity = Spelunky::SpawnEntity(Vector2((*pressedPosition).x, (*pressedPosition).y), entityClass); 292 | entity.SetIsFlipped(player.IsFlipped()); 293 | entity.SetVelocity(velocity); 294 | 295 | if(Config::GetBool("menu_sounds")) 296 | { 297 | player.PlaySound(SOUND_SELECT); 298 | } 299 | } 300 | } 301 | else if(Input::IsKeyPressed(VK_LBUTTON, Input::INPUT_MODE::CONTINUOUS)) 302 | { 303 | Spelunky::Entity entity = Spelunky::SpawnEntity(cursorPosition, entityClass); 304 | entity.SetIsFlipped(player.IsFlipped()); 305 | 306 | if(Config::GetBool("menu_sounds")) 307 | { 308 | player.PlaySound(SOUND_SELECT); 309 | } 310 | } 311 | } 312 | }; 313 | spawnEntityMenuItem->OnDraw = [isCursorControlled, useCursorVelocity, pressedPosition, entityClass](MenuItem* menuItem, LPDIRECT3DDEVICE9 deviceInterface, int menuItemIndex) 314 | { 315 | if((*pressedPosition).x != 0 && (*pressedPosition).y != 0) 316 | { 317 | Vector2 cursorPosition = Spelunky::ScreenToWorld(Window::GetRelativeCursorPosition()); 318 | } 319 | }; 320 | spawnEntityMenuItem->OnSelect = [isCursorControlled, entityClass](MenuItem* menuItem) 321 | { 322 | Vector2 position = player.GetPosition(); 323 | position.x += player.IsFlipped() ? -2 : 2; 324 | position.y += 0.6f; 325 | 326 | Spelunky::Entity entity = Spelunky::SpawnEntity(position, entityClass); 327 | entity.SetIsFlipped(player.IsFlipped()); 328 | }; 329 | menu->AddMenuItem(spawnEntityMenuItem); 330 | }; 331 | 332 | 333 | //Add a MenuItem for playing a sound 334 | std::function AddSoundMenuItem = [](Menu* menu, char* sound) 335 | { 336 | MenuItem* soundMenuItem = new MenuItem(menu, sound); 337 | soundMenuItem->hasSound = false; 338 | soundMenuItem->OnSelect = [sound](MenuItem* menuItem) 339 | { 340 | player.PlaySound(sound); 341 | }; 342 | menu->AddMenuItem(soundMenuItem); 343 | }; 344 | 345 | 346 | //Player inventory menu 347 | 348 | Menu* playerItemsMenu = new Menu("Player Items"); 349 | 350 | AddAllItemsMenuItem(playerItemsMenu, "Get All", true); 351 | AddAllItemsMenuItem(playerItemsMenu, "Remove All", false); 352 | AddItemBoolMenuItem(playerItemsMenu, "Ankh", Spelunky::ITEM_CLASS::ANKH); 353 | AddItemBoolMenuItem(playerItemsMenu, "Book of the Dead", Spelunky::ITEM_CLASS::BOOK_OF_THE_DEAD); 354 | AddItemBoolMenuItem(playerItemsMenu, "Hedjet", Spelunky::ITEM_CLASS::HEDJET); 355 | AddItemBoolMenuItem(playerItemsMenu, "Udjat Eye", Spelunky::ITEM_CLASS::UDJAT_EYE); 356 | AddItemBoolMenuItem(playerItemsMenu, "Climbing Gloves", Spelunky::ITEM_CLASS::CLIMBING_GLOVES); 357 | AddItemBoolMenuItem(playerItemsMenu, "Compass", Spelunky::ITEM_CLASS::COMPASS); 358 | AddItemBoolMenuItem(playerItemsMenu, "Crysknife", Spelunky::ITEM_CLASS::CRYSKNIFE); 359 | AddItemBoolMenuItem(playerItemsMenu, "Kapala", Spelunky::ITEM_CLASS::KAPALA); 360 | AddItemBoolMenuItem(playerItemsMenu, "Parachute", Spelunky::ITEM_CLASS::PARACHUTE); 361 | AddItemBoolMenuItem(playerItemsMenu, "Paste", Spelunky::ITEM_CLASS::PASTE); 362 | AddItemBoolMenuItem(playerItemsMenu, "Pitcher's Mitt", Spelunky::ITEM_CLASS::PITCHERS_MITT); 363 | AddItemBoolMenuItem(playerItemsMenu, "Spectacles", Spelunky::ITEM_CLASS::SPECTACLES); 364 | AddItemBoolMenuItem(playerItemsMenu, "Spike Shoes", Spelunky::ITEM_CLASS::SPIKE_SHOES); 365 | AddItemBoolMenuItem(playerItemsMenu, "Spring Shoes", Spelunky::ITEM_CLASS::SPRING_SHOES); 366 | AddItemBoolMenuItem(playerItemsMenu, "Vlad's Amulet", Spelunky::ITEM_CLASS::VLADS_AMULET); 367 | 368 | 369 | //Player menu 370 | 371 | Menu* playerMenu = new Menu("Player"); 372 | 373 | AddLinkMenuItem(playerMenu, "Items >", playerItemsMenu); 374 | 375 | IntMenuItem* goldIntMenuItem = new IntMenuItem(playerMenu, "Gold", 0, 0, (std::numeric_limits::max)(), 5000); 376 | goldIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 377 | { 378 | IntMenuItem* goldIntMenuItem = (IntMenuItem*)menuItem; 379 | 380 | player.SetGold(goldIntMenuItem->value); 381 | }; 382 | goldIntMenuItem->OnUpdate = [](MenuItem* menuItem) 383 | { 384 | IntMenuItem* goldIntMenuItem = (IntMenuItem*)menuItem; 385 | 386 | goldIntMenuItem->value = player.GetGold(); 387 | }; 388 | playerMenu->AddMenuItem(goldIntMenuItem); 389 | 390 | IntMenuItem* heartsIntMenuItem = new IntMenuItem(playerMenu, "Hearts", 0, 1, 99, 10); 391 | heartsIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 392 | { 393 | IntMenuItem* heartsIntMenuItem = (IntMenuItem*)menuItem; 394 | 395 | player.SetHearts(heartsIntMenuItem->value); 396 | }; 397 | heartsIntMenuItem->OnUpdate = [](MenuItem* menuItem) 398 | { 399 | IntMenuItem* heartsIntMenuItem = (IntMenuItem*)menuItem; 400 | 401 | heartsIntMenuItem->value = player.GetHearts(); 402 | }; 403 | playerMenu->AddMenuItem(heartsIntMenuItem); 404 | 405 | IntMenuItem* bombsIntMenuItem = new IntMenuItem(playerMenu, "Bombs", 0, 0, 99, 10); 406 | bombsIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 407 | { 408 | IntMenuItem* bombsIntMenuItem = (IntMenuItem*)menuItem; 409 | 410 | player.SetBombs(bombsIntMenuItem->value); 411 | }; 412 | bombsIntMenuItem->OnUpdate = [](MenuItem* menuItem) 413 | { 414 | IntMenuItem* bombsIntMenuItem = (IntMenuItem*)menuItem; 415 | 416 | bombsIntMenuItem->value = player.GetBombs(); 417 | }; 418 | playerMenu->AddMenuItem(bombsIntMenuItem); 419 | 420 | IntMenuItem* ropesIntMenuItem = new IntMenuItem(playerMenu, "Ropes", 0, 0, 99, 10); 421 | ropesIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 422 | { 423 | IntMenuItem* ropesIntMenuItem = (IntMenuItem*)menuItem; 424 | 425 | player.SetRopes(ropesIntMenuItem->value); 426 | }; 427 | ropesIntMenuItem->OnUpdate = [](MenuItem* menuItem) 428 | { 429 | IntMenuItem* ropesIntMenuItem = (IntMenuItem*)menuItem; 430 | 431 | ropesIntMenuItem->value = player.GetRopes(); 432 | }; 433 | playerMenu->AddMenuItem(ropesIntMenuItem); 434 | 435 | IntMenuItem* favorIntMenuItem = new IntMenuItem(playerMenu, "Kali Favor", 0, 0, 100, 10); 436 | favorIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 437 | { 438 | IntMenuItem* favorIntMenuItem = (IntMenuItem*)menuItem; 439 | 440 | player.SetFavor(favorIntMenuItem->value); 441 | }; 442 | favorIntMenuItem->OnUpdate = [](MenuItem* menuItem) 443 | { 444 | IntMenuItem* favorIntMenuItem = (IntMenuItem*)menuItem; 445 | 446 | favorIntMenuItem->value = player.GetFavor(); 447 | }; 448 | playerMenu->AddMenuItem(favorIntMenuItem); 449 | 450 | BoolMenuItem* infiniteHeartsBoolMenuItem = new BoolMenuItem(playerMenu, "Infinite Hearts", hasInfiniteHearts); 451 | infiniteHeartsBoolMenuItem->OnSelect = [](MenuItem* menuItem) 452 | { 453 | BoolMenuItem* infiniteHeartsBoolMenuItem = (BoolMenuItem*)menuItem; 454 | 455 | hasInfiniteHearts = infiniteHeartsBoolMenuItem->isOn; 456 | }; 457 | playerMenu->AddMenuItem(infiniteHeartsBoolMenuItem); 458 | 459 | BoolMenuItem* infiniteBombsBoolMenuItem = new BoolMenuItem(playerMenu, "Infinite Bombs", hasInfiniteBombs); 460 | infiniteBombsBoolMenuItem->OnSelect = [](MenuItem* menuItem) 461 | { 462 | BoolMenuItem* infiniteBombsBoolMenuItem = (BoolMenuItem*)menuItem; 463 | 464 | hasInfiniteBombs = infiniteBombsBoolMenuItem->isOn; 465 | }; 466 | playerMenu->AddMenuItem(infiniteBombsBoolMenuItem); 467 | 468 | BoolMenuItem* infiniteRopesBoolMenuItem = new BoolMenuItem(playerMenu, "Infinite Ropes", hasInfiniteRopes); 469 | infiniteRopesBoolMenuItem->OnSelect = [](MenuItem* menuItem) 470 | { 471 | BoolMenuItem* infiniteRopesBoolMenuItem = (BoolMenuItem*)menuItem; 472 | 473 | hasInfiniteRopes = infiniteRopesBoolMenuItem->isOn; 474 | }; 475 | playerMenu->AddMenuItem(infiniteRopesBoolMenuItem); 476 | 477 | BoolMenuItem* infiniteAnkhsBoolMenuItem = new BoolMenuItem(playerMenu, "Infinite Ankhs", hasInfiniteAnkhs); 478 | infiniteAnkhsBoolMenuItem->OnSelect = [](MenuItem* menuItem) 479 | { 480 | BoolMenuItem* infiniteAnkhsBoolMenuItem = (BoolMenuItem*)menuItem; 481 | 482 | hasInfiniteAnkhs = infiniteAnkhsBoolMenuItem->isOn; 483 | }; 484 | playerMenu->AddMenuItem(infiniteAnkhsBoolMenuItem); 485 | 486 | BoolMenuItem* infiniteParachutesBoolMenuItem = new BoolMenuItem(playerMenu, "Infinite Parachutes", hasInfiniteParachutes); 487 | infiniteParachutesBoolMenuItem->OnSelect = [](MenuItem* menuItem) 488 | { 489 | BoolMenuItem* infiniteParachutesBoolMenuItem = (BoolMenuItem*)menuItem; 490 | 491 | hasInfiniteParachutes = infiniteParachutesBoolMenuItem->isOn; 492 | }; 493 | playerMenu->AddMenuItem(infiniteParachutesBoolMenuItem); 494 | 495 | 496 | //World objects menu 497 | 498 | Menu* worldObjectsMenu = new Menu("World Objects"); 499 | 500 | AddSpawnEntityMenuItem(worldObjectsMenu, "Small Spider Web", Spelunky::ENTITY_CLASS::SMALL_SPIDER_WEB); 501 | AddSpawnEntityMenuItem(worldObjectsMenu, "Spider Web", Spelunky::ENTITY_CLASS::SPIDER_WEB); 502 | AddSpawnEntityMenuItem(worldObjectsMenu, "Boulder", Spelunky::ENTITY_CLASS::BOULDER); 503 | AddSpawnEntityMenuItem(worldObjectsMenu, "Pushable Stone Block", Spelunky::ENTITY_CLASS::PUSHABLE_STONE_BLOCK); 504 | AddSpawnEntityMenuItem(worldObjectsMenu, "Powder Box", Spelunky::ENTITY_CLASS::POWDER_BOX); 505 | AddSpawnEntityMenuItem(worldObjectsMenu, "Falling Platform", Spelunky::ENTITY_CLASS::FALLING_PLATFORM); 506 | AddSpawnEntityMenuItem(worldObjectsMenu, "Ice Platform", Spelunky::ENTITY_CLASS::ICE_PLATFORM); 507 | AddSpawnEntityMenuItem(worldObjectsMenu, "Flying Trap Block", Spelunky::ENTITY_CLASS::FLYING_TRAP_BLOCK); 508 | AddSpawnEntityMenuItem(worldObjectsMenu, "Flying Lava", Spelunky::ENTITY_CLASS::FLYING_LAVA); 509 | AddSpawnEntityMenuItem(worldObjectsMenu, "The Worm Entrance", Spelunky::ENTITY_CLASS::WORM_ENTRANCE); 510 | AddSpawnEntityMenuItem(worldObjectsMenu, "Worm Block", Spelunky::ENTITY_CLASS::WORM_BLOCK); 511 | AddSpawnEntityMenuItem(worldObjectsMenu, "Honey", Spelunky::ENTITY_CLASS::HONEY); 512 | AddSpawnEntityMenuItem(worldObjectsMenu, "Spike Ball", Spelunky::ENTITY_CLASS::SPIKE_BALL); 513 | AddSpawnEntityMenuItem(worldObjectsMenu, "Static Chest", Spelunky::ENTITY_CLASS::STATIC_CHEST); 514 | AddSpawnEntityMenuItem(worldObjectsMenu, "Prize Wheel", Spelunky::ENTITY_CLASS::PRIZE_WHEEL); 515 | AddSpawnEntityMenuItem(worldObjectsMenu, "Prize Wheel Flipper", Spelunky::ENTITY_CLASS::PRIZE_WHEEL_FLIPPER); 516 | AddSpawnEntityMenuItem(worldObjectsMenu, "Prize Door", Spelunky::ENTITY_CLASS::PRIZE_DOOR); 517 | AddSpawnEntityMenuItem(worldObjectsMenu, "Falling Ice", Spelunky::ENTITY_CLASS::FALLING_ICE); 518 | AddSpawnEntityMenuItem(worldObjectsMenu, "Force Field Beam", Spelunky::ENTITY_CLASS::FORCE_FIELD_BEAM); 519 | AddSpawnEntityMenuItem(worldObjectsMenu, "Coffin", Spelunky::ENTITY_CLASS::COFFIN); 520 | AddSpawnEntityMenuItem(worldObjectsMenu, "Spaceship Platform", Spelunky::ENTITY_CLASS::SPACESHIP_PLATFORM); 521 | AddSpawnEntityMenuItem(worldObjectsMenu, "Spaceship Elevator", Spelunky::ENTITY_CLASS::SPACESHIP_ELEVATOR); 522 | AddSpawnEntityMenuItem(worldObjectsMenu, "Spaceship Light", Spelunky::ENTITY_CLASS::SPACESHIP_LIGHT); 523 | AddSpawnEntityMenuItem(worldObjectsMenu, "Spider Web Ball", Spelunky::ENTITY_CLASS::SPIDER_WEB_BALL); 524 | AddSpawnEntityMenuItem(worldObjectsMenu, "Ankh Glow", Spelunky::ENTITY_CLASS::ANKH_GLOW); 525 | AddSpawnEntityMenuItem(worldObjectsMenu, "Unlit Wall Torch", Spelunky::ENTITY_CLASS::UNLIT_WALL_TORCH); 526 | AddSpawnEntityMenuItem(worldObjectsMenu, "Invisable Block", Spelunky::ENTITY_CLASS::INVISABLE_BLOCK); 527 | AddSpawnEntityMenuItem(worldObjectsMenu, "Tiny Fire", Spelunky::ENTITY_CLASS::TINY_FIRE); 528 | AddSpawnEntityMenuItem(worldObjectsMenu, "Small Fire", Spelunky::ENTITY_CLASS::SMALL_FIRE); 529 | AddSpawnEntityMenuItem(worldObjectsMenu, "Torch Fire", Spelunky::ENTITY_CLASS::TORCH_FIRE); 530 | 531 | 532 | //AI objects menu 533 | 534 | Menu* aiObjectsMenu = new Menu("AI Objects"); 535 | 536 | AddSpawnEntityMenuItem(aiObjectsMenu, "Rat", Spelunky::ENTITY_CLASS::RAT); 537 | AddSpawnEntityMenuItem(aiObjectsMenu, "Spiderling", Spelunky::ENTITY_CLASS::SPIDERLING); 538 | AddSpawnEntityMenuItem(aiObjectsMenu, "Baby Frog", Spelunky::ENTITY_CLASS::BABY_FROG); 539 | AddSpawnEntityMenuItem(aiObjectsMenu, "Fish", Spelunky::ENTITY_CLASS::FISH); 540 | AddSpawnEntityMenuItem(aiObjectsMenu, "Penguin", Spelunky::ENTITY_CLASS::PENGUIN); 541 | AddSpawnEntityMenuItem(aiObjectsMenu, "Locust", Spelunky::ENTITY_CLASS::LOCUST); 542 | AddSpawnEntityMenuItem(aiObjectsMenu, "Maggot", Spelunky::ENTITY_CLASS::MAGGOT); 543 | AddSpawnEntityMenuItem(aiObjectsMenu, "Snake", Spelunky::ENTITY_CLASS::SNAKE); 544 | AddSpawnEntityMenuItem(aiObjectsMenu, "Cobra", Spelunky::ENTITY_CLASS::COBRA); 545 | AddSpawnEntityMenuItem(aiObjectsMenu, "Spider", Spelunky::ENTITY_CLASS::SPIDER); 546 | AddSpawnEntityMenuItem(aiObjectsMenu, "Spinner Spider", Spelunky::ENTITY_CLASS::SPINNER_SPIDER); 547 | AddSpawnEntityMenuItem(aiObjectsMenu, "Bat", Spelunky::ENTITY_CLASS::BAT); 548 | AddSpawnEntityMenuItem(aiObjectsMenu, "Skeleton", Spelunky::ENTITY_CLASS::SKELETON); 549 | AddSpawnEntityMenuItem(aiObjectsMenu, "Monkey", Spelunky::ENTITY_CLASS::MONKEY); 550 | AddSpawnEntityMenuItem(aiObjectsMenu, "Snail", Spelunky::ENTITY_CLASS::SNAIL); 551 | AddSpawnEntityMenuItem(aiObjectsMenu, "Scorpion", Spelunky::ENTITY_CLASS::SCORPION); 552 | AddSpawnEntityMenuItem(aiObjectsMenu, "Scorpion Fly", Spelunky::ENTITY_CLASS::SCORPION_FLY); 553 | AddSpawnEntityMenuItem(aiObjectsMenu, "Mantrap", Spelunky::ENTITY_CLASS::MANTRAP); 554 | AddSpawnEntityMenuItem(aiObjectsMenu, "Bee", Spelunky::ENTITY_CLASS::BEE); 555 | AddSpawnEntityMenuItem(aiObjectsMenu, "Frog", Spelunky::ENTITY_CLASS::FROG); 556 | AddSpawnEntityMenuItem(aiObjectsMenu, "Fire Frog", Spelunky::ENTITY_CLASS::FIRE_FROG); 557 | AddSpawnEntityMenuItem(aiObjectsMenu, "Piranha", Spelunky::ENTITY_CLASS::PIRANHA); 558 | AddSpawnEntityMenuItem(aiObjectsMenu, "Shopkeeper", Spelunky::ENTITY_CLASS::SHOPKEEPER); 559 | AddSpawnEntityMenuItem(aiObjectsMenu, "Caveman", Spelunky::ENTITY_CLASS::CAVEMAN); 560 | AddSpawnEntityMenuItem(aiObjectsMenu, "Tiki Man", Spelunky::ENTITY_CLASS::TIKI_MAN); 561 | AddSpawnEntityMenuItem(aiObjectsMenu, "Green Knight", Spelunky::ENTITY_CLASS::GREEN_KNIGHT); 562 | AddSpawnEntityMenuItem(aiObjectsMenu, "The Black Knight", Spelunky::ENTITY_CLASS::THE_BLACK_KNIGHT); 563 | AddSpawnEntityMenuItem(aiObjectsMenu, "Hawk Man", Spelunky::ENTITY_CLASS::HAWK_MAN); 564 | AddSpawnEntityMenuItem(aiObjectsMenu, "Croc Man", Spelunky::ENTITY_CLASS::CROC_MAN); 565 | AddSpawnEntityMenuItem(aiObjectsMenu, "Yeti", Spelunky::ENTITY_CLASS::YETI); 566 | AddSpawnEntityMenuItem(aiObjectsMenu, "Giant Spider", Spelunky::ENTITY_CLASS::GIANT_SPIDER); 567 | AddSpawnEntityMenuItem(aiObjectsMenu, "Queen Bee", Spelunky::ENTITY_CLASS::QUEEN_BEE); 568 | AddSpawnEntityMenuItem(aiObjectsMenu, "Giant Frog", Spelunky::ENTITY_CLASS::GIANT_FROG); 569 | AddSpawnEntityMenuItem(aiObjectsMenu, "Old Bitey", Spelunky::ENTITY_CLASS::OLD_BITEY); 570 | AddSpawnEntityMenuItem(aiObjectsMenu, "Yeti King", Spelunky::ENTITY_CLASS::YETI_KING); 571 | AddSpawnEntityMenuItem(aiObjectsMenu, "Jiang Shi", Spelunky::ENTITY_CLASS::JIAN_SHI); 572 | AddSpawnEntityMenuItem(aiObjectsMenu, "Vampire", Spelunky::ENTITY_CLASS::VAMPIRE); 573 | AddSpawnEntityMenuItem(aiObjectsMenu, "Vlad", Spelunky::ENTITY_CLASS::VLAD); 574 | AddSpawnEntityMenuItem(aiObjectsMenu, "UFO", Spelunky::ENTITY_CLASS::UFO); 575 | AddSpawnEntityMenuItem(aiObjectsMenu, "Alien", Spelunky::ENTITY_CLASS::ALIEN); 576 | AddSpawnEntityMenuItem(aiObjectsMenu, "Alien Tank", Spelunky::ENTITY_CLASS::ALIEN_TANK); 577 | AddSpawnEntityMenuItem(aiObjectsMenu, "Alien Lord", Spelunky::ENTITY_CLASS::ALIEN_LORD); 578 | AddSpawnEntityMenuItem(aiObjectsMenu, "Alien Queen", Spelunky::ENTITY_CLASS::ALIEN_QUEEN); 579 | AddSpawnEntityMenuItem(aiObjectsMenu, "Background Alien", Spelunky::ENTITY_CLASS::BACKGROUND_ALIEN); 580 | AddSpawnEntityMenuItem(aiObjectsMenu, "Turret", Spelunky::ENTITY_CLASS::TURRET); 581 | AddSpawnEntityMenuItem(aiObjectsMenu, "Golden Monkey", Spelunky::ENTITY_CLASS::GOLDEN_MONKEY); 582 | AddSpawnEntityMenuItem(aiObjectsMenu, "Damsel", Spelunky::ENTITY_CLASS::DAMSEL); 583 | AddSpawnEntityMenuItem(aiObjectsMenu, "Succubus", Spelunky::ENTITY_CLASS::SUCCUBUS); 584 | AddSpawnEntityMenuItem(aiObjectsMenu, "Ghost", Spelunky::ENTITY_CLASS::GHOST); 585 | AddSpawnEntityMenuItem(aiObjectsMenu, "Fly", Spelunky::ENTITY_CLASS::FLY); 586 | AddSpawnEntityMenuItem(aiObjectsMenu, "Mummy", Spelunky::ENTITY_CLASS::MUMMY); 587 | AddSpawnEntityMenuItem(aiObjectsMenu, "Mammoth", Spelunky::ENTITY_CLASS::MAMMOTH); 588 | AddSpawnEntityMenuItem(aiObjectsMenu, "Scarab", Spelunky::ENTITY_CLASS::SCARAB); 589 | AddSpawnEntityMenuItem(aiObjectsMenu, "Unknown 2", Spelunky::ENTITY_CLASS::UNKNOWN_2); 590 | AddSpawnEntityMenuItem(aiObjectsMenu, "Imp", Spelunky::ENTITY_CLASS::IMP); 591 | AddSpawnEntityMenuItem(aiObjectsMenu, "Devil", Spelunky::ENTITY_CLASS::DEVIL); 592 | AddSpawnEntityMenuItem(aiObjectsMenu, "Bacterium", Spelunky::ENTITY_CLASS::BACTERIUM); 593 | AddSpawnEntityMenuItem(aiObjectsMenu, "Worm Egg", Spelunky::ENTITY_CLASS::WORM_EGG); 594 | AddSpawnEntityMenuItem(aiObjectsMenu, "Worm Baby", Spelunky::ENTITY_CLASS::WORM_BABY); 595 | AddSpawnEntityMenuItem(aiObjectsMenu, "The Worm Activated", Spelunky::ENTITY_CLASS::WORM_ACTIVATED); 596 | AddSpawnEntityMenuItem(aiObjectsMenu, "Anubis", Spelunky::ENTITY_CLASS::ANUBIS); 597 | AddSpawnEntityMenuItem(aiObjectsMenu, "Anubis II", Spelunky::ENTITY_CLASS::ANUBIS_II); 598 | AddSpawnEntityMenuItem(aiObjectsMenu, "Horse Head", Spelunky::ENTITY_CLASS::HORSE_HEAD); 599 | AddSpawnEntityMenuItem(aiObjectsMenu, "Ox Face", Spelunky::ENTITY_CLASS::OX_FACE); 600 | AddSpawnEntityMenuItem(aiObjectsMenu, "King Yama", Spelunky::ENTITY_CLASS::KING_YAMA); 601 | AddSpawnEntityMenuItem(aiObjectsMenu, "Olmec", Spelunky::ENTITY_CLASS::OLMEC); 602 | AddSpawnEntityMenuItem(aiObjectsMenu, "Watching Ball", Spelunky::ENTITY_CLASS::WATCHING_BALL); 603 | AddSpawnEntityMenuItem(aiObjectsMenu, "Camel", Spelunky::ENTITY_CLASS::CAMEL); 604 | AddSpawnEntityMenuItem(aiObjectsMenu, "Tunnel Man", Spelunky::ENTITY_CLASS::TUNNEL_MAN); 605 | AddSpawnEntityMenuItem(aiObjectsMenu, "Yang", Spelunky::ENTITY_CLASS::YANG); 606 | 607 | 608 | //Throwable objects menu 609 | 610 | Menu* throwableObjectsMenu = new Menu("Throwable Objects"); 611 | 612 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Live Bomb", Spelunky::ENTITY_CLASS::LIVE_BOMB); 613 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Stone", Spelunky::ENTITY_CLASS::STONE); 614 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Skull", Spelunky::ENTITY_CLASS::SKULL); 615 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Pot", Spelunky::ENTITY_CLASS::POT); 616 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Arrow", Spelunky::ENTITY_CLASS::ARROW); 617 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Crate", Spelunky::ENTITY_CLASS::CRATE); 618 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Pot", Spelunky::ENTITY_CLASS::POT); 619 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Chest", Spelunky::ENTITY_CLASS::CHEST); 620 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Gold Chest", Spelunky::ENTITY_CLASS::GOLD_CHEST); 621 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Gold Key", Spelunky::ENTITY_CLASS::GOLD_KEY); 622 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Lamp", Spelunky::ENTITY_CLASS::LAMP); 623 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Flare", Spelunky::ENTITY_CLASS::FLARE); 624 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Snowball", Spelunky::ENTITY_CLASS::SNOWBALL); 625 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Piranha Skeleton", Spelunky::ENTITY_CLASS::FISH_SKELETON); 626 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Imp Couldron", Spelunky::ENTITY_CLASS::IMP_COULDRON); 627 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Paper", Spelunky::ENTITY_CLASS::PAPER); 628 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Broken Mattock", Spelunky::ENTITY_CLASS::BROKEN_MATTOCK); 629 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Broken Arrow", Spelunky::ENTITY_CLASS::BROKEN_ARROW); 630 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Chain Ball", Spelunky::ENTITY_CLASS::CHAIN_BALL); 631 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Unlit Torch", Spelunky::ENTITY_CLASS::UNLIT_TORCH); 632 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Mystery Box", Spelunky::ENTITY_CLASS::MYSTERY_BOX); 633 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Skull Crown", Spelunky::ENTITY_CLASS::SKULL_CROWN); 634 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Eggplant", Spelunky::ENTITY_CLASS::EGGPLANT); 635 | AddSpawnEntityMenuItem(throwableObjectsMenu, "Idol", Spelunky::ENTITY_CLASS::IDOL); 636 | 637 | 638 | //Weapon objects menu 639 | 640 | Menu* weaponObjectsMenu = new Menu("Weapon Objects"); 641 | 642 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Mattock", Spelunky::ENTITY_CLASS::MATTOCK); 643 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Boomerang", Spelunky::ENTITY_CLASS::BOOMERANG); 644 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Machete", Spelunky::ENTITY_CLASS::MACHETE); 645 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Crysknife", Spelunky::ENTITY_CLASS::CRYSKNIFE); 646 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Web Gun", Spelunky::ENTITY_CLASS::WEB_GUN); 647 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Shotgun", Spelunky::ENTITY_CLASS::SHOTGUN); 648 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Freeze Ray", Spelunky::ENTITY_CLASS::FREEZE_RAY); 649 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Plasma Cannon", Spelunky::ENTITY_CLASS::PLASMA_CANNON); 650 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Scepter", Spelunky::ENTITY_CLASS::SCEPTER); 651 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Camera", Spelunky::ENTITY_CLASS::CAMERA); 652 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Teleporter", Spelunky::ENTITY_CLASS::TELEPORTER); 653 | AddSpawnEntityMenuItem(weaponObjectsMenu, "Shield", Spelunky::ENTITY_CLASS::SHIELD); 654 | 655 | 656 | //Accessory objects menu 657 | 658 | Menu* accessoryObjectsMenu = new Menu("Accessory Objects"); 659 | 660 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Black Box Accessory", Spelunky::ENTITY_CLASS::BLACK_BOX_ACCESSORY); 661 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Ropes", Spelunky::ENTITY_CLASS::ROPES); 662 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Bomb Bag", Spelunky::ENTITY_CLASS::BOMB_BAG); 663 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Bomb Box", Spelunky::ENTITY_CLASS::BOMB_BOX); 664 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Bomb Paste", Spelunky::ENTITY_CLASS::BOMB_PASTE); 665 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Spectacles", Spelunky::ENTITY_CLASS::SPECTACLE); 666 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Climbing Gloves", Spelunky::ENTITY_CLASS::CLIMBING_GLOVES); 667 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Pitcher's Mitt", Spelunky::ENTITY_CLASS::PITCHERS_MITT); 668 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Spring Shoes", Spelunky::ENTITY_CLASS::SPRING_SHOES); 669 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Spike Shoes", Spelunky::ENTITY_CLASS::SPIKE_SHOES); 670 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Compass", Spelunky::ENTITY_CLASS::COMPASS); 671 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Crysknife", Spelunky::ENTITY_CLASS::CRYSKNIFE); 672 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Parachute", Spelunky::ENTITY_CLASS::PARACHUTE); 673 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Cape", Spelunky::ENTITY_CLASS::CAPE); 674 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Jetpack", Spelunky::ENTITY_CLASS::JETPACK); 675 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Royal Jelly", Spelunky::ENTITY_CLASS::ROYAL_JELLY); 676 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Kapala", Spelunky::ENTITY_CLASS::KAPALA); 677 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Udjat Eye", Spelunky::ENTITY_CLASS::UDJAT_EYE); 678 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Ankh", Spelunky::ENTITY_CLASS::ANKH); 679 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Hedjet", Spelunky::ENTITY_CLASS::HEDJET); 680 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Book of the Dead", Spelunky::ENTITY_CLASS::BOOK_OF_THE_DEAD); 681 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Vlad's Cape", Spelunky::ENTITY_CLASS::VLADS_CAPE); 682 | AddSpawnEntityMenuItem(accessoryObjectsMenu, "Vlad's Amulet", Spelunky::ENTITY_CLASS::VLADS_AMULET); 683 | 684 | 685 | //Gold objects menu 686 | 687 | Menu* goldObjectsMenu = new Menu("Gold Objects"); 688 | 689 | AddSpawnEntityMenuItem(goldObjectsMenu, "Coin", Spelunky::ENTITY_CLASS::COIN); 690 | AddSpawnEntityMenuItem(goldObjectsMenu, "Small Gold Nugget", Spelunky::ENTITY_CLASS::SMALL_GOLD_NUGGET); 691 | AddSpawnEntityMenuItem(goldObjectsMenu, "Large Gold Nugget", Spelunky::ENTITY_CLASS::LARGE_GOLD_NUGGET); 692 | AddSpawnEntityMenuItem(goldObjectsMenu, "Gold Bar", Spelunky::ENTITY_CLASS::GOLD_BAR); 693 | AddSpawnEntityMenuItem(goldObjectsMenu, "Stack of Gold Bars", Spelunky::ENTITY_CLASS::STACK_OF_GOLD_BARS); 694 | AddSpawnEntityMenuItem(goldObjectsMenu, "Small Emerald", Spelunky::ENTITY_CLASS::SMALL_EMERALD); 695 | AddSpawnEntityMenuItem(goldObjectsMenu, "Large Emerald", Spelunky::ENTITY_CLASS::LARGE_EMERALD); 696 | AddSpawnEntityMenuItem(goldObjectsMenu, "Small Sapphire", Spelunky::ENTITY_CLASS::SMALL_SAPPHIRE); 697 | AddSpawnEntityMenuItem(goldObjectsMenu, "Large Sapphire", Spelunky::ENTITY_CLASS::LARGE_SAPPHIRE); 698 | AddSpawnEntityMenuItem(goldObjectsMenu, "Small Ruby", Spelunky::ENTITY_CLASS::SMALL_RUBY); 699 | AddSpawnEntityMenuItem(goldObjectsMenu, "Large Ruby", Spelunky::ENTITY_CLASS::LARGE_RUBY); 700 | AddSpawnEntityMenuItem(goldObjectsMenu, "Natural Diamond", Spelunky::ENTITY_CLASS::NATURAL_DIAMOND); 701 | AddSpawnEntityMenuItem(goldObjectsMenu, "Skull Crown", Spelunky::ENTITY_CLASS::SKULL_CROWN); 702 | AddSpawnEntityMenuItem(goldObjectsMenu, "Scarab", Spelunky::ENTITY_CLASS::SCARAB); 703 | 704 | 705 | //Player objects menu 706 | 707 | Menu* playerObjectsMenu = new Menu("Player Objects"); 708 | 709 | AddSpawnEntityMenuItem(playerObjectsMenu, "Live Bomb", Spelunky::ENTITY_CLASS::LIVE_BOMB); 710 | AddSpawnEntityMenuItem(playerObjectsMenu, "Attached Rope", Spelunky::ENTITY_CLASS::ATTACHED_ROPE); 711 | AddSpawnEntityMenuItem(playerObjectsMenu, "Used Parachute", Spelunky::ENTITY_CLASS::USED_PARACHUTE); 712 | AddSpawnEntityMenuItem(playerObjectsMenu, "White Flag", Spelunky::ENTITY_CLASS::WHITE_FLAG); 713 | AddSpawnEntityMenuItem(playerObjectsMenu, "Chain Ball", Spelunky::ENTITY_CLASS::CHAIN_BALL); 714 | 715 | 716 | //Container objects menu 717 | 718 | Menu* containerObjectsMenu = new Menu("Container Objects"); 719 | 720 | AddSpawnEntityMenuItem(containerObjectsMenu, "Crate", Spelunky::ENTITY_CLASS::CRATE); 721 | AddSpawnEntityMenuItem(containerObjectsMenu, "Pot", Spelunky::ENTITY_CLASS::POT); 722 | AddSpawnEntityMenuItem(containerObjectsMenu, "Chest", Spelunky::ENTITY_CLASS::CHEST); 723 | AddSpawnEntityMenuItem(containerObjectsMenu, "Gold Chest", Spelunky::ENTITY_CLASS::GOLD_CHEST); 724 | AddSpawnEntityMenuItem(containerObjectsMenu, "Mystery Box", Spelunky::ENTITY_CLASS::MYSTERY_BOX); 725 | 726 | 727 | //Effect objects menu 728 | 729 | Menu* effectObjectsMenu = new Menu("Effect Objects"); 730 | 731 | AddSpawnEntityMenuItem(effectObjectsMenu, "Blood", Spelunky::ENTITY_CLASS::BLOOD); 732 | AddSpawnEntityMenuItem(effectObjectsMenu, "Leaf", Spelunky::ENTITY_CLASS::LEAF); 733 | AddSpawnEntityMenuItem(effectObjectsMenu, "Dirt Break", Spelunky::ENTITY_CLASS::DIRT_BREAK); 734 | AddSpawnEntityMenuItem(effectObjectsMenu, "Metal Break", Spelunky::ENTITY_CLASS::METAL_BREAK); 735 | AddSpawnEntityMenuItem(effectObjectsMenu, "Ice Break", Spelunky::ENTITY_CLASS::ICE_BREAK); 736 | AddSpawnEntityMenuItem(effectObjectsMenu, "Smoke 1", Spelunky::ENTITY_CLASS::SMOKE_1); 737 | AddSpawnEntityMenuItem(effectObjectsMenu, "Smoke 2", Spelunky::ENTITY_CLASS::SMOKE_2); 738 | AddSpawnEntityMenuItem(effectObjectsMenu, "Unknown 1", Spelunky::ENTITY_CLASS::UNKNOWN_1); 739 | AddSpawnEntityMenuItem(effectObjectsMenu, "Flying Lava", Spelunky::ENTITY_CLASS::FLYING_LAVA); 740 | AddSpawnEntityMenuItem(effectObjectsMenu, "Falling Water", Spelunky::ENTITY_CLASS::FALLING_WATER); 741 | AddSpawnEntityMenuItem(effectObjectsMenu, "Bee Parts", Spelunky::ENTITY_CLASS::BEE_PARTS); 742 | AddSpawnEntityMenuItem(effectObjectsMenu, "Fire", Spelunky::ENTITY_CLASS::FIRE); 743 | AddSpawnEntityMenuItem(effectObjectsMenu, "String", Spelunky::ENTITY_CLASS::STRING); 744 | AddSpawnEntityMenuItem(effectObjectsMenu, "Firework", Spelunky::ENTITY_CLASS::FIREWORK); 745 | AddSpawnEntityMenuItem(effectObjectsMenu, "Alien Queen Ring", Spelunky::ENTITY_CLASS::ALIEN_QUEEN_RING); 746 | AddSpawnEntityMenuItem(effectObjectsMenu, "Explosion", Spelunky::ENTITY_CLASS::EXPLOSION); 747 | AddSpawnEntityMenuItem(effectObjectsMenu, "Red Ball", Spelunky::ENTITY_CLASS::RED_BALL); 748 | AddSpawnEntityMenuItem(effectObjectsMenu, "Spring Rings", Spelunky::ENTITY_CLASS::SPRING_RINGS); 749 | AddSpawnEntityMenuItem(effectObjectsMenu, "Spelunker Teleport", Spelunky::ENTITY_CLASS::SPELUNKER_TELEPORT); 750 | AddSpawnEntityMenuItem(effectObjectsMenu, "Tiny Fire", Spelunky::ENTITY_CLASS::TINY_FIRE); 751 | AddSpawnEntityMenuItem(effectObjectsMenu, "Small Fire", Spelunky::ENTITY_CLASS::SMALL_FIRE); 752 | AddSpawnEntityMenuItem(effectObjectsMenu, "Torch Fire", Spelunky::ENTITY_CLASS::TORCH_FIRE); 753 | 754 | 755 | //Lighting objets menu 756 | 757 | Menu* lightingObjectsMenu = new Menu("Lighting Objects"); 758 | 759 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Lamp", Spelunky::ENTITY_CLASS::LAMP); 760 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Flare", Spelunky::ENTITY_CLASS::FLARE); 761 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Flying Lava", Spelunky::ENTITY_CLASS::FLYING_LAVA); 762 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Bright Light", Spelunky::ENTITY_CLASS::BRIGHT_LIGHT); 763 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Spaceship Light", Spelunky::ENTITY_CLASS::SPACESHIP_LIGHT); 764 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Ankh Glow", Spelunky::ENTITY_CLASS::ANKH_GLOW); 765 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Unlit Wall Torch", Spelunky::ENTITY_CLASS::UNLIT_WALL_TORCH); 766 | AddSpawnEntityMenuItem(lightingObjectsMenu, "Unlit Torch", Spelunky::ENTITY_CLASS::UNLIT_TORCH); 767 | 768 | 769 | //Bullet objects menu 770 | 771 | Menu* bulletObjectsMenu = new Menu("Bullet Objects"); 772 | 773 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Shotgun Shot", Spelunky::ENTITY_CLASS::SHOTGUN_SHOT); 774 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Spider Web Shot", Spelunky::ENTITY_CLASS::SPIDER_WEB_SHOT); 775 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Scratch", Spelunky::ENTITY_CLASS::SCRATCH); 776 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Alien Shot", Spelunky::ENTITY_CLASS::ALIEN_SHOT); 777 | AddSpawnEntityMenuItem(bulletObjectsMenu, "UFO Shot", Spelunky::ENTITY_CLASS::UFO_SHOT); 778 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Acid Bobble", Spelunky::ENTITY_CLASS::ACID_BOBBLE); 779 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Acid Drop", Spelunky::ENTITY_CLASS::ACID_DROP); 780 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Ice Energy Shot", Spelunky::ENTITY_CLASS::ICE_ENERGY_SHOT); 781 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Turret Shot", Spelunky::ENTITY_CLASS::TURRET_SHOT); 782 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Olmec Orb", Spelunky::ENTITY_CLASS::OLMEC_ORB); 783 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Alien Target", Spelunky::ENTITY_CLASS::ALIEN_TARGET); 784 | AddSpawnEntityMenuItem(bulletObjectsMenu, "Alien Target Shot", Spelunky::ENTITY_CLASS::ALIEN_TARGET_SHOT); 785 | 786 | 787 | //Broken objects menu 788 | 789 | Menu* brokenObjectsMenu = new Menu("Broken Objects"); 790 | 791 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Spritesheet 1", Spelunky::ENTITY_CLASS::SPRITESHEET_1); 792 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Spritesheet 2", Spelunky::ENTITY_CLASS::SPRITESHEET_2); 793 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Spritesheet 3", Spelunky::ENTITY_CLASS::SPRITESHEET_3); 794 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Olmec", Spelunky::ENTITY_CLASS::OLMEC); 795 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Balloon", Spelunky::ENTITY_CLASS::BALLOON); 796 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Black Box", Spelunky::ENTITY_CLASS::BLACK_BOX); 797 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Win Game", Spelunky::ENTITY_CLASS::WIN_GAME); 798 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Coffin", Spelunky::ENTITY_CLASS::COFFIN); 799 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Unknown 1", Spelunky::ENTITY_CLASS::UNKNOWN_1); 800 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Black Box Pickup", Spelunky::ENTITY_CLASS::BLACK_BOX_PICKUP); 801 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Ankh Respawn", Spelunky::ENTITY_CLASS::ANKH_RESPAWN); 802 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Black Box Rope", Spelunky::ENTITY_CLASS::BLACK_BOX_ROPE); 803 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Mystery Box", Spelunky::ENTITY_CLASS::MYSTERY_BOX); 804 | AddSpawnEntityMenuItem(brokenObjectsMenu, "King Yama's Hand", Spelunky::ENTITY_CLASS::KING_YAMAS_HAND); 805 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Force Field (crash)", Spelunky::ENTITY_CLASS::FORCE_FIELD); 806 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Journal (crash)", Spelunky::ENTITY_CLASS::JOURNAL); 807 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Olmec Intro (crash)", Spelunky::ENTITY_CLASS::OLMEC_INTRO); 808 | AddSpawnEntityMenuItem(brokenObjectsMenu, "Glass Block (crash)", Spelunky::ENTITY_CLASS::GLASS_BLOCK); 809 | 810 | 811 | //All objects menu 812 | 813 | Menu* allObjectsMenu = new Menu("All Objects (Unstable)"); 814 | 815 | for(int i = 100; i < 1100; i++) 816 | { 817 | AddSpawnEntityMenuItem(allObjectsMenu, "Object", (Spelunky::ENTITY_CLASS)i); 818 | } 819 | 820 | 821 | //Object spawner menu 822 | 823 | Menu* objectSpawnerMenu = new Menu("Object Spawner"); 824 | 825 | BoolMenuItem* cursorControlBoolMenuItem = new BoolMenuItem(objectSpawnerMenu, "Mouse Control", *isCursorControlled); 826 | cursorControlBoolMenuItem->OnSelect = [isCursorControlled](MenuItem* menuItem) 827 | { 828 | BoolMenuItem* cursorControlBoolMenuItem = (BoolMenuItem*)menuItem; 829 | 830 | *isCursorControlled = cursorControlBoolMenuItem->isOn; 831 | }; 832 | objectSpawnerMenu->AddMenuItem(cursorControlBoolMenuItem); 833 | 834 | BoolMenuItem* useCursorVelocityBoolMenuItem = new BoolMenuItem(objectSpawnerMenu, "Use Mouse Velocity", *useCursorVelocity); 835 | useCursorVelocityBoolMenuItem->OnSelect = [useCursorVelocity](MenuItem* menuItem) 836 | { 837 | BoolMenuItem* useCursorVelocityBoolMenuItem = (BoolMenuItem*)menuItem; 838 | 839 | *useCursorVelocity = useCursorVelocityBoolMenuItem->isOn; 840 | }; 841 | objectSpawnerMenu->AddMenuItem(useCursorVelocityBoolMenuItem); 842 | 843 | AddLinkMenuItem(objectSpawnerMenu, "World Objects >", worldObjectsMenu); 844 | AddLinkMenuItem(objectSpawnerMenu, "AI Objects >", aiObjectsMenu); 845 | AddLinkMenuItem(objectSpawnerMenu, "Throwable Objects >", throwableObjectsMenu); 846 | AddLinkMenuItem(objectSpawnerMenu, "Weapon Objects >", weaponObjectsMenu); 847 | AddLinkMenuItem(objectSpawnerMenu, "Accessory Objects >", accessoryObjectsMenu); 848 | AddLinkMenuItem(objectSpawnerMenu, "Gold Objects >", goldObjectsMenu); 849 | AddLinkMenuItem(objectSpawnerMenu, "Player Objects >", playerObjectsMenu); 850 | AddLinkMenuItem(objectSpawnerMenu, "Container Objects >", containerObjectsMenu); 851 | AddLinkMenuItem(objectSpawnerMenu, "Effect Objects >", effectObjectsMenu); 852 | AddLinkMenuItem(objectSpawnerMenu, "Lighting Objects >", lightingObjectsMenu); 853 | AddLinkMenuItem(objectSpawnerMenu, "Bullet Objects >", bulletObjectsMenu); 854 | AddLinkMenuItem(objectSpawnerMenu, "Broken Objects >", brokenObjectsMenu); 855 | AddLinkMenuItem(objectSpawnerMenu, "All Objects (unstable) >", allObjectsMenu); 856 | 857 | 858 | //Teleporting menu 859 | 860 | Menu* teleportingMenu = new Menu("Teleporting"); 861 | 862 | IntMenuItem* moveDistanceMenuItem = new IntMenuItem(teleportingMenu, "Move Distance", (int)*moveDistance, 1, 20, 5); 863 | moveDistanceMenuItem->OnValueChanged = [moveDistance](MenuItem* menuItem) 864 | { 865 | IntMenuItem* moveDistanceMenuItem = (IntMenuItem*)menuItem; 866 | 867 | *moveDistance = (float)moveDistanceMenuItem->value; 868 | }; 869 | teleportingMenu->AddMenuItem(moveDistanceMenuItem); 870 | 871 | AddRelativeMoveMenuItem(teleportingMenu, "Move Right", Vector2(1, 0)); 872 | AddRelativeMoveMenuItem(teleportingMenu, "Move Left", Vector2(-1, 0)); 873 | AddRelativeMoveMenuItem(teleportingMenu, "Move Up", Vector2(0, 1)); 874 | AddRelativeMoveMenuItem(teleportingMenu, "Move Down", Vector2(0, -1)); 875 | 876 | MenuItem* teleportToCursorMenuItem = new MenuItem(teleportingMenu, "Teleport To Mouse"); 877 | teleportToCursorMenuItem->OnUpdate = [](MenuItem* menuItem) 878 | { 879 | if(menuItem->IsInFocus() && Input::IsKeyPressed(VK_LBUTTON, Input::INPUT_MODE::CONTINUOUS)) 880 | { 881 | menuItem->Select(); 882 | } 883 | }; 884 | teleportToCursorMenuItem->OnSelect = [](MenuItem* menuItem) 885 | { 886 | player.Teleport(Spelunky::ScreenToWorld(Window::GetRelativeCursorPosition())); 887 | }; 888 | teleportingMenu->AddMenuItem(teleportToCursorMenuItem); 889 | 890 | 891 | //Time menu 892 | 893 | Menu* timeMenu = new Menu("Time"); 894 | 895 | BoolMenuItem* freezeTotalTimeBoolMenuItem = new BoolMenuItem(timeMenu, "Freeze Total Time", isTotalTimeFrozen); 896 | freezeTotalTimeBoolMenuItem->OnSelect = [](MenuItem* menuItem) 897 | { 898 | BoolMenuItem* freezeTotalTimeBoolMenuItem = (BoolMenuItem*)menuItem; 899 | 900 | isTotalTimeFrozen = freezeTotalTimeBoolMenuItem->isOn; 901 | frozenTotalMinutes = Spelunky::GetTotalMinutes(); 902 | frozenTotalSeconds = Spelunky::GetTotalSeconds(); 903 | }; 904 | timeMenu->AddMenuItem(freezeTotalTimeBoolMenuItem); 905 | 906 | BoolMenuItem* freezeStageTimeBoolMenuItem = new BoolMenuItem(timeMenu, "Freeze Stage Time", isStageTimeFrozen); 907 | freezeStageTimeBoolMenuItem->OnSelect = [](MenuItem* menuItem) 908 | { 909 | BoolMenuItem* freezeStageTimeBoolMenuItem = (BoolMenuItem*)menuItem; 910 | 911 | isStageTimeFrozen = freezeStageTimeBoolMenuItem->isOn; 912 | frozenStageMinutes = Spelunky::GetStageMinutes(); 913 | frozenStageSeconds = Spelunky::GetStageSeconds(); 914 | }; 915 | timeMenu->AddMenuItem(freezeStageTimeBoolMenuItem); 916 | 917 | IntMenuItem* totalMinutesIntMenuItem = new IntMenuItem(timeMenu, "Total Minutes", 0, 0, 99, 10); 918 | totalMinutesIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 919 | { 920 | IntMenuItem* totalMinutesIntMenuItem = (IntMenuItem*)menuItem; 921 | 922 | Spelunky::SetTotalMinutes(totalMinutesIntMenuItem->value); 923 | 924 | if(isTotalTimeFrozen) 925 | { 926 | frozenTotalMinutes = totalMinutesIntMenuItem->value; 927 | } 928 | }; 929 | totalMinutesIntMenuItem->OnUpdate = [](MenuItem* menuItem) 930 | { 931 | IntMenuItem* totalMinutesIntMenuItem = (IntMenuItem*)menuItem; 932 | 933 | totalMinutesIntMenuItem->value = Spelunky::GetTotalMinutes(); 934 | }; 935 | timeMenu->AddMenuItem(totalMinutesIntMenuItem); 936 | 937 | IntMenuItem* totalSecondsIntMenuItem = new IntMenuItem(timeMenu, "Total Seconds", 0, 0, 59, 5); 938 | totalSecondsIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 939 | { 940 | IntMenuItem* totalSecondsIntMenuItem = (IntMenuItem*)menuItem; 941 | 942 | Spelunky::SetTotalSeconds(totalSecondsIntMenuItem->value); 943 | 944 | if(isTotalTimeFrozen) 945 | { 946 | frozenTotalSeconds = totalSecondsIntMenuItem->value; 947 | } 948 | }; 949 | totalSecondsIntMenuItem->OnUpdate = [](MenuItem* menuItem) 950 | { 951 | IntMenuItem* totalSecondsIntMenuItem = (IntMenuItem*)menuItem; 952 | 953 | totalSecondsIntMenuItem->value = Spelunky::GetTotalSeconds(); 954 | }; 955 | timeMenu->AddMenuItem(totalSecondsIntMenuItem); 956 | 957 | IntMenuItem* stageMinutesIntMenuItem = new IntMenuItem(timeMenu, "Stage Minutes", 0, 0, 99, 10); 958 | stageMinutesIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 959 | { 960 | IntMenuItem* stageMinutesIntMenuItem = (IntMenuItem*)menuItem; 961 | 962 | Spelunky::SetStageMinutes(stageMinutesIntMenuItem->value); 963 | 964 | if(isStageTimeFrozen) 965 | { 966 | frozenStageMinutes = stageMinutesIntMenuItem->value; 967 | } 968 | }; 969 | stageMinutesIntMenuItem->OnUpdate = [](MenuItem* menuItem) 970 | { 971 | IntMenuItem* stageMinutesIntMenuItem = (IntMenuItem*)menuItem; 972 | 973 | stageMinutesIntMenuItem->value = Spelunky::GetStageMinutes(); 974 | }; 975 | timeMenu->AddMenuItem(stageMinutesIntMenuItem); 976 | 977 | IntMenuItem* stageSecondsIntMenuItem = new IntMenuItem(timeMenu, "Stage Seconds", 0, 0, 59, 5); 978 | stageSecondsIntMenuItem->OnValueChanged = [](MenuItem* menuItem) 979 | { 980 | IntMenuItem* stageSecondsIntMenuItem = (IntMenuItem*)menuItem; 981 | 982 | Spelunky::SetStageSeconds(stageSecondsIntMenuItem->value); 983 | 984 | if(isStageTimeFrozen) 985 | { 986 | frozenStageSeconds = stageSecondsIntMenuItem->value; 987 | } 988 | }; 989 | stageSecondsIntMenuItem->OnUpdate = [](MenuItem* menuItem) 990 | { 991 | IntMenuItem* stageSecondsIntMenuItem = (IntMenuItem*)menuItem; 992 | 993 | stageSecondsIntMenuItem->value = Spelunky::GetStageSeconds(); 994 | }; 995 | timeMenu->AddMenuItem(stageSecondsIntMenuItem); 996 | 997 | 998 | //Sound player menu 999 | 1000 | Menu* soundPlayerMenu = new Menu("Sound Player"); 1001 | 1002 | AddSoundMenuItem(soundPlayerMenu, "alien_jump.wav"); 1003 | AddSoundMenuItem(soundPlayerMenu, "alienexplosion.wav"); 1004 | AddSoundMenuItem(soundPlayerMenu, "angry_kali.wav"); 1005 | AddSoundMenuItem(soundPlayerMenu, "ani_squeak.wav"); 1006 | AddSoundMenuItem(soundPlayerMenu, "ankhbreak.wav"); 1007 | AddSoundMenuItem(soundPlayerMenu, "ankhflash.wav"); 1008 | AddSoundMenuItem(soundPlayerMenu, "ankhflashback.wav"); 1009 | AddSoundMenuItem(soundPlayerMenu, "anubisII_appear.wav"); 1010 | AddSoundMenuItem(soundPlayerMenu, "anubisII_summons.wav"); 1011 | AddSoundMenuItem(soundPlayerMenu, "armor_break.wav"); 1012 | AddSoundMenuItem(soundPlayerMenu, "arrowhitwall.wav"); 1013 | AddSoundMenuItem(soundPlayerMenu, "arrowshot.wav"); 1014 | AddSoundMenuItem(soundPlayerMenu, "batflap.wav"); 1015 | AddSoundMenuItem(soundPlayerMenu, "batoneflap.wav"); 1016 | AddSoundMenuItem(soundPlayerMenu, "bee.wav"); 1017 | AddSoundMenuItem(soundPlayerMenu, "bee2.wav"); 1018 | AddSoundMenuItem(soundPlayerMenu, "bee3.wav"); 1019 | AddSoundMenuItem(soundPlayerMenu, "blockfall.wav"); 1020 | AddSoundMenuItem(soundPlayerMenu, "blocksmash.wav"); 1021 | AddSoundMenuItem(soundPlayerMenu, "bomb_glue.wav"); 1022 | AddSoundMenuItem(soundPlayerMenu, "bomb_timer.wav"); 1023 | AddSoundMenuItem(soundPlayerMenu, "bone_shatter.wav"); 1024 | AddSoundMenuItem(soundPlayerMenu, "boomerang_loop.wav"); 1025 | AddSoundMenuItem(soundPlayerMenu, "bouldercoming.wav"); 1026 | AddSoundMenuItem(soundPlayerMenu, "boulderhit.wav"); 1027 | AddSoundMenuItem(soundPlayerMenu, "boulderhit2.wav"); 1028 | AddSoundMenuItem(soundPlayerMenu, "boulderhit3.wav"); 1029 | AddSoundMenuItem(soundPlayerMenu, "boulderhit4.wav"); 1030 | AddSoundMenuItem(soundPlayerMenu, "bounce.wav"); 1031 | AddSoundMenuItem(soundPlayerMenu, "bounce_light.wav"); 1032 | AddSoundMenuItem(soundPlayerMenu, "camera.wav"); 1033 | AddSoundMenuItem(soundPlayerMenu, "cape.wav"); 1034 | AddSoundMenuItem(soundPlayerMenu, "catch_boomerang.wav"); 1035 | AddSoundMenuItem(soundPlayerMenu, "chaching.wav"); 1036 | AddSoundMenuItem(soundPlayerMenu, "char_unlock.wav"); 1037 | AddSoundMenuItem(soundPlayerMenu, "chestopen.wav"); 1038 | AddSoundMenuItem(soundPlayerMenu, "chime.wav"); 1039 | AddSoundMenuItem(soundPlayerMenu, "chime3.wav"); 1040 | AddSoundMenuItem(soundPlayerMenu, "chimp_attack.wav"); 1041 | AddSoundMenuItem(soundPlayerMenu, "chimp_bounce.wav"); 1042 | AddSoundMenuItem(soundPlayerMenu, "chute.wav"); 1043 | AddSoundMenuItem(soundPlayerMenu, "coinsdrop.wav"); 1044 | AddSoundMenuItem(soundPlayerMenu, "collect.wav"); 1045 | AddSoundMenuItem(soundPlayerMenu, "crateopen.wav"); 1046 | AddSoundMenuItem(soundPlayerMenu, "cricket.wav"); 1047 | AddSoundMenuItem(soundPlayerMenu, "crushhit.wav"); 1048 | AddSoundMenuItem(soundPlayerMenu, "crysknife.wav"); 1049 | AddSoundMenuItem(soundPlayerMenu, "damsel_dog.wav"); 1050 | AddSoundMenuItem(soundPlayerMenu, "damsel_female.wav"); 1051 | AddSoundMenuItem(soundPlayerMenu, "damsel_male.wav"); 1052 | AddSoundMenuItem(soundPlayerMenu, "damsel_sloth.wav"); 1053 | AddSoundMenuItem(soundPlayerMenu, "damsel_water.wav"); 1054 | AddSoundMenuItem(soundPlayerMenu, "demon.wav"); 1055 | AddSoundMenuItem(soundPlayerMenu, "deposit.wav"); 1056 | AddSoundMenuItem(soundPlayerMenu, "dm_go.wav"); 1057 | AddSoundMenuItem(soundPlayerMenu, "dm_jump.wav"); 1058 | AddSoundMenuItem(soundPlayerMenu, "dm_point.wav"); 1059 | AddSoundMenuItem(soundPlayerMenu, "dm_ready.wav"); 1060 | AddSoundMenuItem(soundPlayerMenu, "dm_winner.wav"); 1061 | AddSoundMenuItem(soundPlayerMenu, "doorcrack.wav"); 1062 | AddSoundMenuItem(soundPlayerMenu, "doorcrack2.wav"); 1063 | AddSoundMenuItem(soundPlayerMenu, "doorglow.wav"); 1064 | AddSoundMenuItem(soundPlayerMenu, "down.wav"); 1065 | AddSoundMenuItem(soundPlayerMenu, "eggplant.wav"); 1066 | AddSoundMenuItem(soundPlayerMenu, "end_chest.wav"); 1067 | AddSoundMenuItem(soundPlayerMenu, "eruption.wav"); 1068 | AddSoundMenuItem(soundPlayerMenu, "eyeblink.wav"); 1069 | AddSoundMenuItem(soundPlayerMenu, "fadein.wav"); 1070 | AddSoundMenuItem(soundPlayerMenu, "fadeout.wav"); 1071 | AddSoundMenuItem(soundPlayerMenu, "fly_loop.wav"); 1072 | AddSoundMenuItem(soundPlayerMenu, "forcefield.wav"); 1073 | AddSoundMenuItem(soundPlayerMenu, "freezeray.wav"); 1074 | AddSoundMenuItem(soundPlayerMenu, "frog1.wav"); 1075 | AddSoundMenuItem(soundPlayerMenu, "frog2.wav"); 1076 | AddSoundMenuItem(soundPlayerMenu, "frog3.wav"); 1077 | AddSoundMenuItem(soundPlayerMenu, "frog_big_land.wav"); 1078 | AddSoundMenuItem(soundPlayerMenu, "frog_bomb_charge.wav"); 1079 | AddSoundMenuItem(soundPlayerMenu, "frog_mini.wav"); 1080 | AddSoundMenuItem(soundPlayerMenu, "frozen.wav"); 1081 | AddSoundMenuItem(soundPlayerMenu, "fwboom.wav"); 1082 | AddSoundMenuItem(soundPlayerMenu, "fwshot.wav"); 1083 | AddSoundMenuItem(soundPlayerMenu, "gem1.wav"); 1084 | AddSoundMenuItem(soundPlayerMenu, "gem2.wav"); 1085 | AddSoundMenuItem(soundPlayerMenu, "gem3.wav"); 1086 | AddSoundMenuItem(soundPlayerMenu, "gem4.wav"); 1087 | AddSoundMenuItem(soundPlayerMenu, "gem5.wav"); 1088 | AddSoundMenuItem(soundPlayerMenu, "ghostloop.wav"); 1089 | AddSoundMenuItem(soundPlayerMenu, "gold_poop.wav"); 1090 | AddSoundMenuItem(soundPlayerMenu, "grab.wav"); 1091 | AddSoundMenuItem(soundPlayerMenu, "grunt01.wav"); 1092 | AddSoundMenuItem(soundPlayerMenu, "grunt02.wav"); 1093 | AddSoundMenuItem(soundPlayerMenu, "grunt03.wav"); 1094 | AddSoundMenuItem(soundPlayerMenu, "grunt04.wav"); 1095 | AddSoundMenuItem(soundPlayerMenu, "grunt05.wav"); 1096 | AddSoundMenuItem(soundPlayerMenu, "grunt06.wav"); 1097 | AddSoundMenuItem(soundPlayerMenu, "heartbeat.wav"); 1098 | AddSoundMenuItem(soundPlayerMenu, "hit.wav"); 1099 | AddSoundMenuItem(soundPlayerMenu, "homing1.wav"); 1100 | AddSoundMenuItem(soundPlayerMenu, "homing2.wav"); 1101 | AddSoundMenuItem(soundPlayerMenu, "horsehead.wav"); 1102 | AddSoundMenuItem(soundPlayerMenu, "ice_crack1.wav"); 1103 | AddSoundMenuItem(soundPlayerMenu, "ice_crack2.wav"); 1104 | AddSoundMenuItem(soundPlayerMenu, "ice_crack3.wav"); 1105 | AddSoundMenuItem(soundPlayerMenu, "idol_get6.wav"); 1106 | AddSoundMenuItem(soundPlayerMenu, "ihear_water.wav"); 1107 | AddSoundMenuItem(soundPlayerMenu, "immortal_bounce.wav"); 1108 | AddSoundMenuItem(soundPlayerMenu, "imp_flap.wav"); 1109 | AddSoundMenuItem(soundPlayerMenu, "intodoor.wav"); 1110 | AddSoundMenuItem(soundPlayerMenu, "item_drop.wav"); 1111 | AddSoundMenuItem(soundPlayerMenu, "itemsplash.wav"); 1112 | AddSoundMenuItem(soundPlayerMenu, "jelly_get.wav"); 1113 | AddSoundMenuItem(soundPlayerMenu, "jetpack_loop.wav"); 1114 | AddSoundMenuItem(soundPlayerMenu, "jump.wav"); 1115 | AddSoundMenuItem(soundPlayerMenu, "kaboom.wav"); 1116 | AddSoundMenuItem(soundPlayerMenu, "kaboombass.wav"); 1117 | AddSoundMenuItem(soundPlayerMenu, "kiss.wav"); 1118 | AddSoundMenuItem(soundPlayerMenu, "knifeattack.wav"); 1119 | AddSoundMenuItem(soundPlayerMenu, "knifepickup.wav"); 1120 | AddSoundMenuItem(soundPlayerMenu, "land.wav"); 1121 | AddSoundMenuItem(soundPlayerMenu, "lasergun.wav"); 1122 | AddSoundMenuItem(soundPlayerMenu, "lava_splash.wav"); 1123 | AddSoundMenuItem(soundPlayerMenu, "lavastream.wav"); 1124 | AddSoundMenuItem(soundPlayerMenu, "lick.wav"); 1125 | AddSoundMenuItem(soundPlayerMenu, "lobbydrum.wav"); 1126 | AddSoundMenuItem(soundPlayerMenu, "maindooropen.wav"); 1127 | AddSoundMenuItem(soundPlayerMenu, "mantrapbite.wav"); 1128 | AddSoundMenuItem(soundPlayerMenu, "match.wav"); 1129 | AddSoundMenuItem(soundPlayerMenu, "menu_enter.wav"); 1130 | AddSoundMenuItem(soundPlayerMenu, "menu_hor_l.wav"); 1131 | AddSoundMenuItem(soundPlayerMenu, "menu_hor_r.wav"); 1132 | AddSoundMenuItem(soundPlayerMenu, "menu_ret.wav"); 1133 | AddSoundMenuItem(soundPlayerMenu, "menu_selection.wav"); 1134 | AddSoundMenuItem(soundPlayerMenu, "menu_selection2.wav"); 1135 | AddSoundMenuItem(soundPlayerMenu, "menu_swipe.wav"); 1136 | AddSoundMenuItem(soundPlayerMenu, "menu_ver.wav"); 1137 | AddSoundMenuItem(soundPlayerMenu, "metal_clank.wav"); 1138 | AddSoundMenuItem(soundPlayerMenu, "mine_timer.wav"); 1139 | AddSoundMenuItem(soundPlayerMenu, "mm_amb.wav"); 1140 | AddSoundMenuItem(soundPlayerMenu, "mm_click.wav"); 1141 | AddSoundMenuItem(soundPlayerMenu, "mm_door1.wav"); 1142 | AddSoundMenuItem(soundPlayerMenu, "mm_door2.wav"); 1143 | AddSoundMenuItem(soundPlayerMenu, "mm_door3.wav"); 1144 | AddSoundMenuItem(soundPlayerMenu, "monkey_stealing.wav"); 1145 | AddSoundMenuItem(soundPlayerMenu, "msgup.wav"); 1146 | AddSoundMenuItem(soundPlayerMenu, "newshatter.wav"); 1147 | AddSoundMenuItem(soundPlayerMenu, "oxface.wav"); 1148 | AddSoundMenuItem(soundPlayerMenu, "pageget.wav"); 1149 | AddSoundMenuItem(soundPlayerMenu, "pageturn.wav"); 1150 | AddSoundMenuItem(soundPlayerMenu, "pause_in.wav"); 1151 | AddSoundMenuItem(soundPlayerMenu, "pause_out.wav"); 1152 | AddSoundMenuItem(soundPlayerMenu, "penguin.wav"); 1153 | AddSoundMenuItem(soundPlayerMenu, "pickup.wav"); 1154 | AddSoundMenuItem(soundPlayerMenu, "pushblock.wav"); 1155 | AddSoundMenuItem(soundPlayerMenu, "queenblast.wav"); 1156 | AddSoundMenuItem(soundPlayerMenu, "ropecatch.wav"); 1157 | AddSoundMenuItem(soundPlayerMenu, "ropetoss.wav"); 1158 | AddSoundMenuItem(soundPlayerMenu, "rubble.wav"); 1159 | AddSoundMenuItem(soundPlayerMenu, "rubble2.wav"); 1160 | AddSoundMenuItem(soundPlayerMenu, "rubble3.wav"); 1161 | AddSoundMenuItem(soundPlayerMenu, "rubble_bone1.wav"); 1162 | AddSoundMenuItem(soundPlayerMenu, "rubble_bone2.wav"); 1163 | AddSoundMenuItem(soundPlayerMenu, "rubble_bone3.wav"); 1164 | AddSoundMenuItem(soundPlayerMenu, "rubble_ice1.wav"); 1165 | AddSoundMenuItem(soundPlayerMenu, "rubble_ice2.wav"); 1166 | AddSoundMenuItem(soundPlayerMenu, "rubble_ice3.wav"); 1167 | AddSoundMenuItem(soundPlayerMenu, "rubble_metal1.wav"); 1168 | AddSoundMenuItem(soundPlayerMenu, "rubble_metal2.wav"); 1169 | AddSoundMenuItem(soundPlayerMenu, "rubble_metal3.wav"); 1170 | AddSoundMenuItem(soundPlayerMenu, "rubble_vase1.wav"); 1171 | AddSoundMenuItem(soundPlayerMenu, "rubble_vase2.wav"); 1172 | AddSoundMenuItem(soundPlayerMenu, "rubble_vase3.wav"); 1173 | AddSoundMenuItem(soundPlayerMenu, "sacrifice.wav"); 1174 | AddSoundMenuItem(soundPlayerMenu, "scarab_get.wav"); 1175 | AddSoundMenuItem(soundPlayerMenu, "scorpion.wav"); 1176 | AddSoundMenuItem(soundPlayerMenu, "scrollhit.wav"); 1177 | AddSoundMenuItem(soundPlayerMenu, "secret.wav"); 1178 | AddSoundMenuItem(soundPlayerMenu, "shatter.wav"); 1179 | AddSoundMenuItem(soundPlayerMenu, "shop_bells.wav"); 1180 | AddSoundMenuItem(soundPlayerMenu, "shopwheel.wav"); 1181 | AddSoundMenuItem(soundPlayerMenu, "shotgun.wav"); 1182 | AddSoundMenuItem(soundPlayerMenu, "shotgunpump.wav"); 1183 | AddSoundMenuItem(soundPlayerMenu, "skeleton_arise.wav"); 1184 | AddSoundMenuItem(soundPlayerMenu, "snail_bubble.wav"); 1185 | AddSoundMenuItem(soundPlayerMenu, "snail_bubble_burst.wav"); 1186 | AddSoundMenuItem(soundPlayerMenu, "snakebite.wav"); 1187 | AddSoundMenuItem(soundPlayerMenu, "snowball.wav"); 1188 | AddSoundMenuItem(soundPlayerMenu, "spider_jump.wav"); 1189 | AddSoundMenuItem(soundPlayerMenu, "spidershot.wav"); 1190 | AddSoundMenuItem(soundPlayerMenu, "spike_hit.wav"); 1191 | AddSoundMenuItem(soundPlayerMenu, "splash.wav"); 1192 | AddSoundMenuItem(soundPlayerMenu, "splat.wav"); 1193 | AddSoundMenuItem(soundPlayerMenu, "spring.wav"); 1194 | AddSoundMenuItem(soundPlayerMenu, "squish.wav"); 1195 | AddSoundMenuItem(soundPlayerMenu, "sr_frogburp.wav"); 1196 | AddSoundMenuItem(soundPlayerMenu, "succubus.wav"); 1197 | AddSoundMenuItem(soundPlayerMenu, "talkbutton.wav"); 1198 | AddSoundMenuItem(soundPlayerMenu, "tank.wav"); 1199 | AddSoundMenuItem(soundPlayerMenu, "teleport.wav"); 1200 | AddSoundMenuItem(soundPlayerMenu, "throw_item.wav"); 1201 | AddSoundMenuItem(soundPlayerMenu, "tikifire.wav"); 1202 | AddSoundMenuItem(soundPlayerMenu, "tikispike.wav"); 1203 | AddSoundMenuItem(soundPlayerMenu, "torchgust.wav"); 1204 | AddSoundMenuItem(soundPlayerMenu, "torchlight.wav"); 1205 | AddSoundMenuItem(soundPlayerMenu, "torchlightshort.wav"); 1206 | AddSoundMenuItem(soundPlayerMenu, "turretlaser.wav"); 1207 | AddSoundMenuItem(soundPlayerMenu, "ufo_loop.wav"); 1208 | AddSoundMenuItem(soundPlayerMenu, "ufo_shot.wav"); 1209 | AddSoundMenuItem(soundPlayerMenu, "uhoh.wav"); 1210 | AddSoundMenuItem(soundPlayerMenu, "up.wav"); 1211 | AddSoundMenuItem(soundPlayerMenu, "vanish.wav"); 1212 | AddSoundMenuItem(soundPlayerMenu, "volcanoshot.wav"); 1213 | AddSoundMenuItem(soundPlayerMenu, "vomitflies.wav"); 1214 | AddSoundMenuItem(soundPlayerMenu, "vsnake_sizzle.wav"); 1215 | AddSoundMenuItem(soundPlayerMenu, "waterstream.wav"); 1216 | AddSoundMenuItem(soundPlayerMenu, "webshot.wav"); 1217 | AddSoundMenuItem(soundPlayerMenu, "whip.wav"); 1218 | AddSoundMenuItem(soundPlayerMenu, "worm_block_destroy.wav"); 1219 | AddSoundMenuItem(soundPlayerMenu, "worm_block_regen.wav"); 1220 | AddSoundMenuItem(soundPlayerMenu, "worm_contact.wav"); 1221 | AddSoundMenuItem(soundPlayerMenu, "worm_contact2.wav"); 1222 | AddSoundMenuItem(soundPlayerMenu, "worm_contact3.wav"); 1223 | AddSoundMenuItem(soundPlayerMenu, "worm_eats.wav"); 1224 | AddSoundMenuItem(soundPlayerMenu, "worm_tounge_wiggle.wav"); 1225 | AddSoundMenuItem(soundPlayerMenu, "yama_faceoff.wav"); 1226 | AddSoundMenuItem(soundPlayerMenu, "yama_slam.wav"); 1227 | AddSoundMenuItem(soundPlayerMenu, "yamaspew.wav"); 1228 | AddSoundMenuItem(soundPlayerMenu, "yeti_roar.wav"); 1229 | AddSoundMenuItem(soundPlayerMenu, "yeti_toss.wav"); 1230 | AddSoundMenuItem(soundPlayerMenu, "zap.wav"); 1231 | AddSoundMenuItem(soundPlayerMenu, "zombie_jump.wav"); 1232 | 1233 | 1234 | //Main menu 1235 | 1236 | Menu* mainMenu = new Menu(TITLE); 1237 | 1238 | AddLinkMenuItem(mainMenu, "Player >", playerMenu); 1239 | AddLinkMenuItem(mainMenu, "Object Spawner >", objectSpawnerMenu); 1240 | AddLinkMenuItem(mainMenu, "Teleporting >", teleportingMenu); 1241 | AddLinkMenuItem(mainMenu, "Time >", timeMenu); 1242 | AddLinkMenuItem(mainMenu, "Sound Player >", soundPlayerMenu); 1243 | 1244 | Menu::previousMenu = mainMenu; 1245 | } 1246 | } 1247 | } 1248 | --------------------------------------------------------------------------------