Compare commits

...

45 Commits

Author SHA1 Message Date
Marco Tylus
31050fa2c7
Merge 8935c520c0 into b4751725a6 2026-02-10 08:58:09 +01:00
fallenoak
b4751725a6
feat(object): implement CGObject_C::AddWorldObject
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-09 15:40:23 -06:00
fallenoak
9f3160b1d2
feat(world): add CWorld::GetM2Scene 2026-02-09 15:38:48 -06:00
fallenoak
c604ae6d19
feat(ui): implement CSimpleFrame_UnregisterEvent
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-09 10:49:18 -06:00
fallenoak
17198939da
feat(ui): add FrameScript_Object::UnregisterScriptEvent 2026-02-09 10:48:58 -06:00
fallenoak
121f41d6b8
feat(ui): implement CSimpleFrame_CreateFontString 2026-02-09 08:33:24 -06:00
fallenoak
0d001d4b3f
feat(ui): implement Script_GetCVarDefault 2026-02-09 08:01:56 -06:00
fallenoak
e175894099
feat(ui): implement Script_GetNumRaidMembers 2026-02-09 06:09:41 -06:00
fallenoak
39bf2f5ad4
feat(ui): add RaidInfoRegisterScriptFunctions 2026-02-09 06:04:57 -06:00
fallenoak
8e67adc15f
feat(ui): add CGRaidInfo::NumMembers 2026-02-09 05:55:20 -06:00
fallenoak
8da307593d
feat(ui): implement Script_GetNumPartyMembers 2026-02-09 05:13:02 -06:00
fallenoak
4d003129be
feat(ui): add PartyInfoRegisterScriptFunctions 2026-02-09 05:07:34 -06:00
fallenoak
d210df2f43
feat(ui): add CGPartyInfo::NumMembers 2026-02-09 04:56:46 -06:00
fallenoak
66df4c55da
feat(ui): implement CScriptRegion_SetSize
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-08 21:45:58 -06:00
fallenoak
91da4e9680
feat(ui): add CLayoutFrame::SetSize 2026-02-08 21:45:31 -06:00
fallenoak
fabd5888a9
feat(ui): add CGGameUI::RegisterGameCVars 2026-02-08 20:37:45 -06:00
fallenoak
1fd5c5c944
feat(ui): stub Script_BNFeaturesEnabledAndConnected
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-08 13:22:15 -06:00
fallenoak
4f26eeb05c
feat(ui): stub Script_BNConnected 2026-02-08 13:18:40 -06:00
fallenoak
14d14dacb0
feat(ui): stub Script_BNFeaturesEnabled 2026-02-08 13:11:45 -06:00
fallenoak
c6ddfc0d87
feat(ui): implement Script_IsBNLogin 2026-02-08 13:07:40 -06:00
fallenoak
99a95e9db4
feat(ui): add BattlenetUI_RegisterScriptFunctions 2026-02-08 13:01:55 -06:00
fallenoak
7ec9a35b4b
feat(ui): implement Script_GetBonusBarOffset
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-08 07:16:58 -06:00
fallenoak
43895197af
feat(ui): implement Script_SetCVar 2026-02-08 06:58:15 -06:00
fallenoak
72d2c3b1a2
feat(ui): implement Script_GetPlayerTradeMoney
Some checks failed
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Has been cancelled
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Has been cancelled
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Has been cancelled
2026-02-06 22:29:43 -06:00
fallenoak
3366ea2c89
feat(ui): add TradeInfoRegisterScriptFunctions 2026-02-06 22:23:27 -06:00
fallenoak
cda8fff096
feat(ui): implement Script_GetCursorMoney
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-06 15:35:17 -06:00
fallenoak
5ee4c54827
feat(ui): implement Script_GetMoney 2026-02-06 14:04:52 -06:00
fallenoak
68ad71090e
feat(object): simplify getters in CGPlayer_C 2026-02-06 10:36:54 -06:00
fallenoak
4bf88801ed
feat(ui): implement Script_GetInventorySlotInfo
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-06 06:43:00 -06:00
fallenoak
c133d37705
feat(db): add PaperDollItemFrameRec 2026-02-06 06:23:28 -06:00
Tristan Cormier
8c850c0bd5 feat(glue): implement Script_IsShiftKeyDown
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
2026-02-05 23:14:44 -06:00
fallenoak
7dcc33bcb4
feat(object): partially implement CGPlayer_C::PostInitActivePlayer 2026-02-05 22:22:33 -06:00
fallenoak
5b88141acb
feat(object): add ClntObjMgrGetPlayerType 2026-02-05 22:22:01 -06:00
fallenoak
61303b51a2
feat(object): stub CGPlayer_C::PostInitActivePlayer 2026-02-05 22:09:52 -06:00
fallenoak
c7179026fc
feat(object): implement SkipPartialObjectUpdate 2026-02-05 22:09:25 -06:00
fallenoak
e5aab736b7
feat(ui): add CGGameUI::EnterWorld 2026-02-05 21:04:31 -06:00
fallenoak
1d364ec689
feat(ui): add CGGameUI::IsLoggingIn 2026-02-05 20:51:46 -06:00
aomizu
8935c520c0 feat: Add texture matrix transform support to Metal shaders for animated textures 2025-12-26 17:03:37 +09:00
aomizu
7cf7127810 feat: Implement color animation in Metal shaders by using diffuse and emissive vertex constants for output color. 2025-12-25 15:11:18 +09:00
aomizu
8fb51991e0 revert: remove non-metal shader init from Client.cpp 2025-12-25 13:24:07 +09:00
aomizu
7fdd22545f feat: Convert GxTex_Argb4444 textures to RGBA8 during Metal upload to simplify handling 2025-12-25 13:10:25 +09:00
aomizu
15eafe92d7 feat: Implement fog and point size in Metal shaders and refine render state processing for textures and other states. 2025-12-25 13:10:25 +09:00
aomizu
1ad3679f90 feat: Implement initial Metal graphics device with comprehensive shader system and pipeline management. 2025-12-25 13:10:25 +09:00
aomizu
81970958a8 feat: Add debug rendering pipeline to draw a triangle in the Metal backend. 2025-12-25 13:10:25 +09:00
aomizu
a9cad5238d init metal backend 2025-12-25 13:10:25 +09:00
65 changed files with 3465 additions and 38 deletions

View File

@ -32,6 +32,8 @@ if(WHOA_SYSTEM_MAC)
"-framework AppKit" "-framework AppKit"
"-framework Carbon" "-framework Carbon"
"-framework IOKit" "-framework IOKit"
"-framework Metal"
"-framework QuartzCore"
) )
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mac/MainMenu.nib DESTINATION "bin") install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mac/MainMenu.nib DESTINATION "bin")

View File

@ -0,0 +1,9 @@
#ifndef APP_MAC_ENGINE_MTL_LAYER_VIEW_H
#define APP_MAC_ENGINE_MTL_LAYER_VIEW_H
#include "app/mac/EngineGLLayerView.h"
@interface EngineMTLLayerView : EngineGLLayerView
@end
#endif

View File

@ -0,0 +1,36 @@
#include "app/mac/EngineMTLLayerView.h"
#import <QuartzCore/CAMetalLayer.h>
@implementation EngineMTLLayerView
- (CALayer*)makeBackingLayer {
return [CAMetalLayer layer];
}
- (id)initWithFrame:(NSRect)frame glWindow:(GLWindow*)window {
self = [super initWithFrame:frame glWindow:window];
if (self) {
[self setWantsLayer:YES];
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect {
// Rendering is driven by CGxDeviceMTL.
}
- (void)update {
[super update];
if (![self.layer isKindOfClass:[CAMetalLayer class]]) {
return;
}
CAMetalLayer* layer = (CAMetalLayer*)self.layer;
CGSize size = [self convertSizeToBacking:self.bounds.size];
layer.drawableSize = size;
}
@end

View File

@ -1,7 +1,9 @@
#include "app/mac/View.h" #include "app/mac/View.h"
#include "app/mac/EngineGLLayerView.h" #include "app/mac/EngineGLLayerView.h"
#include "app/mac/EngineMTLLayerView.h"
#include "app/mac/WindowCallbacks.h" #include "app/mac/WindowCallbacks.h"
#include "gx/gll/GLWindow.h" #include "gx/gll/GLWindow.h"
#include "gx/Device.hpp"
GLWindowCallbacks EngineViewCallbacks = { GLWindowCallbacks EngineViewCallbacks = {
&MacOnResized, &MacOnResized,
@ -23,5 +25,9 @@ void AssignEngineViewCallbacks(GLWindowCallbacks* callbacks) {
} }
Class GetEngineViewClass() { Class GetEngineViewClass() {
if (GxDevApi() == GxApi_Metal) {
return [EngineMTLLayerView class];
}
return [EngineGLLayerView class]; return [EngineGLLayerView class];
} }

View File

@ -2,6 +2,7 @@
#include "app/mac/MacClient.h" #include "app/mac/MacClient.h"
#include "event/Input.hpp" #include "event/Input.hpp"
#include "gx/gll/CGxDeviceGLL.hpp" #include "gx/gll/CGxDeviceGLL.hpp"
#include "gx/mtl/CGxDeviceMTL.hpp"
#include "gx/Device.hpp" #include "gx/Device.hpp"
#include "gx/Window.hpp" #include "gx/Window.hpp"
#include <bc/Debug.hpp> #include <bc/Debug.hpp>
@ -171,7 +172,11 @@ void MacOnResized(int32_t width, int32_t height, bool a3) {
return; return;
} }
static_cast<CGxDeviceGLL*>(g_theGxDevicePtr)->Resize(width, height); if (GxDevApi() == GxApi_GLL) {
static_cast<CGxDeviceGLL*>(g_theGxDevicePtr)->Resize(width, height);
} else if (GxDevApi() == GxApi_Metal) {
static_cast<CGxDeviceMTL*>(g_theGxDevicePtr)->Resize(width, height);
}
OsQueuePut(OS_INPUT_SIZE, width, height, 0, 0); OsQueuePut(OS_INPUT_SIZE, width, height, 0, 0);

View File

@ -6,6 +6,7 @@
#include "gx/Adapter.hpp" #include "gx/Adapter.hpp"
#include "gx/Device.hpp" #include "gx/Device.hpp"
#include <storm/Array.hpp> #include <storm/Array.hpp>
#include <cstdlib>
#include <cstring> #include <cstring>
static CGxDevice* s_device; static CGxDevice* s_device;
@ -417,6 +418,13 @@ void ConsoleDeviceInitialize(const char* title) {
api = GxApi_GLL; api = GxApi_GLL;
#endif #endif
#if defined(WHOA_SYSTEM_MAC)
const char* apiOverride = getenv("WHOA_GX_API");
if (apiOverride && !strcmp(apiOverride, "metal")) {
api = GxApi_Metal;
}
#endif
s_device = GxDevCreate(api, OsWindowProc, format); s_device = GxDevCreate(api, OsWindowProc, format);
// TODO // TODO

View File

@ -18,6 +18,7 @@ WowClientDB<FactionTemplateRec> g_factionTemplateDB;
WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB; WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
WowClientDB<ItemVisualsRec> g_itemVisualsDB; WowClientDB<ItemVisualsRec> g_itemVisualsDB;
WowClientDB<MapRec> g_mapDB; WowClientDB<MapRec> g_mapDB;
WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
WowClientDB<SoundEntriesRec> g_soundEntriesDB; WowClientDB<SoundEntriesRec> g_soundEntriesDB;
WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB; WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;
@ -43,6 +44,7 @@ void StaticDBLoadAll(void (*loadFn)(WowClientDB_Base*, const char*, int32_t)) {
loadFn(&g_itemDisplayInfoDB, __FILE__, __LINE__); loadFn(&g_itemDisplayInfoDB, __FILE__, __LINE__);
loadFn(&g_itemVisualsDB, __FILE__, __LINE__); loadFn(&g_itemVisualsDB, __FILE__, __LINE__);
loadFn(&g_mapDB, __FILE__, __LINE__); loadFn(&g_mapDB, __FILE__, __LINE__);
loadFn(&g_paperDollItemFrameDB, __FILE__, __LINE__);
loadFn(&g_soundEntriesDB, __FILE__, __LINE__); loadFn(&g_soundEntriesDB, __FILE__, __LINE__);
loadFn(&g_soundEntriesAdvancedDB, __FILE__, __LINE__); loadFn(&g_soundEntriesAdvancedDB, __FILE__, __LINE__);
}; };

View File

@ -19,6 +19,7 @@
#include "db/rec/ItemDisplayInfoRec.hpp" #include "db/rec/ItemDisplayInfoRec.hpp"
#include "db/rec/ItemVisualsRec.hpp" #include "db/rec/ItemVisualsRec.hpp"
#include "db/rec/MapRec.hpp" #include "db/rec/MapRec.hpp"
#include "db/rec/PaperDollItemFrameRec.hpp"
#include "db/rec/SoundEntriesRec.hpp" #include "db/rec/SoundEntriesRec.hpp"
#include "db/rec/SoundEntriesAdvancedRec.hpp" #include "db/rec/SoundEntriesAdvancedRec.hpp"
@ -39,6 +40,7 @@ extern WowClientDB<FactionTemplateRec> g_factionTemplateDB;
extern WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB; extern WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
extern WowClientDB<ItemVisualsRec> g_itemVisualsDB; extern WowClientDB<ItemVisualsRec> g_itemVisualsDB;
extern WowClientDB<MapRec> g_mapDB; extern WowClientDB<MapRec> g_mapDB;
extern WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
extern WowClientDB<SoundEntriesRec> g_soundEntriesDB; extern WowClientDB<SoundEntriesRec> g_soundEntriesDB;
extern WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB; extern WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;

View File

@ -0,0 +1,51 @@
// DO NOT EDIT: generated by whoa-autocode
#include "db/rec/PaperDollItemFrameRec.hpp"
#include "util/Locale.hpp"
#include "util/SFile.hpp"
const char* PaperDollItemFrameRec::GetFilename() {
return "DBFilesClient\\PaperDollItemFrame.dbc";
}
uint32_t PaperDollItemFrameRec::GetNumColumns() {
return 3;
}
uint32_t PaperDollItemFrameRec::GetRowSize() {
return 12;
}
bool PaperDollItemFrameRec::NeedIDAssigned() {
return true;
}
int32_t PaperDollItemFrameRec::GetID() {
return this->m_generatedID;
}
void PaperDollItemFrameRec::SetID(int32_t id) {
this->m_generatedID = id;
}
bool PaperDollItemFrameRec::Read(SFile* f, const char* stringBuffer) {
uint32_t itemButtonNameOfs;
uint32_t slotIconOfs;
if (
!SFile::Read(f, &itemButtonNameOfs, sizeof(uint32_t), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &slotIconOfs, sizeof(uint32_t), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_slotNumber, sizeof(this->m_slotNumber), nullptr, nullptr, nullptr)
) {
return false;
}
if (stringBuffer) {
this->m_itemButtonName = &stringBuffer[itemButtonNameOfs];
this->m_slotIcon = &stringBuffer[slotIconOfs];
} else {
this->m_itemButtonName = "";
this->m_slotIcon = "";
}
return true;
}

View File

@ -0,0 +1,25 @@
// DO NOT EDIT: generated by whoa-autocode
#ifndef DB_REC_PAPER_DOLL_ITEM_FRAME_REC_HPP
#define DB_REC_PAPER_DOLL_ITEM_FRAME_REC_HPP
#include <cstdint>
class SFile;
class PaperDollItemFrameRec {
public:
const char* m_itemButtonName;
const char* m_slotIcon;
int32_t m_slotNumber;
int32_t m_generatedID;
static const char* GetFilename();
static uint32_t GetNumColumns();
static uint32_t GetRowSize();
static bool NeedIDAssigned();
int32_t GetID();
void SetID(int32_t id);
bool Read(SFile* f, const char* stringBuffer);
};
#endif

View File

@ -17,7 +17,13 @@
#include <cstdint> #include <cstdint>
int32_t Script_IsShiftKeyDown(lua_State* L) { int32_t Script_IsShiftKeyDown(lua_State* L) {
WHOA_UNIMPLEMENTED(0); if (EventIsKeyDown(KEY_LSHIFT) || EventIsKeyDown(KEY_RSHIFT)) {
lua_pushnumber(L, 1.0);
} else {
lua_pushnil(L);
}
return 1;
} }
int32_t Script_GetBuildInfo(lua_State* L) { int32_t Script_GetBuildInfo(lua_State* L) {

View File

@ -18,6 +18,7 @@
#if defined(WHOA_SYSTEM_MAC) #if defined(WHOA_SYSTEM_MAC)
#include "gx/gll/CGxDeviceGLL.hpp" #include "gx/gll/CGxDeviceGLL.hpp"
#include "gx/mtl/CGxDeviceMTL.hpp"
#include "gx/mac/Display.hpp" #include "gx/mac/Display.hpp"
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/OpenGL.h> #include <OpenGL/OpenGL.h>
@ -117,6 +118,8 @@ int32_t CGxDevice::AdapterFormats(EGxApi api, TSGrowableArray<CGxFormat>& adapte
CGxDevice::OpenGlAdapterFormats(adapterFormats); CGxDevice::OpenGlAdapterFormats(adapterFormats);
} else if (api == GxApi_GLL) { } else if (api == GxApi_GLL) {
CGxDevice::GLLAdapterFormats(adapterFormats); CGxDevice::GLLAdapterFormats(adapterFormats);
} else if (api == GxApi_Metal) {
CGxDevice::OpenGlAdapterFormats(adapterFormats);
} }
#elif defined(WHOA_SYSTEM_LINUX) #elif defined(WHOA_SYSTEM_LINUX)
@ -228,6 +231,11 @@ CGxDevice* CGxDevice::NewGLL() {
auto m = SMemAlloc(sizeof(CGxDeviceGLL), __FILE__, __LINE__, 0x0); auto m = SMemAlloc(sizeof(CGxDeviceGLL), __FILE__, __LINE__, 0x0);
return new (m) CGxDeviceGLL(); return new (m) CGxDeviceGLL();
} }
CGxDevice* CGxDevice::NewMTL() {
auto m = SMemAlloc(sizeof(CGxDeviceMTL), __FILE__, __LINE__, 0x0);
return new (m) CGxDeviceMTL();
}
#endif #endif
CGxDevice* CGxDevice::NewOpenGl() { CGxDevice* CGxDevice::NewOpenGl() {

View File

@ -70,6 +70,7 @@ class CGxDevice {
#endif #endif
#if defined(WHOA_SYSTEM_MAC) #if defined(WHOA_SYSTEM_MAC)
static CGxDevice* NewGLL(); static CGxDevice* NewGLL();
static CGxDevice* NewMTL();
#endif #endif
static CGxDevice* NewOpenGl(); static CGxDevice* NewOpenGl();
static void OpenGlAdapterFormats(TSGrowableArray<CGxFormat>& adapterFormats); static void OpenGlAdapterFormats(TSGrowableArray<CGxFormat>& adapterFormats);

View File

@ -20,6 +20,7 @@ if(WHOA_SYSTEM_MAC)
file(GLOB MAC_SOURCES file(GLOB MAC_SOURCES
"gll/*.cpp" "gll/*.cpp"
"gll/*.mm" "gll/*.mm"
"mtl/*.mm"
"mac/*.cpp" "mac/*.cpp"
) )

View File

@ -24,6 +24,8 @@ CGxDevice* GxDevCreate(EGxApi api, int32_t (*windowProc)(void* window, uint32_t
device = CGxDevice::NewOpenGl(); device = CGxDevice::NewOpenGl();
} else if (api == GxApi_GLL) { } else if (api == GxApi_GLL) {
device = CGxDevice::NewGLL(); device = CGxDevice::NewGLL();
} else if (api == GxApi_Metal) {
device = CGxDevice::NewMTL();
} else { } else {
// Error // Error
} }

View File

@ -35,7 +35,8 @@ enum EGxApi {
GxApi_D3d10 = 3, GxApi_D3d10 = 3,
GxApi_D3d11 = 4, GxApi_D3d11 = 4,
GxApi_GLL = 5, GxApi_GLL = 5,
GxApis_Last = 6 GxApi_Metal = 6,
GxApis_Last = 7
}; };
enum EGxBlend { enum EGxBlend {

View File

@ -0,0 +1,81 @@
#ifndef GX_MTL_C_GX_DEVICE_MTL_HPP
#define GX_MTL_C_GX_DEVICE_MTL_HPP
#include "gx/CGxDevice.hpp"
#include "gx/gll/GLWindow.h"
class CGxBatch;
class CGxShader;
class CGxDeviceMTL : public CGxDevice {
public:
// Member variables
GLWindow m_window;
// Virtual member functions
void ITexMarkAsUpdated(CGxTex*) override;
void IRsSendToHw(EGxRenderState) override;
int32_t DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat&) override;
int32_t DeviceSetFormat(const CGxFormat&) override;
void* DeviceWindow() override;
void DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) override {};
void CapsWindowSize(CRect&) override;
void CapsWindowSizeInScreenCoords(CRect& dst) override;
void ScenePresent() override;
void SceneClear(uint32_t, CImVector) override;
void Draw(CGxBatch* batch, int32_t indexed) override;
void PoolSizeSet(CGxPool*, uint32_t) override;
char* BufLock(CGxBuf*) override;
int32_t BufUnlock(CGxBuf*, uint32_t) override;
void BufData(CGxBuf* buf, const void* data, size_t size, uintptr_t offset) override;
void TexDestroy(CGxTex* texId) override;
void IShaderCreate(CGxShader*) override;
void ShaderCreate(CGxShader*[], EGxShTarget, const char*, const char*, int32_t) override;
int32_t StereoEnabled(void) override;
void XformSetProjection(const C44Matrix& matrix) override;
// Member functions
CGxDeviceMTL();
void Resize(uint32_t width, uint32_t height);
private:
void ISetCaps(const CGxFormat& format);
void EnsureLibrary();
void BeginFrame();
void* GetPipeline(EGxVertexBufferFormat format, bool useColor, bool useSkin, bool useTex, int32_t blendMode);
void* GetPoolBuffer(CGxPool* pool);
void ITexCreate(CGxTex* texId);
void ITexUpload(CGxTex* texId);
void* GetTexture(CGxTex* texId);
void* GetSampler(CGxTex* texId);
void EnsureFallbackTexture();
void EnsureDepthTexture(uint32_t width, uint32_t height);
void* GetDepthState(bool depthTest, bool depthWrite, uint32_t depthFunc);
void* m_device = nullptr;
void* m_commandQueue = nullptr;
void* m_layer = nullptr;
void* m_shaderLibrary = nullptr;
void* m_pipelineColor[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineSolid[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineSkin[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineColorTex[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineSolidTex[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineSkinTex[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineColorTex2[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineSolidTex2[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_pipelineSkinTex2[GxVertexBufferFormats_Last][GxBlends_Last] = {};
void* m_frameCommandBuffer = nullptr;
void* m_frameEncoder = nullptr;
void* m_frameDrawable = nullptr;
uint32_t m_frameHasDraw = 0;
uint32_t m_clearMask = 0;
uint32_t m_clearColor = 0;
void* m_fallbackTexture = nullptr;
void* m_fallbackSampler = nullptr;
void* m_depthTexture = nullptr;
uint32_t m_depthWidth = 0;
uint32_t m_depthHeight = 0;
void* m_depthStates[2][2][4] = {};
};
#endif

1855
src/gx/mtl/CGxDeviceMTL.mm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -78,6 +78,11 @@ enum OUT_OF_RANGE_TYPE {
OUT_OF_RANGE_2 = 2, OUT_OF_RANGE_2 = 2,
}; };
enum PLAYER_TYPE {
PLAYER_NORMAL = 0,
PLAYER_BOT = 1,
};
enum SHEATHE_TYPE { enum SHEATHE_TYPE {
SHEATHE_0 = 0, SHEATHE_0 = 0,
SHEATHE_1 = 1, SHEATHE_1 = 1,

View File

@ -1,4 +1,5 @@
#include "object/client/CGObject_C.hpp" #include "object/client/CGObject_C.hpp"
#include "model/Model2.hpp"
#include "object/client/ObjMgr.hpp" #include "object/client/ObjMgr.hpp"
#include "world/World.hpp" #include "world/World.hpp"
@ -6,6 +7,7 @@ CGObject_C::CGObject_C(uint32_t time, CClientObjCreate& objCreate) {
// TODO // TODO
this->m_model = nullptr; this->m_model = nullptr;
this->m_worldObject = 0;
// TODO // TODO
@ -28,7 +30,52 @@ CGObject_C::~CGObject_C() {
} }
void CGObject_C::AddWorldObject() { void CGObject_C::AddWorldObject() {
// TODO if (!this->m_model) {
const char* fileName;
if (this->GetModelFileName(fileName)) {
auto model = CWorld::GetM2Scene()->CreateModel(fileName, 0);
this->SetModel(model);
model->Release();
}
}
if (!this->m_model) {
return;
}
if (ClntObjMgrGetPlayerType() != PLAYER_NORMAL) {
return;
}
if (this->m_worldObject) {
// TODO SysMsgPrintf(1, 2, "OBJECTALREADYACTIVE|0x%016I64X", this->GetGUID());
return;
}
uint32_t objFlags = 0x0;
if (this->IsA(TYPE_GAMEOBJECT)) {
objFlags |= 0x8 | 0x2 | 0x1;
} else if (this->IsA(TYPE_DYNAMICOBJECT)) {
objFlags |= 0x8 | 0x2;
} else if (this->IsA(TYPE_CORPSE)) {
// TODO
} else if (this->IsA(TYPE_UNIT)) {
// TODO
objFlags |= 0x10;
if (this->IsA(TYPE_PLAYER)) {
objFlags |= 0x20;
}
}
this->m_worldObject = CWorld::AddObject(this->GetObjectModel(), nullptr, nullptr, this->GetGUID(), 0, objFlags);
if (!this->m_inReenable && this->m_postInited) {
this->UpdateWorldObject(false);
}
} }
int32_t CGObject_C::CanBeTargetted() { int32_t CGObject_C::CanBeTargetted() {
@ -48,6 +95,14 @@ void CGObject_C::Disable() {
this->m_disableTimeMs = CWorld::GetCurTimeMs(); this->m_disableTimeMs = CWorld::GetCurTimeMs();
} }
int32_t CGObject_C::GetModelFileName(const char*& name) {
return false;
}
CM2Model* CGObject_C::GetObjectModel() {
return this->m_model;
}
int32_t CGObject_C::IsInReenable() { int32_t CGObject_C::IsInReenable() {
return this->m_inReenable; return this->m_inReenable;
} }
@ -90,6 +145,25 @@ void CGObject_C::SetDisablePending(int32_t pending) {
} }
} }
void CGObject_C::SetModel(CM2Model* model) {
// No change
if (this->m_model == model) {
return;
}
if (model) {
model->AddRef();
}
this->m_model = model;
this->SetModelFinish(model);
}
void CGObject_C::SetModelFinish(CM2Model* model) {
// TODO
}
void CGObject_C::SetObjectLocked(int32_t locked) { void CGObject_C::SetObjectLocked(int32_t locked) {
if (locked) { if (locked) {
if (this->m_lockCount != 0xFFFF) { if (this->m_lockCount != 0xFFFF) {
@ -147,3 +221,7 @@ void CGObject_C::SetTypeID(OBJECT_TYPE_ID typeID) {
break; break;
} }
} }
void CGObject_C::UpdateWorldObject(int32_t a2) {
// TODO
}

View File

@ -5,6 +5,7 @@
#include "object/client/CClientObjCreate.hpp" #include "object/client/CClientObjCreate.hpp"
#include "object/client/CGObject.hpp" #include "object/client/CGObject.hpp"
#include "util/GUID.hpp" #include "util/GUID.hpp"
#include "world/Types.hpp"
#include <storm/Hash.hpp> #include <storm/Hash.hpp>
#include <storm/List.hpp> #include <storm/List.hpp>
@ -18,6 +19,7 @@ class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID
// TODO // TODO
CM2Model* m_model; CM2Model* m_model;
// TODO // TODO
HWORLDOBJECT m_worldObject;
uint32_t m_lockCount : 16; uint32_t m_lockCount : 16;
uint32_t m_disabled : 1; uint32_t m_disabled : 1;
uint32_t m_inReenable : 1; uint32_t m_inReenable : 1;
@ -32,9 +34,14 @@ class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID
void Reenable(); void Reenable();
void PostReenable(); void PostReenable();
virtual void HandleOutOfRange(OUT_OF_RANGE_TYPE type) {}; virtual void HandleOutOfRange(OUT_OF_RANGE_TYPE type) {};
virtual void UpdateWorldObject(int32_t a2);
// TODO
virtual int32_t GetModelFileName(const char*& name);
// TODO // TODO
virtual int32_t CanHighlight(); virtual int32_t CanHighlight();
virtual int32_t CanBeTargetted(); virtual int32_t CanBeTargetted();
// TODO
virtual CM2Model* GetObjectModel();
// Public member functions // Public member functions
CGObject_C() = default; CGObject_C() = default;
@ -45,6 +52,8 @@ class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4); void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void SetBlock(uint32_t block, uint32_t value); void SetBlock(uint32_t block, uint32_t value);
void SetDisablePending(int32_t pending); void SetDisablePending(int32_t pending);
void SetModel(CM2Model* model);
void SetModelFinish(CM2Model* model);
void SetObjectLocked(int32_t locked); void SetObjectLocked(int32_t locked);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
void SetTypeID(OBJECT_TYPE_ID typeID); void SetTypeID(OBJECT_TYPE_ID typeID);

View File

@ -41,6 +41,10 @@ uint32_t CGPlayer::TotalRemoteFieldsSaved() {
return CGPlayer::GetBaseOffsetSaved() + 173; return CGPlayer::GetBaseOffsetSaved() + 173;
} }
uint32_t CGPlayer::GetMoney() const {
return this->Player()->coinage;
}
uint32_t CGPlayer::GetNextLevelXP() const { uint32_t CGPlayer::GetNextLevelXP() const {
return this->Player()->nextLevelXP; return this->Player()->nextLevelXP;
} }

View File

@ -149,6 +149,7 @@ class CGPlayer {
static uint32_t TotalRemoteFieldsSaved(); static uint32_t TotalRemoteFieldsSaved();
// Public member functions // Public member functions
uint32_t GetMoney() const;
uint32_t GetNextLevelXP() const; uint32_t GetNextLevelXP() const;
uint32_t GetXP() const; uint32_t GetXP() const;

View File

@ -1,9 +1,17 @@
#include "object/client/CGPlayer_C.hpp" #include "object/client/CGPlayer_C.hpp"
#include "db/Db.hpp" #include "db/Db.hpp"
#include "object/client/ObjMgr.hpp"
#include "object/Types.hpp" #include "object/Types.hpp"
#include "object/client/ObjMgr.hpp"
#include "ui/FrameScript.hpp"
#include "ui/Game.hpp"
#include <storm/Error.hpp> #include <storm/Error.hpp>
CGPlayer_C* CGPlayer_C::GetActivePtr() {
return static_cast<CGPlayer_C*>(
ClntObjMgrObjectPtr(ClntObjMgrGetActivePlayer(), TYPE_PLAYER, __FILE__, __LINE__)
);
}
CGPlayer_C::CGPlayer_C(uint32_t time, CClientObjCreate& objCreate) : CGUnit_C(time, objCreate) { CGPlayer_C::CGPlayer_C(uint32_t time, CClientObjCreate& objCreate) : CGUnit_C(time, objCreate) {
// TODO // TODO
} }
@ -12,20 +20,28 @@ CGPlayer_C::~CGPlayer_C() {
// TODO // TODO
} }
uint32_t CGPlayer_C::GetActiveNextLevelXP() const { uint32_t CGPlayer_C::GetMoney() const {
if (this->GetGUID() != ClntObjMgrGetActivePlayer()) { if (this->GetGUID() != ClntObjMgrGetActivePlayer()) {
return 0; return 0;
} }
return this->GetNextLevelXP(); return this->CGPlayer::GetMoney();
} }
uint32_t CGPlayer_C::GetActiveXP() const { uint32_t CGPlayer_C::GetNextLevelXP() const {
if (this->GetGUID() != ClntObjMgrGetActivePlayer()) { if (this->GetGUID() != ClntObjMgrGetActivePlayer()) {
return 0; return 0;
} }
return this->GetXP(); return this->CGPlayer::GetNextLevelXP();
}
uint32_t CGPlayer_C::GetXP() const {
if (this->GetGUID() != ClntObjMgrGetActivePlayer()) {
return 0;
}
return this->CGPlayer::GetXP();
} }
void CGPlayer_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) { void CGPlayer_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
@ -34,6 +50,34 @@ void CGPlayer_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4)
this->CGUnit_C::PostInit(time, init, a4); this->CGUnit_C::PostInit(time, init, a4);
// TODO // TODO
if (this->GetGUID() == ClntObjMgrGetActivePlayer()) {
this->PostInitActivePlayer();
} else {
this->UpdatePartyMemberState();
}
// TODO
}
void CGPlayer_C::PostInitActivePlayer() {
// TODO
if (ClntObjMgrGetPlayerType() == PLAYER_NORMAL) {
// TODO
FrameScript_SignalEvent(SCRIPT_ACTIONBAR_SLOT_CHANGED, "%d", 0);
}
// TODO
if (ClntObjMgrGetPlayerType() == PLAYER_NORMAL) {
// TODO
CGGameUI::EnterWorld();
}
// TODO
} }
void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
@ -43,6 +87,10 @@ void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->m_playerSaved = &saved[CGPlayer::GetBaseOffsetSaved()]; this->m_playerSaved = &saved[CGPlayer::GetBaseOffsetSaved()];
} }
void CGPlayer_C::UpdatePartyMemberState() {
// TODO
}
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex) { uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex) {
STORM_ASSERT(sex < UNITSEX_LAST); STORM_ASSERT(sex < UNITSEX_LAST);

View File

@ -10,15 +10,21 @@ class CreatureModelDataRec;
class CGPlayer_C : public CGUnit_C, public CGPlayer { class CGPlayer_C : public CGUnit_C, public CGPlayer {
public: public:
// Public static functions
static CGPlayer_C* GetActivePtr();
// Virtual public member functions // Virtual public member functions
virtual ~CGPlayer_C(); virtual ~CGPlayer_C();
// Public member functions // Public member functions
CGPlayer_C(uint32_t time, CClientObjCreate& objCreate); CGPlayer_C(uint32_t time, CClientObjCreate& objCreate);
uint32_t GetActiveNextLevelXP() const; uint32_t GetMoney() const;
uint32_t GetActiveXP() const; uint32_t GetNextLevelXP() const;
uint32_t GetXP() const;
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4); void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void PostInitActivePlayer();
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
void UpdatePartyMemberState();
}; };
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex); uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex);

View File

@ -18,8 +18,12 @@ class ClntObjMgr {
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_reenabledObjects; STORM_EXPLICIT_LIST(CGObject_C, m_link) m_reenabledObjects;
// TODO // TODO
WOWGUID m_activePlayer = 0; WOWGUID m_activePlayer = 0;
PLAYER_TYPE m_type;
uint32_t m_mapID = 0; uint32_t m_mapID = 0;
ClientConnection* m_net = nullptr; ClientConnection* m_net = nullptr;
// Member functions
ClntObjMgr(PLAYER_TYPE type) : m_type(type) {};
}; };
#endif #endif

View File

@ -229,3 +229,20 @@ int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* ms
return 1; return 1;
} }
int32_t SkipPartialObjectUpdate(CDataStore* msg) {
uint8_t changeMaskCount;
uint32_t changeMasks[MAX_CHANGE_MASKS];
if (!ExtractDirtyMasks(msg, &changeMaskCount, changeMasks)) {
return 0;
}
for (int32_t block = 0; block < changeMaskCount * 32; block++) {
if (IsMaskBitSet(changeMasks, block)) {
uint32_t blockValue;
msg->Get(blockValue);
}
}
return 1;
}

View File

@ -11,4 +11,6 @@ int32_t CallMirrorHandlers(CDataStore* msg, bool a2, WOWGUID guid);
int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* msg, bool forFullUpdate, bool zeroZeroBits); int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* msg, bool forFullUpdate, bool zeroZeroBits);
int32_t SkipPartialObjectUpdate(CDataStore* msg);
#endif #endif

View File

@ -141,6 +141,10 @@ uint32_t ClntObjMgrGetMapID() {
return s_curMgr->m_mapID; return s_curMgr->m_mapID;
} }
PLAYER_TYPE ClntObjMgrGetPlayerType() {
return s_curMgr->m_type;
}
void ClntObjMgrInitializeShared() { void ClntObjMgrInitializeShared() {
if (!s_heapsAllocated) { if (!s_heapsAllocated) {
for (int32_t i = ID_ITEM; i < NUM_CLIENT_OBJECT_TYPES; i++) { for (int32_t i = ID_ITEM; i < NUM_CLIENT_OBJECT_TYPES; i++) {
@ -158,7 +162,7 @@ void ClntObjMgrInitializeShared() {
void ClntObjMgrInitializeStd(uint32_t mapID) { void ClntObjMgrInitializeStd(uint32_t mapID) {
// TODO last instance time // TODO last instance time
auto mgr = STORM_NEW(ClntObjMgr); auto mgr = STORM_NEW(ClntObjMgr)(PLAYER_NORMAL);
g_clientConnection->SetObjMgr(mgr); g_clientConnection->SetObjMgr(mgr);
mgr->m_net = g_clientConnection; mgr->m_net = g_clientConnection;

View File

@ -16,6 +16,8 @@ ClntObjMgr* ClntObjMgrGetCurrent();
uint32_t ClntObjMgrGetMapID(); uint32_t ClntObjMgrGetMapID();
PLAYER_TYPE ClntObjMgrGetPlayerType();
void ClntObjMgrInitializeShared(); void ClntObjMgrInitializeShared();
void ClntObjMgrInitializeStd(uint32_t mapID); void ClntObjMgrInitializeStd(uint32_t mapID);

View File

@ -164,8 +164,3 @@ void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate)
} }
} }
} }
int32_t SkipPartialObjectUpdate(CDataStore* msg) {
// TODO
return 0;
}

View File

@ -20,6 +20,4 @@ void HandleObjectOutOfRangePass2(CGObject_C* object);
void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate); void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate);
int32_t SkipPartialObjectUpdate(CDataStore* msg);
#endif #endif

View File

@ -862,6 +862,13 @@ void CLayoutFrame::SetProtectFlag(uint32_t flag) {
this->m_flags &= ~0x800; this->m_flags &= ~0x800;
} }
void CLayoutFrame::SetSize(float width, float height) {
this->m_flags &= ~0x8;
this->m_width = width;
this->m_height = height;
this->Resize(0);
}
void CLayoutFrame::SetWidth(float width) { void CLayoutFrame::SetWidth(float width) {
this->m_flags &= ~0x8; this->m_flags &= ~0x8;
this->m_width = width; this->m_width = width;

View File

@ -49,6 +49,7 @@ class CLayoutFrame {
virtual bool SetLayoutScale(float scale, bool force); virtual bool SetLayoutScale(float scale, bool force);
virtual void SetWidth(float width); virtual void SetWidth(float width);
virtual void SetHeight(float height); virtual void SetHeight(float height);
virtual void SetSize(float width, float height);
virtual float GetWidth(); virtual float GetWidth();
virtual float GetHeight(); virtual float GetHeight();
virtual void GetSize(float& width, float& height, int32_t a4); virtual void GetSize(float& width, float& height, int32_t a4);

View File

@ -219,7 +219,28 @@ int32_t CScriptRegion_SetHeight(lua_State* L) {
} }
int32_t CScriptRegion_SetSize(lua_State* L) { int32_t CScriptRegion_SetSize(lua_State* L) {
WHOA_UNIMPLEMENTED(0); auto type = CScriptRegion::GetObjectType();
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
if (!region->ProtectedFunctionsAllowed()) {
// TODO disallowed logic
return 0;
}
if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3)) {
luaL_error(L, "Usage: %s:SetSize(width, height)", region->GetDisplayName());
return 0;
}
auto ndcWidth = static_cast<float>(lua_tonumber(L, 2)) / (CoordinateGetAspectCompensation() * 1024.0f);
auto ddcWidth = NDCToDDCWidth(ndcWidth);
auto ndcHeight = static_cast<float>(lua_tonumber(L, 3)) / (CoordinateGetAspectCompensation() * 1024.0f);
auto ddcHeight = NDCToDDCWidth(ndcHeight);
region->SetSize(ddcWidth, ddcHeight);
return 0;
} }
int32_t CScriptRegion_GetSize(lua_State* L) { int32_t CScriptRegion_GetSize(lua_State* L) {

View File

@ -193,6 +193,25 @@ int32_t FrameScript_Object::SetScript(lua_State* L) {
return 0; return 0;
} }
void FrameScript_Object::UnregisterScriptEvent(const char* name) {
auto event = FrameScript::s_scriptEventsHash.Ptr(name);
if (!event) {
return;
}
if (event->pendingSignalCount) {
for (auto node = event->registerListeners.Head(); node; node = event->registerListeners.Next(node)) {
if (node->listener == this) {
event->registerListeners.DeleteNode(node);
break;
}
}
}
FrameScript_UnregisterScriptEvent(this, event);
}
void FrameScript_Object::UnregisterScriptObject(const char* name) { void FrameScript_Object::UnregisterScriptObject(const char* name) {
auto L = FrameScript_GetContext(); auto L = FrameScript_GetContext();

View File

@ -48,6 +48,7 @@ class FrameScript_Object {
void RegisterScriptObject(const char* name); void RegisterScriptObject(const char* name);
void RunScript(ScriptIx const& script, int32_t argCount, const char* a4); void RunScript(ScriptIx const& script, int32_t argCount, const char* a4);
int32_t SetScript(lua_State* L); int32_t SetScript(lua_State* L);
void UnregisterScriptEvent(const char* name);
void UnregisterScriptObject(const char* name); void UnregisterScriptObject(const char* name);
}; };

View File

@ -4,5 +4,6 @@
#include "ui/game/CGGameUI.hpp" #include "ui/game/CGGameUI.hpp"
#include "ui/game/CGPetInfo.hpp" #include "ui/game/CGPetInfo.hpp"
#include "ui/game/ScriptEvents.hpp" #include "ui/game/ScriptEvents.hpp"
#include "ui/game/Types.hpp"
#endif #endif

View File

@ -83,7 +83,9 @@ int32_t Script_IsActionInRange(lua_State* L) {
} }
int32_t Script_GetBonusBarOffset(lua_State* L) { int32_t Script_GetBonusBarOffset(lua_State* L) {
WHOA_UNIMPLEMENTED(0); lua_pushnumber(L, CGActionBar::GetBonusBarOffset());
return 1;
} }
int32_t Script_GetMultiCastBarOffset(lua_State* L) { int32_t Script_GetMultiCastBarOffset(lua_State* L) {

319
src/ui/game/BattlenetUI.cpp Normal file
View File

@ -0,0 +1,319 @@
#include "ui/game/BattlenetUI.hpp"
#include "client/ClientServices.hpp"
#include "net/Login.hpp"
#include "ui/FrameScript.hpp"
#include "util/Lua.hpp"
#include "util/Unimplemented.hpp"
namespace BattlenetUI {
int32_t Script_BNGetInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetNumFriends(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetFriendInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetFriendInfoByID(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetNumFriendToons(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetFriendToonInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetToonInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNRemoveFriend(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetFriendNote(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetSelectedFriend(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetSelectedFriend(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetNumFriendInvites(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetFriendInviteInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSendFriendInvite(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSendFriendInviteByID(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNAcceptFriendInvite(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNDeclineFriendInvite(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNReportFriendInvite(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetAFK(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetDND(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetCustomMessage(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetCustomMessageTable(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetFocus(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSendWhisper(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNCreateConversation(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNInviteToConversation(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNLeaveConversation(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSendConversationMessage(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetNumConversationMembers(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetConversationMemberInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetConversationInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNListConversation(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetNumBlocked(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetBlockedInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNIsBlocked(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetBlocked(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetSelectedBlock(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetSelectedBlock(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetNumBlockedToons(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetBlockedToonInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNIsToonBlocked(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetToonBlocked(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetSelectedToonBlock(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetSelectedToonBlock(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNReportPlayer(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNConnected(lua_State* L) {
// TODO real implementation
lua_pushboolean(L, false);
return 1;
}
int32_t Script_BNFeaturesEnabledAndConnected(lua_State* L) {
// TODO real implementation
lua_pushboolean(L, false);
return 1;
}
int32_t Script_IsBNLogin(lua_State* L) {
if (ClientServices::LoginConnection() && ClientServices::LoginConnection()->GetLoginServerType() == 1) {
lua_pushboolean(L, true);
} else {
lua_pushboolean(L, false);
}
return 1;
}
int32_t Script_BNFeaturesEnabled(lua_State* L) {
// TODO real implementation
lua_pushboolean(L, false);
return 1;
}
int32_t Script_BNRequestFOFInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetNumFOF(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetFOFInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNSetMatureLanguageFilter(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetMatureLanguageFilter(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNIsSelf(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNIsFriend(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_BNGetMaxPlayersInConversation(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
static FrameScript_Method s_ScriptFunctions[] = {
{ "BNGetInfo", &Script_BNGetInfo },
{ "BNGetNumFriends", &Script_BNGetNumFriends },
{ "BNGetFriendInfo", &Script_BNGetFriendInfo },
{ "BNGetFriendInfoByID", &Script_BNGetFriendInfoByID },
{ "BNGetNumFriendToons", &Script_BNGetNumFriendToons },
{ "BNGetFriendToonInfo", &Script_BNGetFriendToonInfo },
{ "BNGetToonInfo", &Script_BNGetToonInfo },
{ "BNRemoveFriend", &Script_BNRemoveFriend },
{ "BNSetFriendNote", &Script_BNSetFriendNote },
{ "BNSetSelectedFriend", &Script_BNSetSelectedFriend },
{ "BNGetSelectedFriend", &Script_BNGetSelectedFriend },
{ "BNGetNumFriendInvites", &Script_BNGetNumFriendInvites },
{ "BNGetFriendInviteInfo", &Script_BNGetFriendInviteInfo },
{ "BNSendFriendInvite", &Script_BNSendFriendInvite },
{ "BNSendFriendInviteByID", &Script_BNSendFriendInviteByID },
{ "BNAcceptFriendInvite", &Script_BNAcceptFriendInvite },
{ "BNDeclineFriendInvite", &Script_BNDeclineFriendInvite },
{ "BNReportFriendInvite", &Script_BNReportFriendInvite },
{ "BNSetAFK", &Script_BNSetAFK },
{ "BNSetDND", &Script_BNSetDND },
{ "BNSetCustomMessage", &Script_BNSetCustomMessage },
{ "BNGetCustomMessageTable", &Script_BNGetCustomMessageTable },
{ "BNSetFocus", &Script_BNSetFocus },
{ "BNSendWhisper", &Script_BNSendWhisper },
{ "BNCreateConversation", &Script_BNCreateConversation },
{ "BNInviteToConversation", &Script_BNInviteToConversation },
{ "BNLeaveConversation", &Script_BNLeaveConversation },
{ "BNSendConversationMessage", &Script_BNSendConversationMessage },
{ "BNGetNumConversationMembers", &Script_BNGetNumConversationMembers },
{ "BNGetConversationMemberInfo", &Script_BNGetConversationMemberInfo },
{ "BNGetConversationInfo", &Script_BNGetConversationInfo },
{ "BNListConversation", &Script_BNListConversation },
{ "BNGetNumBlocked", &Script_BNGetNumBlocked },
{ "BNGetBlockedInfo", &Script_BNGetBlockedInfo },
{ "BNIsBlocked", &Script_BNIsBlocked },
{ "BNSetBlocked", &Script_BNSetBlocked },
{ "BNSetSelectedBlock", &Script_BNSetSelectedBlock },
{ "BNGetSelectedBlock", &Script_BNGetSelectedBlock },
{ "BNGetNumBlockedToons", &Script_BNGetNumBlockedToons },
{ "BNGetBlockedToonInfo", &Script_BNGetBlockedToonInfo },
{ "BNIsToonBlocked", &Script_BNIsToonBlocked },
{ "BNSetToonBlocked", &Script_BNSetToonBlocked },
{ "BNSetSelectedToonBlock", &Script_BNSetSelectedToonBlock },
{ "BNGetSelectedToonBlock", &Script_BNGetSelectedToonBlock },
{ "BNReportPlayer", &Script_BNReportPlayer },
{ "BNConnected", &Script_BNConnected },
{ "BNFeaturesEnabledAndConnected", &Script_BNFeaturesEnabledAndConnected },
{ "IsBNLogin", &Script_IsBNLogin },
{ "BNFeaturesEnabled", &Script_BNFeaturesEnabled },
{ "BNRequestFOFInfo", &Script_BNRequestFOFInfo },
{ "BNGetNumFOF", &Script_BNGetNumFOF },
{ "BNGetFOFInfo", &Script_BNGetFOFInfo },
{ "BNSetMatureLanguageFilter", &Script_BNSetMatureLanguageFilter },
{ "BNGetMatureLanguageFilter", &Script_BNGetMatureLanguageFilter },
{ "BNIsSelf", &Script_BNIsSelf },
{ "BNIsFriend", &Script_BNIsFriend },
{ "BNGetMaxPlayersInConversation", &Script_BNGetMaxPlayersInConversation },
};
}
void BattlenetUI_RegisterScriptFunctions() {
for (auto& func : BattlenetUI::s_ScriptFunctions) {
FrameScript_RegisterFunction(func.name, func.method);
}
}

View File

@ -0,0 +1,6 @@
#ifndef UI_GAME_BATTLENET_UI_HPP
#define UI_GAME_BATTLENET_UI_HPP
void BattlenetUI_RegisterScriptFunctions();
#endif

View File

@ -1,4 +1,9 @@
#include "ui/game/CGActionBar.hpp" #include "ui/game/CGActionBar.hpp"
uint32_t CGActionBar::s_bonusBarOffset;
uint32_t CGActionBar::s_currentPage; uint32_t CGActionBar::s_currentPage;
uint32_t CGActionBar::s_tempPageActiveFlags; uint32_t CGActionBar::s_tempPageActiveFlags;
uint32_t CGActionBar::GetBonusBarOffset() {
return CGActionBar::s_bonusBarOffset;
}

View File

@ -5,9 +5,16 @@
class CGActionBar { class CGActionBar {
public: public:
// Static variables // Public static variables
static uint32_t s_currentPage; static uint32_t s_currentPage;
static uint32_t s_tempPageActiveFlags; static uint32_t s_tempPageActiveFlags;
// Public static functions
static uint32_t GetBonusBarOffset();
private:
// Private static variables
static uint32_t s_bonusBarOffset;
}; };
#endif #endif

View File

@ -1,10 +1,13 @@
#include "ui/game/CGGameUI.hpp" #include "ui/game/CGGameUI.hpp"
#include "client/Client.hpp" #include "client/Client.hpp"
#include "console/CVar.hpp"
#include "object/Client.hpp"
#include "ui/CScriptObject.hpp" #include "ui/CScriptObject.hpp"
#include "ui/FrameXML.hpp" #include "ui/FrameXML.hpp"
#include "ui/Key.hpp" #include "ui/Key.hpp"
#include "ui/game/ActionBarScript.hpp" #include "ui/game/ActionBarScript.hpp"
#include "ui/game/BattlefieldInfoScript.hpp" #include "ui/game/BattlefieldInfoScript.hpp"
#include "ui/game/BattlenetUI.hpp"
#include "ui/game/CGCharacterModelBase.hpp" #include "ui/game/CGCharacterModelBase.hpp"
#include "ui/game/CGCooldown.hpp" #include "ui/game/CGCooldown.hpp"
#include "ui/game/CGDressUpModelFrame.hpp" #include "ui/game/CGDressUpModelFrame.hpp"
@ -16,15 +19,22 @@
#include "ui/game/CharacterInfoScript.hpp" #include "ui/game/CharacterInfoScript.hpp"
#include "ui/game/GMTicketInfoScript.hpp" #include "ui/game/GMTicketInfoScript.hpp"
#include "ui/game/GameScript.hpp" #include "ui/game/GameScript.hpp"
#include "ui/game/PartyInfoScript.hpp"
#include "ui/game/RaidInfoScript.hpp"
#include "ui/game/ScriptEvents.hpp" #include "ui/game/ScriptEvents.hpp"
#include "ui/game/TradeInfoScript.hpp"
#include "ui/game/Types.hpp"
#include "ui/game/UIBindingsScript.hpp" #include "ui/game/UIBindingsScript.hpp"
#include "ui/simple/CSimpleTop.hpp" #include "ui/simple/CSimpleTop.hpp"
#include "util/CStatus.hpp" #include "util/CStatus.hpp"
#include <common/MD5.hpp> #include <common/MD5.hpp>
WOWGUID CGGameUI::s_currentObjectTrack; WOWGUID CGGameUI::s_currentObjectTrack;
uint32_t CGGameUI::s_cursorMoney;
CScriptObject* CGGameUI::s_gameTooltip; CScriptObject* CGGameUI::s_gameTooltip;
bool CGGameUI::s_inWorld;
WOWGUID CGGameUI::s_lockedTarget; WOWGUID CGGameUI::s_lockedTarget;
bool CGGameUI::s_loggingIn;
CSimpleTop* CGGameUI::s_simpleTop; CSimpleTop* CGGameUI::s_simpleTop;
void LoadScriptFunctions() { void LoadScriptFunctions() {
@ -48,6 +58,7 @@ void LoadScriptFunctions() {
// TODO // TODO
ActionBarRegisterScriptFunctions(); ActionBarRegisterScriptFunctions();
PartyInfoRegisterScriptFunctions();
// TODO // TODO
@ -55,11 +66,40 @@ void LoadScriptFunctions() {
// TODO // TODO
TradeInfoRegisterScriptFunctions();
// TODO
BattlefieldInfoRegisterScriptFunctions(); BattlefieldInfoRegisterScriptFunctions();
// TODO // TODO
RaidInfoRegisterScriptFunctions();
// TODO
GMTicketInfoRegisterScriptFunctions(); GMTicketInfoRegisterScriptFunctions();
BattlenetUI_RegisterScriptFunctions();
}
void CGGameUI::EnterWorld() {
if (CGGameUI::s_inWorld) {
return;
}
CGGameUI::s_inWorld = true;
// TODO
if (CGGameUI::s_loggingIn) {
CGGameUI::s_loggingIn = false;
FrameScript_SignalEvent(SCRIPT_PLAYER_LOGIN, nullptr);
// TODO CGLCD::Login();
}
FrameScript_SignalEvent(SCRIPT_PLAYER_ENTERING_WORLD, nullptr);
// TODO // TODO
} }
@ -68,6 +108,10 @@ WOWGUID& CGGameUI::GetCurrentObjectTrack() {
return CGGameUI::s_currentObjectTrack; return CGGameUI::s_currentObjectTrack;
} }
uint32_t CGGameUI::GetCursorMoney() {
return CGGameUI::s_cursorMoney;
}
WOWGUID& CGGameUI::GetLockedTarget() { WOWGUID& CGGameUI::GetLockedTarget() {
return CGGameUI::s_lockedTarget; return CGGameUI::s_lockedTarget;
} }
@ -75,12 +119,17 @@ WOWGUID& CGGameUI::GetLockedTarget() {
void CGGameUI::Initialize() { void CGGameUI::Initialize() {
// TODO // TODO
CGGameUI::s_loggingIn = true;
// TODO
CGGameUI::s_simpleTop = STORM_NEW(CSimpleTop); CGGameUI::s_simpleTop = STORM_NEW(CSimpleTop);
// TODO // TODO
LoadScriptFunctions(); LoadScriptFunctions();
ScriptEventsRegisterEvents(); ScriptEventsRegisterEvents();
CGGameUI::RegisterGameCVars();
// TODO // TODO
@ -150,6 +199,12 @@ void CGGameUI::Initialize() {
STORM_ASSERT(CGGameUI::s_gameTooltip); STORM_ASSERT(CGGameUI::s_gameTooltip);
// TODO // TODO
if (ClntObjMgrGetActivePlayer()) {
CGGameUI::EnterWorld();
}
// TODO
} }
void CGGameUI::InitializeGame() { void CGGameUI::InitializeGame() {
@ -160,6 +215,10 @@ void CGGameUI::InitializeGame() {
// TODO // TODO
} }
bool CGGameUI::IsLoggingIn() {
return CGGameUI::s_loggingIn;
}
int32_t CGGameUI::IsRaidMember(const WOWGUID& guid) { int32_t CGGameUI::IsRaidMember(const WOWGUID& guid) {
// TODO // TODO
@ -182,3 +241,47 @@ void CGGameUI::RegisterFrameFactories() {
FrameXML_RegisterFactory("TabardModel", &CGTabardModelFrame::Create, false); FrameXML_RegisterFactory("TabardModel", &CGTabardModelFrame::Create, false);
FrameXML_RegisterFactory("QuestPOIFrame", &CGQuestPOIFrame::Create, false); FrameXML_RegisterFactory("QuestPOIFrame", &CGQuestPOIFrame::Create, false);
} }
void CGGameUI::RegisterGameCVars() {
// TODO
CVar::Register("enableCombatText", "Whether to show floating combat text", 0x10, "1", nullptr, GAME);
CVar::Register("combatTextFloatMode", "The combat text float mode", 0x10, "1", nullptr, GAME);
CVar::Register("fctCombatState", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctDodgeParryMiss", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctDamageReduction", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctRepChanges", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctReactives", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctFriendlyHealers", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctComboPoints", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctLowManaHealth", nullptr, 0x10, "1", nullptr, GAME);
CVar::Register("fctEnergyGains", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctPeriodicEnergyGains", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctHonorGains", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctAuras", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctAllSpellMechanics", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctSpellMechanics", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("fctSpellMechanicsOther", nullptr, 0x10, "0", nullptr, GAME);
CVar::Register("xpBarText", "Whether the XP bar shows the numeric experience value", 0x10, "0", nullptr, GAME);
CVar::Register("playerStatusText", "Whether the player portrait shows numeric health/mana values", 0x10, "0", nullptr, GAME);
CVar::Register("petStatusText", "Whether the pet portrait shows numeric health/mana values", 0x10, "0", nullptr, GAME);
CVar::Register("partyStatusText", "Whether the party portraits shows numeric health/mana values", 0x10, "0", nullptr, GAME);
CVar::Register("targetStatusText", "Whether the target portrait shows numeric health/mana values", 0x10, "0", nullptr, GAME);
CVar::Register("statusTextPercentage", "Whether numeric health/mana values are shown as raw values or percentages", 0x10, "0", nullptr, GAME);
CVar::Register("showPartyBackground", "Show a background behind party members", 0x10, "0", nullptr, GAME);
CVar::Register("partyBackgroundOpacity", "The opacity of the party background", 0x10, "0.5", nullptr, GAME);
CVar::Register("hidePartyInRaid", "Whether to hide the party UI while in a raid", 0x10, "0", nullptr, GAME);
CVar::Register("showPartyPets", "Whether to show pets in the party UI", 0x20, "1", nullptr, GAME);
CVar::Register("showRaidRange", "Show range indicator in raid UI", 0x20, "0", nullptr, GAME);
CVar::Register("showArenaEnemyFrames", "Show arena enemy frames while in an Arena", 0x20, "1", nullptr, GAME);
CVar::Register("showArenaEnemyCastbar", "Show the spell enemies are casting on the Arena Enemy frames", 0x20, "1", nullptr, GAME);
CVar::Register("showArenaEnemyPets", "Show the enemy team's pets on the ArenaEnemy frames", 0x20, "1", nullptr, GAME);
CVar::Register("fullSizeFocusFrame", "Increases the size of the focus frame to that of the target frame", 0x20, "0", nullptr, GAME);
// TODO
}

View File

@ -13,17 +13,24 @@ class CGGameUI {
static CSimpleTop* s_simpleTop; static CSimpleTop* s_simpleTop;
// Static functions // Static functions
static void EnterWorld();
static WOWGUID& GetCurrentObjectTrack(); static WOWGUID& GetCurrentObjectTrack();
static uint32_t GetCursorMoney();
static WOWGUID& GetLockedTarget(); static WOWGUID& GetLockedTarget();
static void Initialize(); static void Initialize();
static void InitializeGame(); static void InitializeGame();
static bool IsLoggingIn();
static int32_t IsRaidMember(const WOWGUID& guid); static int32_t IsRaidMember(const WOWGUID& guid);
static int32_t IsRaidMemberOrPet(const WOWGUID& guid); static int32_t IsRaidMemberOrPet(const WOWGUID& guid);
static void RegisterFrameFactories(); static void RegisterFrameFactories();
static void RegisterGameCVars();
private: private:
static WOWGUID s_currentObjectTrack; static WOWGUID s_currentObjectTrack;
static uint32_t s_cursorMoney;
static bool s_inWorld;
static WOWGUID s_lockedTarget; static WOWGUID s_lockedTarget;
static bool s_loggingIn;
}; };
#endif #endif

View File

@ -0,0 +1,15 @@
#include "ui/game/CGPartyInfo.hpp"
WOWGUID CGPartyInfo::m_members[4];
uint32_t CGPartyInfo::NumMembers() {
uint32_t count = 0;
for (auto& member : CGPartyInfo::m_members) {
if (member != 0) {
count++;
}
}
return count;
}

View File

@ -0,0 +1,16 @@
#ifndef UI_GAME_C_G_PARTY_INFO_HPP
#define UI_GAME_C_G_PARTY_INFO_HPP
#include "util/GUID.hpp"
class CGPartyInfo {
public:
// Public static functions
static uint32_t NumMembers();
private:
// Private static variables
static WOWGUID m_members[];
};
#endif

View File

@ -0,0 +1,7 @@
#include "ui/game/CGRaidInfo.hpp"
uint32_t CGRaidInfo::s_numMembers;
uint32_t CGRaidInfo::NumMembers() {
return CGRaidInfo::s_numMembers;
}

View File

@ -0,0 +1,16 @@
#ifndef UI_GAME_C_G_RAID_INFO_HPP
#define UI_GAME_C_G_RAID_INFO_HPP
#include <cstdint>
class CGRaidInfo {
public:
// Public static functions
static uint32_t NumMembers();
private:
// Private static variables
static uint32_t s_numMembers;
};
#endif

View File

@ -0,0 +1,12 @@
#include "ui/game/CGTradeInfo.hpp"
uint32_t CGTradeInfo::s_playerMoney;
WOWGUID CGTradeInfo::s_tradingPlayer;
uint32_t CGTradeInfo::GetPlayerTradeMoney() {
return CGTradeInfo::s_playerMoney;
}
WOWGUID CGTradeInfo::GetTradePartner() {
return CGTradeInfo::s_tradingPlayer;
}

View File

@ -0,0 +1,19 @@
#ifndef UI_GAME_C_G_TRADE_INFO_HPP
#define UI_GAME_C_G_TRADE_INFO_HPP
#include "util/GUID.hpp"
#include <cstdint>
class CGTradeInfo {
public:
// Public static functions
static uint32_t GetPlayerTradeMoney();
static WOWGUID GetTradePartner();
private:
// Private static variables
static uint32_t s_playerMoney;
static WOWGUID s_tradingPlayer;
};
#endif

View File

@ -1,11 +1,48 @@
#include "ui/game/CharacterInfoScript.hpp" #include "ui/game/CharacterInfoScript.hpp"
#include "db/Db.hpp"
#include "ui/FrameScript.hpp" #include "ui/FrameScript.hpp"
#include "util/Lua.hpp"
#include "util/Unimplemented.hpp" #include "util/Unimplemented.hpp"
namespace { namespace {
int32_t Script_GetInventorySlotInfo(lua_State* L) { int32_t Script_GetInventorySlotInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0); if (!lua_isstring(L, 1)) {
luaL_error(L, "Invalid inventory slot in GetInventorySlotInfo");
return 0;
}
auto slotName = lua_tostring(L, 1);
PaperDollItemFrameRec* slotRec = nullptr;
for (int32_t i = 0; i < g_paperDollItemFrameDB.GetNumRecords(); i++) {
auto paperDollItemFrameRec = g_paperDollItemFrameDB.GetRecordByIndex(i);
if (paperDollItemFrameRec && !SStrCmpI(slotName, paperDollItemFrameRec->m_itemButtonName)) {
slotRec = paperDollItemFrameRec;
break;
}
}
if (!slotRec) {
luaL_error(L, "Invalid inventory slot in GetInventorySlotInfo");
return 0;
}
// id
lua_pushnumber(L, slotRec->m_slotNumber);
// textureName
lua_pushstring(L, slotRec->m_slotIcon);
// checkRelic
if (slotRec->m_slotNumber == EQUIPPED_LAST) {
lua_pushnumber(L, 1.0);
} else {
lua_pushnil(L);
}
return 3;
} }
int32_t Script_GetInventoryItemsForSlot(lua_State* L) { int32_t Script_GetInventoryItemsForSlot(lua_State* L) {

View File

@ -3,6 +3,8 @@
#include "gx/Coordinate.hpp" #include "gx/Coordinate.hpp"
#include "ui/FrameScript.hpp" #include "ui/FrameScript.hpp"
#include "ui/ScriptFunctionsShared.hpp" #include "ui/ScriptFunctionsShared.hpp"
#include "ui/game/CGGameUI.hpp"
#include "ui/game/Types.hpp"
#include "ui/simple/CSimpleTop.hpp" #include "ui/simple/CSimpleTop.hpp"
#include "util/StringTo.hpp" #include "util/StringTo.hpp"
#include "util/Unimplemented.hpp" #include "util/Unimplemented.hpp"
@ -130,7 +132,41 @@ int32_t Script_GetCVarInfo(lua_State* L) {
} }
int32_t Script_SetCVar(lua_State* L) { int32_t Script_SetCVar(lua_State* L) {
WHOA_UNIMPLEMENTED(0); if (!lua_isstring(L, 1)) {
luaL_error(L, "Usage: SetCVar(\"cvar\", value [, \"scriptCvar\")");
return 0;
}
auto varName = lua_tostring(L, 1);
auto var = CVar::LookupRegistered(varName);
if (!var || (var->m_flags & 0x40)) {
luaL_error(L, "Couldn't find CVar named '%s'", varName);
return 0;
}
if (var->m_flags & 0x4 || var->m_flags & 0x100) {
luaL_error(L, "\"%s\" is read-only", varName);
return 0;
}
if (!(var->m_flags & 0x8)/* TODO || CSimpleTop::GetInstance()->dword124C */) {
auto value = lua_tostring(L, 2);
if (!value) {
value = "0";
}
var->Set(value, true, false, false, true);
if (lua_isstring(L, 3)) {
auto scriptVarName = lua_tostring(L, 3);
FrameScript_SignalEvent(SCRIPT_CVAR_UPDATE, "%s%s", scriptVarName, value);
}
} else {
// TODO CGGameUI::ShowBlockedActionFeedback(nullptr, 2);
}
return 0;
} }
int32_t Script_GetCVar(lua_State* L) { int32_t Script_GetCVar(lua_State* L) {
@ -170,7 +206,22 @@ int32_t Script_GetCVarBool(lua_State* L) {
} }
int32_t Script_GetCVarDefault(lua_State* L) { int32_t Script_GetCVarDefault(lua_State* L) {
WHOA_UNIMPLEMENTED(0); if (!lua_isstring(L, 1)) {
luaL_error(L, "Usage: GetCVarDefault(\"cvar\")");
return 0;
}
auto varName = lua_tostring(L, 1);
auto var = CVar::LookupRegistered(varName);
if (!var || (var->m_flags & 0x40)) {
luaL_error(L, "Couldn't find CVar named '%s'", varName);
return 0;
}
lua_pushstring(L, var->GetDefaultValue());
return 1;
} }
int32_t Script_GetCVarMin(lua_State* L) { int32_t Script_GetCVarMin(lua_State* L) {
@ -502,7 +553,9 @@ int32_t Script_ForceQuit(lua_State* L) {
} }
int32_t Script_GetCursorMoney(lua_State* L) { int32_t Script_GetCursorMoney(lua_State* L) {
WHOA_UNIMPLEMENTED(0); lua_pushnumber(L, CGGameUI::GetCursorMoney());
return 1;
} }
int32_t Script_DropCursorMoney(lua_State* L) { int32_t Script_DropCursorMoney(lua_State* L) {

View File

@ -0,0 +1,130 @@
#include "ui/game/PartyInfoScript.hpp"
#include "ui/FrameScript.hpp"
#include "ui/game/CGPartyInfo.hpp"
#include "util/Lua.hpp"
#include "util/Unimplemented.hpp"
namespace {
int32_t Script_GetNumPartyMembers(lua_State* L) {
lua_pushnumber(L, CGPartyInfo::NumMembers());
return 1;
}
int32_t Script_GetRealNumPartyMembers(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetPartyMember(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetPartyLeaderIndex(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_IsPartyLeader(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_IsRealPartyLeader(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_LeaveParty(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetLootMethod(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetLootMethod(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetLootThreshold(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetLootThreshold(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetPartyAssignment(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_ClearPartyAssignment(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetPartyAssignment(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SilenceMember(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_UnSilenceMember(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetOptOutOfLoot(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetOptOutOfLoot(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_CanChangePlayerDifficulty(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_ChangePlayerDifficulty(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_IsPartyLFG(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_HasLFGRestrictions(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
}
static FrameScript_Method s_ScriptFunctions[] = {
{ "GetNumPartyMembers", &Script_GetNumPartyMembers },
{ "GetRealNumPartyMembers", &Script_GetRealNumPartyMembers },
{ "GetPartyMember", &Script_GetPartyMember },
{ "GetPartyLeaderIndex", &Script_GetPartyLeaderIndex },
{ "IsPartyLeader", &Script_IsPartyLeader },
{ "IsRealPartyLeader", &Script_IsRealPartyLeader },
{ "LeaveParty", &Script_LeaveParty },
{ "GetLootMethod", &Script_GetLootMethod },
{ "SetLootMethod", &Script_SetLootMethod },
{ "GetLootThreshold", &Script_GetLootThreshold },
{ "SetLootThreshold", &Script_SetLootThreshold },
{ "SetPartyAssignment", &Script_SetPartyAssignment },
{ "ClearPartyAssignment", &Script_ClearPartyAssignment },
{ "GetPartyAssignment", &Script_GetPartyAssignment },
{ "SilenceMember", &Script_SilenceMember },
{ "UnSilenceMember", &Script_UnSilenceMember },
{ "SetOptOutOfLoot", &Script_SetOptOutOfLoot },
{ "GetOptOutOfLoot", &Script_GetOptOutOfLoot },
{ "CanChangePlayerDifficulty", &Script_CanChangePlayerDifficulty },
{ "ChangePlayerDifficulty", &Script_ChangePlayerDifficulty },
{ "IsPartyLFG", &Script_IsPartyLFG },
{ "HasLFGRestrictions", &Script_HasLFGRestrictions },
};
void PartyInfoRegisterScriptFunctions() {
for (auto& func : s_ScriptFunctions) {
FrameScript_RegisterFunction(func.name, func.method);
}
}

View File

@ -0,0 +1,6 @@
#ifndef UI_GAME_PARTY_INFO_SCRIPT_HPP
#define UI_GAME_PARTY_INFO_SCRIPT_HPP
void PartyInfoRegisterScriptFunctions();
#endif

View File

@ -0,0 +1,120 @@
#include "ui/game/RaidInfoScript.hpp"
#include "ui/FrameScript.hpp"
#include "ui/game/CGRaidInfo.hpp"
#include "util/Lua.hpp"
#include "util/Unimplemented.hpp"
namespace {
int32_t Script_GetNumRaidMembers(lua_State* L) {
lua_pushnumber(L, CGRaidInfo::NumMembers());
return 1;
}
int32_t Script_GetRealNumRaidMembers(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetRaidRosterInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetRaidRosterSelection(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetRaidRosterSelection(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_IsRaidLeader(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_IsRealRaidLeader(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_IsRaidOfficer(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetRaidSubgroup(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SwapRaidSubgroup(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_ConvertToRaid(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_PromoteToLeader(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_PromoteToAssistant(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_DemoteAssistant(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetRaidTarget(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetRaidTargetIndex(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_DoReadyCheck(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_ConfirmReadyCheck(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetReadyCheckTimeLeft(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetReadyCheckStatus(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
}
static FrameScript_Method s_ScriptFunctions[] = {
{ "GetNumRaidMembers", &Script_GetNumRaidMembers },
{ "GetRealNumRaidMembers", &Script_GetRealNumRaidMembers },
{ "GetRaidRosterInfo", &Script_GetRaidRosterInfo },
{ "SetRaidRosterSelection", &Script_SetRaidRosterSelection },
{ "GetRaidRosterSelection", &Script_GetRaidRosterSelection },
{ "IsRaidLeader", &Script_IsRaidLeader },
{ "IsRealRaidLeader", &Script_IsRealRaidLeader },
{ "IsRaidOfficer", &Script_IsRaidOfficer },
{ "SetRaidSubgroup", &Script_SetRaidSubgroup },
{ "SwapRaidSubgroup", &Script_SwapRaidSubgroup },
{ "ConvertToRaid", &Script_ConvertToRaid },
{ "PromoteToLeader", &Script_PromoteToLeader },
{ "PromoteToAssistant", &Script_PromoteToAssistant },
{ "DemoteAssistant", &Script_DemoteAssistant },
{ "SetRaidTarget", &Script_SetRaidTarget },
{ "GetRaidTargetIndex", &Script_GetRaidTargetIndex },
{ "DoReadyCheck", &Script_DoReadyCheck },
{ "ConfirmReadyCheck", &Script_ConfirmReadyCheck },
{ "GetReadyCheckTimeLeft", &Script_GetReadyCheckTimeLeft },
{ "GetReadyCheckStatus", &Script_GetReadyCheckStatus },
};
void RaidInfoRegisterScriptFunctions() {
for (auto& func : s_ScriptFunctions) {
FrameScript_RegisterFunction(func.name, func.method);
}
}

View File

@ -0,0 +1,6 @@
#ifndef UI_GAME_RAID_INFO_SCRIPT_HPP
#define UI_GAME_RAID_INFO_SCRIPT_HPP
void RaidInfoRegisterScriptFunctions();
#endif

View File

@ -5,6 +5,7 @@
#include "ui/ScriptFunctionsSystem.hpp" #include "ui/ScriptFunctionsSystem.hpp"
#include "ui/game/CGGameUI.hpp" #include "ui/game/CGGameUI.hpp"
#include "ui/game/ScriptUtil.hpp" #include "ui/game/ScriptUtil.hpp"
#include "ui/game/Types.hpp"
#include "util/GUID.hpp" #include "util/GUID.hpp"
#include "util/Lua.hpp" #include "util/Lua.hpp"
#include "util/StringTo.hpp" #include "util/StringTo.hpp"
@ -188,7 +189,7 @@ int32_t Script_UnitXP(lua_State* L) {
float xp = 0.0f; float xp = 0.0f;
if (unit && unit->IsA(TYPE_PLAYER)) { if (unit && unit->IsA(TYPE_PLAYER)) {
xp = static_cast<CGPlayer_C*>(unit)->GetActiveXP(); xp = static_cast<CGPlayer_C*>(unit)->GetXP();
} }
lua_pushnumber(L, xp); lua_pushnumber(L, xp);
@ -208,7 +209,7 @@ int32_t Script_UnitXPMax(lua_State* L) {
float xpMax = 0.0f; float xpMax = 0.0f;
if (unit && unit->IsA(TYPE_PLAYER)) { if (unit && unit->IsA(TYPE_PLAYER)) {
xpMax = static_cast<CGPlayer_C*>(unit)->GetActiveNextLevelXP(); xpMax = static_cast<CGPlayer_C*>(unit)->GetNextLevelXP();
} }
lua_pushnumber(L, xpMax); lua_pushnumber(L, xpMax);
@ -281,7 +282,15 @@ int32_t Script_UnitLevel(lua_State* L) {
} }
int32_t Script_GetMoney(lua_State* L) { int32_t Script_GetMoney(lua_State* L) {
WHOA_UNIMPLEMENTED(0); auto player = CGPlayer_C::GetActivePtr();
if (player) {
lua_pushnumber(L, player->GetMoney());
} else {
lua_pushnumber(L, 0.0f);
}
return 1;
} }
int32_t Script_GetHonorCurrency(lua_State* L) { int32_t Script_GetHonorCurrency(lua_State* L) {
@ -1056,7 +1065,7 @@ void ScriptEventsInitialize() {
g_scriptEvents[173] = "ACTIONBAR_SHOWGRID"; g_scriptEvents[173] = "ACTIONBAR_SHOWGRID";
g_scriptEvents[174] = "ACTIONBAR_HIDEGRID"; g_scriptEvents[174] = "ACTIONBAR_HIDEGRID";
g_scriptEvents[175] = "ACTIONBAR_PAGE_CHANGED"; g_scriptEvents[175] = "ACTIONBAR_PAGE_CHANGED";
g_scriptEvents[176] = "ACTIONBAR_SLOT_CHANGED"; g_scriptEvents[SCRIPT_ACTIONBAR_SLOT_CHANGED] = "ACTIONBAR_SLOT_CHANGED";
g_scriptEvents[177] = "ACTIONBAR_UPDATE_STATE"; g_scriptEvents[177] = "ACTIONBAR_UPDATE_STATE";
g_scriptEvents[178] = "ACTIONBAR_UPDATE_USABLE"; g_scriptEvents[178] = "ACTIONBAR_UPDATE_USABLE";
g_scriptEvents[179] = "ACTIONBAR_UPDATE_COOLDOWN"; g_scriptEvents[179] = "ACTIONBAR_UPDATE_COOLDOWN";
@ -1133,9 +1142,9 @@ void ScriptEventsInitialize() {
g_scriptEvents[250] = "LOOT_SLOT_CLEARED"; g_scriptEvents[250] = "LOOT_SLOT_CLEARED";
g_scriptEvents[251] = "LOOT_SLOT_CHANGED"; g_scriptEvents[251] = "LOOT_SLOT_CHANGED";
g_scriptEvents[252] = "LOOT_CLOSED"; g_scriptEvents[252] = "LOOT_CLOSED";
g_scriptEvents[253] = "PLAYER_LOGIN"; g_scriptEvents[SCRIPT_PLAYER_LOGIN] = "PLAYER_LOGIN";
g_scriptEvents[254] = "PLAYER_LOGOUT"; g_scriptEvents[SCRIPT_PLAYER_LOGOUT] = "PLAYER_LOGOUT";
g_scriptEvents[255] = "PLAYER_ENTERING_WORLD"; g_scriptEvents[SCRIPT_PLAYER_ENTERING_WORLD] = "PLAYER_ENTERING_WORLD";
g_scriptEvents[256] = "PLAYER_LEAVING_WORLD"; g_scriptEvents[256] = "PLAYER_LEAVING_WORLD";
g_scriptEvents[257] = "PLAYER_ALIVE"; g_scriptEvents[257] = "PLAYER_ALIVE";
g_scriptEvents[258] = "PLAYER_DEAD"; g_scriptEvents[258] = "PLAYER_DEAD";
@ -1178,7 +1187,7 @@ void ScriptEventsInitialize() {
g_scriptEvents[295] = "TRAINER_UPDATE"; g_scriptEvents[295] = "TRAINER_UPDATE";
g_scriptEvents[296] = "TRAINER_DESCRIPTION_UPDATE"; g_scriptEvents[296] = "TRAINER_DESCRIPTION_UPDATE";
g_scriptEvents[297] = "TRAINER_CLOSED"; g_scriptEvents[297] = "TRAINER_CLOSED";
g_scriptEvents[298] = "CVAR_UPDATE"; g_scriptEvents[SCRIPT_CVAR_UPDATE] = "CVAR_UPDATE";
g_scriptEvents[299] = "TRADE_SKILL_SHOW"; g_scriptEvents[299] = "TRADE_SKILL_SHOW";
g_scriptEvents[300] = "TRADE_SKILL_UPDATE"; g_scriptEvents[300] = "TRADE_SKILL_UPDATE";
g_scriptEvents[301] = "TRADE_SKILL_CLOSE"; g_scriptEvents[301] = "TRADE_SKILL_CLOSE";

View File

@ -0,0 +1,94 @@
#include "ui/game/TradeInfoScript.hpp"
#include "ui/FrameScript.hpp"
#include "ui/game/CGTradeInfo.hpp"
#include "util/Lua.hpp"
#include "util/Unimplemented.hpp"
namespace {
int32_t Script_CloseTrade(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_ClickTradeButton(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_ClickTargetTradeButton(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetTradeTargetItemInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetTradeTargetItemLink(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetTradePlayerItemInfo(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetTradePlayerItemLink(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_AcceptTrade(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_CancelTradeAccept(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_GetPlayerTradeMoney(lua_State* L) {
if (CGTradeInfo::GetTradePartner()) {
lua_pushnumber(L, CGTradeInfo::GetPlayerTradeMoney());
} else {
lua_pushnumber(L, 0);
}
return 1;
}
int32_t Script_GetTargetTradeMoney(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_PickupTradeMoney(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_AddTradeMoney(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
int32_t Script_SetTradeMoney(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
}
}
static FrameScript_Method s_ScriptFunctions[] = {
{ "CloseTrade", &Script_CloseTrade },
{ "ClickTradeButton", &Script_ClickTradeButton },
{ "ClickTargetTradeButton", &Script_ClickTargetTradeButton },
{ "GetTradeTargetItemInfo", &Script_GetTradeTargetItemInfo },
{ "GetTradeTargetItemLink", &Script_GetTradeTargetItemLink },
{ "GetTradePlayerItemInfo", &Script_GetTradePlayerItemInfo },
{ "GetTradePlayerItemLink", &Script_GetTradePlayerItemLink },
{ "AcceptTrade", &Script_AcceptTrade },
{ "CancelTradeAccept", &Script_CancelTradeAccept },
{ "GetPlayerTradeMoney", &Script_GetPlayerTradeMoney },
{ "GetTargetTradeMoney", &Script_GetTargetTradeMoney },
{ "PickupTradeMoney", &Script_PickupTradeMoney },
{ "AddTradeMoney", &Script_AddTradeMoney },
{ "SetTradeMoney", &Script_SetTradeMoney },
};
void TradeInfoRegisterScriptFunctions() {
for (auto& func : s_ScriptFunctions) {
FrameScript_RegisterFunction(func.name, func.method);
}
}

View File

@ -0,0 +1,6 @@
#ifndef UI_GAME_TRADE_INFO_SCRIPT_HPP
#define UI_GAME_TRADE_INFO_SCRIPT_HPP
void TradeInfoRegisterScriptFunctions();
#endif

16
src/ui/game/Types.hpp Normal file
View File

@ -0,0 +1,16 @@
#ifndef UI_GAME_TYPES_HPP
#define UI_GAME_TYPES_HPP
enum SCRIPTEVENT {
// TODO
SCRIPT_ACTIONBAR_SLOT_CHANGED = 176,
// TODO
SCRIPT_PLAYER_LOGIN = 253,
SCRIPT_PLAYER_LOGOUT = 254,
SCRIPT_PLAYER_ENTERING_WORLD = 255,
// TODO
SCRIPT_CVAR_UPDATE = 298,
// TODO
};
#endif

View File

@ -3,6 +3,8 @@
#include "ui/CBackdropGenerator.hpp" #include "ui/CBackdropGenerator.hpp"
#include "ui/FrameScript.hpp" #include "ui/FrameScript.hpp"
#include "ui/FrameXML.hpp" #include "ui/FrameXML.hpp"
#include "ui/simple/CSimpleFont.hpp"
#include "ui/simple/CSimpleFontString.hpp"
#include "ui/simple/CSimpleFrame.hpp" #include "ui/simple/CSimpleFrame.hpp"
#include "ui/simple/CSimpleTexture.hpp" #include "ui/simple/CSimpleTexture.hpp"
#include "util/Lua.hpp" #include "util/Lua.hpp"
@ -85,7 +87,73 @@ int32_t CSimpleFrame_CreateTexture(lua_State* L) {
} }
int32_t CSimpleFrame_CreateFontString(lua_State* L) { int32_t CSimpleFrame_CreateFontString(lua_State* L) {
WHOA_UNIMPLEMENTED(0); auto type = CSimpleFrame::GetObjectType();
auto frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
const char* name = nullptr;
if (lua_isstring(L, 2)) {
name = lua_tostring(L, 2);
}
int32_t drawlayer = DRAWLAYER_ARTWORK;
if (lua_isstring(L, 3)) {
auto drawlayerStr = lua_tostring(L, 3);
StringToDrawLayer(drawlayerStr, drawlayer);
}
CSimpleFont* inheritFont = nullptr;
XMLNode* inheritNode = nullptr;
if (lua_type(L, 4) == LUA_TSTRING) {
auto inheritName = lua_tostring(L, 4);
inheritFont = CSimpleFont::GetFont(inheritName, 0);
if (!inheritFont) {
const char* tainted;
bool locked;
inheritNode = FrameXML_AcquireHashNode(inheritName, tainted, locked);
if (!inheritNode) {
luaL_error(L, "%s:CreateFontString(): Couldn't find inherited node \"%s\"", frame->GetDisplayName(), inheritName);
return 0;
}
if (locked) {
luaL_error(L, "%s:CreateFontString(): Recursively inherited node \"%s\"", frame->GetDisplayName(), inheritName);
return 0;
}
}
}
// TODO CDataAllocator::GetData
auto string = STORM_NEW(CSimpleFontString)(frame, drawlayer, true);
if (name && *name) {
string->SetName(name);
}
if (inheritFont) {
string->SetFontObject(inheritFont);
} else if (inheritNode) {
CStatus status;
string->LoadXML(inheritNode, &status);
string->PostLoadXML(inheritNode, &status);
auto inheritName = lua_tostring(L, 4);
FrameXML_ReleaseHashNode(inheritName);
}
// TODO anim related logic?
if (!string->lua_registered) {
string->RegisterScriptObject(nullptr);
}
lua_rawgeti(L, LUA_REGISTRYINDEX, string->lua_objectRef);
return 1;
} }
int32_t CSimpleFrame_GetBoundsRect(lua_State* L) { int32_t CSimpleFrame_GetBoundsRect(lua_State* L) {
@ -221,7 +289,19 @@ int32_t CSimpleFrame_RegisterEvent(lua_State* L) {
} }
int32_t CSimpleFrame_UnregisterEvent(lua_State* L) { int32_t CSimpleFrame_UnregisterEvent(lua_State* L) {
WHOA_UNIMPLEMENTED(0); auto type = CSimpleFrame::GetObjectType();
auto frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
if (!lua_isstring(L, 2)) {
luaL_error(L, "Usage: %s:UnregisterEvent(\"event\")", frame->GetDisplayName());
return 0;
}
auto eventName = lua_tostring(L, 2);
frame->UnregisterScriptEvent(eventName);
return 0;
} }
int32_t CSimpleFrame_RegisterAllEvents(lua_State* L) { int32_t CSimpleFrame_RegisterAllEvents(lua_State* L) {

View File

@ -12,6 +12,7 @@ uint32_t CWorld::s_enables;
uint32_t CWorld::s_enables2; uint32_t CWorld::s_enables2;
uint32_t CWorld::s_gameTimeFixed; uint32_t CWorld::s_gameTimeFixed;
float CWorld::s_gameTimeSec; float CWorld::s_gameTimeSec;
CM2Scene* CWorld::s_m2Scene;
uint32_t CWorld::s_tickTimeFixed; uint32_t CWorld::s_tickTimeFixed;
uint32_t CWorld::s_tickTimeMs; uint32_t CWorld::s_tickTimeMs;
float CWorld::s_tickTimeSec; float CWorld::s_tickTimeSec;
@ -66,6 +67,10 @@ float CWorld::GetGameTimeSec() {
return CWorld::s_gameTimeSec; return CWorld::s_gameTimeSec;
} }
CM2Scene* CWorld::GetM2Scene() {
return CWorld::s_m2Scene;
}
uint32_t CWorld::GetTickTimeFixed() { uint32_t CWorld::GetTickTimeFixed() {
return CWorld::s_tickTimeFixed; return CWorld::s_tickTimeFixed;
} }
@ -97,8 +102,6 @@ void CWorld::Initialize() {
CWorld::s_gameTimeFixed = 0; CWorld::s_gameTimeFixed = 0;
CWorld::s_gameTimeSec = 0.0f; CWorld::s_gameTimeSec = 0.0f;
// TODO
if (GxCaps().m_shaderTargets[GxSh_Pixel] > GxShPS_none) { if (GxCaps().m_shaderTargets[GxSh_Pixel] > GxShPS_none) {
CWorld::s_enables |= Enables::Enable_PixelShader; CWorld::s_enables |= Enables::Enable_PixelShader;
} }
@ -109,6 +112,10 @@ void CWorld::Initialize() {
// TODO // TODO
CWorld::s_m2Scene = M2CreateScene();
// TODO
uint32_t m2Flags = M2GetCacheFlags(); uint32_t m2Flags = M2GetCacheFlags();
CShaderEffect::InitShaderSystem( CShaderEffect::InitShaderSystem(
(m2Flags & 0x8) != 0, (m2Flags & 0x8) != 0,

View File

@ -7,6 +7,7 @@
#include <cstdint> #include <cstdint>
class CM2Model; class CM2Model;
class CM2Scene;
class Weather; class Weather;
class CWorld { class CWorld {
@ -58,6 +59,7 @@ class CWorld {
static float GetCurTimeSec(); static float GetCurTimeSec();
static uint32_t GetGameTimeFixed(); static uint32_t GetGameTimeFixed();
static float GetGameTimeSec(); static float GetGameTimeSec();
static CM2Scene* GetM2Scene();
static uint32_t GetTickTimeFixed(); static uint32_t GetTickTimeFixed();
static uint32_t GetTickTimeMs(); static uint32_t GetTickTimeMs();
static float GetTickTimeSec(); static float GetTickTimeSec();
@ -72,6 +74,7 @@ class CWorld {
static float s_curTimeSec; static float s_curTimeSec;
static uint32_t s_gameTimeFixed; static uint32_t s_gameTimeFixed;
static float s_gameTimeSec; static float s_gameTimeSec;
static CM2Scene* s_m2Scene;
static uint32_t s_tickTimeFixed; static uint32_t s_tickTimeFixed;
static uint32_t s_tickTimeMs; static uint32_t s_tickTimeMs;
static float s_tickTimeSec; static float s_tickTimeSec;

View File

@ -23,6 +23,8 @@ if(WHOA_SYSTEM_MAC)
"-framework AppKit" "-framework AppKit"
"-framework Carbon" "-framework Carbon"
"-framework IOKit" "-framework IOKit"
"-framework Metal"
"-framework QuartzCore"
) )
endif() endif()