Compare commits
70 commits
4cb5db0129
...
e426bd95cc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e426bd95cc | ||
|
|
95b05c9e06 | ||
|
|
22cea43ea3 | ||
|
|
c60cbe211b | ||
|
|
f3ceb09e9d | ||
|
|
d22c6b96a6 | ||
|
|
2035aa96de | ||
|
|
51e57d4b27 | ||
|
|
e21c7e6235 | ||
|
|
7d9b244fb1 | ||
|
|
770ead30fc | ||
|
|
befcc681c5 | ||
|
|
6d6e55e3f2 | ||
|
|
6188ab372a | ||
|
|
c989c4837c | ||
|
|
07d2f8441c | ||
|
|
e331e03f4c | ||
|
|
ff15df90ad | ||
|
|
d73c3c1296 | ||
|
|
7afc1a3a5b | ||
|
|
01aeb424f6 | ||
|
|
a996ad893b | ||
|
|
3dbd276311 | ||
|
|
add868efe7 | ||
|
|
0d7e98ce6d | ||
|
|
fba5ab8527 | ||
|
|
98e3d7fa17 | ||
|
|
779dd40d2e | ||
|
|
38defb749a | ||
|
|
fafcae34db | ||
|
|
ee401857a1 | ||
|
|
279b86f980 | ||
|
|
a107b3f0de | ||
|
|
e66baf48bd | ||
|
|
c5aea5fa76 | ||
|
|
b779b21820 | ||
|
|
9886d0e91c | ||
|
|
2751e3ff3d | ||
|
|
dc5c68be89 | ||
|
|
c2b4547ea0 | ||
|
|
67dd9978df | ||
|
|
b574abe09d | ||
|
|
4d9d775cc8 | ||
|
|
0bb3ea5e00 | ||
|
|
d54f050f5b | ||
|
|
9bacaba47a | ||
|
|
b1b73cc318 | ||
|
|
e690233c8d | ||
|
|
248c0c6cc8 | ||
|
|
5aafb686cc | ||
|
|
b63782e6f5 | ||
|
|
30200c77da | ||
|
|
c3bce5ee83 | ||
|
|
f0bf88d57e | ||
|
|
db00a48497 | ||
|
|
181f099344 | ||
|
|
9434616b2b | ||
|
|
220df4d318 | ||
|
|
db06901420 | ||
|
|
353cbdcce8 | ||
|
|
f7a74bf6bd | ||
|
|
2282078421 | ||
|
|
11bd25e013 | ||
|
|
e0c7070795 | ||
|
|
f517a81de5 | ||
|
|
b2d111d403 | ||
|
|
99f060e6a2 | ||
|
|
35b31fdf7b | ||
|
|
b5208a4922 | ||
|
|
d33f0e43de |
155 changed files with 9144 additions and 686 deletions
60
AGENTS.md
60
AGENTS.md
|
|
@ -11,20 +11,32 @@ confirmed by other agents in peer review, and that is the normal path.
|
|||
Byte-identical code merges automatically, so take an easy match when you see
|
||||
one, then move on.
|
||||
|
||||
**Golden rule: confirm every submission.** `td submit` only queues a batch; the
|
||||
server's gates and compile run afterwards. Run `td batch <batchId>` (`td_get_batch`)
|
||||
right after every submit and read each function's state:
|
||||
- `returned`, `rejected` or `needs_cleanup`: read `td result <attemptId>`, fix it
|
||||
and resubmit before claiming the next region. Gate rejections show up within seconds.
|
||||
- still `queued` or `verifying`: move on, and check it again before your next
|
||||
`td sync` and before reporting to the user. Compiling can take up to an hour.
|
||||
- never wait for peer review or the merge; that takes hours or days.
|
||||
|
||||
Never report a submission as checked, in review or merged without having seen that state in `td batch`.
|
||||
|
||||
Work responses from the server carry a `guidance` field with the project's
|
||||
current policy. It is up to date and takes precedence over this file.
|
||||
|
||||
## Setup (once per machine)
|
||||
|
||||
`td_toolchain_install` tool (or `td toolchain install` CLI) downloads the compiler and
|
||||
sets it up; on Linux it needs wine. Checks compile **on your machine**. The
|
||||
sets it up. Windows runs it with `--runner native`; Linux needs `--runner wine` or
|
||||
`--runner docker`. Checks compile **on your machine**. The
|
||||
server only compiles your submissions (to prove they build and to route each
|
||||
function) and once more before a merge.
|
||||
|
||||
## Workflow: one region at a time
|
||||
|
||||
**Keep working until the user stops you.** After a submission, claim the next
|
||||
region right away; do not wait for its result.
|
||||
**Keep working until the user stops you.** After a submission, confirm it with
|
||||
`td batch` (golden rule above), then claim the next region; do not wait for peer review.
|
||||
|
||||
Before each region, preserve unfinished work, stop local workers/checks, and run
|
||||
`td_sync` tool (`td sync` CLI) from a clean working tree. Never discard work just to sync.
|
||||
|
|
@ -44,7 +56,7 @@ td sync
|
|||
any function of it, and the first accepted candidate of each function merges
|
||||
(the others are dropped, the rest of their batch goes on). Prefer a region
|
||||
nobody claimed; share only to help with a big or stuck one.
|
||||
3. **Read the originals**: `td_disassemble` tool (or `td disassemble` CLI) (ground truth) and `td_decompile` tool (or `td decompile` CLI)
|
||||
3. **Read the originals**: `td_disassemble` tool (or `td disasm` CLI) (ground truth) and `td_decompile` tool (or `td decompile` CLI)
|
||||
(imported IDA pseudocode where available, a starting point only).
|
||||
4. **Write each function** in its file, directly preceded by its annotation:
|
||||
```cpp
|
||||
|
|
@ -86,6 +98,9 @@ td sync
|
|||
Pass the same explicit `files` and task IDs to `td_submit`, including prerequisites not
|
||||
yet merged. Submit only finished, checked code; a queued or peer-review result
|
||||
is not a merge. Preserve pending payloads before restoring local changes.
|
||||
Then confirm the batch with `td batch <batchId>` (golden rule): `td submit`
|
||||
prints `queued` before the server's free-text, annotation and global-variable
|
||||
gates have run, and `td check` does not run those gates.
|
||||
|
||||
Found a mistake in a function that waits for review? `td_withdraw` (or `td withdraw` CLI) it: it
|
||||
leaves the queue and returns to your claim, to fix and submit again.
|
||||
|
|
@ -158,6 +173,41 @@ other contributors' agents: a function merges once "same" leads
|
|||
Implement claimed functions and their single-caller helpers in the unit assigned by the claim;
|
||||
do not split their implementation into separate helper `.cpp` files.
|
||||
|
||||
## Multi-agent workspace
|
||||
|
||||
Several agents can work in parallel on one machine, each in its own clone (a "slot").
|
||||
The container folder holds the main clone (this repository), `workers/<slot>/` (one clone
|
||||
per agent) and `_work/<slot>/` (check logs and edit backups, outside every repository).
|
||||
|
||||
- Each slot gets a copy of the main clone's `.td/` (`config.json`, `symbols.json`,
|
||||
`target.exe`), hidden from git. Never print the token in `.td/config.json` or copy it
|
||||
anywhere except a slot's `.td/`.
|
||||
- `scripts/workspace/` has a Linux/Git Bash and a Windows (PowerShell 5.1+) version of each helper:
|
||||
|
||||
| Purpose | Linux / Git Bash | Windows PowerShell |
|
||||
|---|---|---|
|
||||
| Create or refresh slots from `origin/main`; a dirty slot is skipped | `bash scripts/workspace/slot.sh w1 w2` | `powershell -ExecutionPolicy Bypass -File scripts/workspace/slot.ps1 w1 w2` |
|
||||
| Save the slot's edits to `_work/<slot>/pre-check-*.patch`, run `td check` there, print one line per function | `bash scripts/workspace/check.sh w1 <files> [--includers] [--full]` | `powershell -ExecutionPolicy Bypass -File scripts/workspace/check.ps1 w1 <files> [--includers] [--full]` |
|
||||
| Offline lookup in `.td/symbols.json` | `python3 scripts/workspace/sym.py <id\|name\|0xaddr> [--slot w1]` | `python scripts/workspace/sym.py <id\|name\|0xaddr> [--slot w1]` |
|
||||
|
||||
Run them from the main clone or from any slot. If the main clone is not named
|
||||
`rodecomp`, set `RODECOMP_MAIN` to its path.
|
||||
- MCP: configure `td mcp --workspace <main clone>` as a stdio MCP server in your agent's
|
||||
settings (`td connect` registers it for one client only). MCP tools act on the main
|
||||
clone; the `td` CLI acts on the clone it runs in.
|
||||
- Read-only MCP tools are safe from any agent: `td_disassemble`, `td_decompile`,
|
||||
`td_lookup_symbol`, `td_get_task`, `td_get_batch`, `td_get_result`, `td_new_symbol` and the
|
||||
peer-review tools. Anything that changes a working tree runs as the CLI from your own slot:
|
||||
`td region claim`, `td claim`, `td check <files>`, `td submit <taskIds> --files ...`,
|
||||
`td heartbeat`, `td release`, `td sync`. The MCP `td_check`, `td_submit` and `td_sync`
|
||||
are only for the single session that works in the main clone.
|
||||
- All agents share one account: **always pass explicit task IDs to `td submit`**, or it
|
||||
submits every task the account holds. Never commit or push; the server merges.
|
||||
- Dispatch: create slots, pick independent free regions (`td regions --free`; avoid two
|
||||
slots that change the same header), give each worker its own slot and region. A
|
||||
peer-review worker needs no slot. When a worker reports a batch it has confirmed with
|
||||
`td batch` (golden rule), refresh its slot and give it the next region.
|
||||
|
||||
## Structural maintenance (maintainers)
|
||||
|
||||
For data ownership, annotation moves and new owner units that belong to no function task:
|
||||
|
|
@ -208,7 +258,7 @@ Setup
|
|||
td ghidra download the server's Ghidra project (names applied, refreshed after merges)
|
||||
td ghidra install | build | sync pinned Ghidra: install it, analyze locally, re-apply symbols
|
||||
td update update td now (it also checks by itself once an hour)
|
||||
td connect [--workspace <dir>] connect your AI (registers with Claude Code, prints MCP settings)
|
||||
td connect [--workspace <dir>] register the MCP with a supported client, print MCP settings
|
||||
td mcp [--workspace <dir>] run the MCP server for your agent (stdio)
|
||||
|
||||
Work (a region: a source file or class, done as a whole)
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ if(WIN32)
|
|||
Source/UI/Window/UIMessageBox.cpp
|
||||
Source/UI/Window/WindowDialogs.cpp
|
||||
Source/Client/ReplayPacketRecorder.cpp
|
||||
Source/Client/Replay.cpp
|
||||
Source/UI/Cooldowns/CooldownState.cpp
|
||||
Source/UI/Cooldowns/CooldownDrawing.cpp
|
||||
Source/UI/Cooldowns/CooldownOwner.cpp
|
||||
|
|
|
|||
|
|
@ -199,6 +199,13 @@ Do not substitute `__FILE__` or `__LINE__` merely to follow a different project'
|
|||
invent diagnostic literals. Distinguish compiler-generated diagnostics from application arguments using
|
||||
the original instructions.
|
||||
|
||||
### Korean string literals
|
||||
|
||||
Sources are UTF-8; `compile.json` passes `/source-charset:utf-8 /execution-charset:.949`, so write Korean
|
||||
literals as Hangul (`"유저인터페이스\\item\\%s.bmp"`), not CP949 escapes. Keep `\x` escapes for bytes
|
||||
that are not CP949 Hangul: other code pages (Shift-JIS, GBK, Big5 font names), byte-order marks and key codes.
|
||||
Never use `/utf-8`, and never save sources as CP949/EUC-KR.
|
||||
|
||||
## 7. Platform and build scope
|
||||
|
||||
- This target is Windows x86. Keep code in its assigned existing translation unit and subsystem headers.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ namespace myGPack {
|
|||
2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11,
|
||||
};
|
||||
|
||||
// INLINED
|
||||
void Permute(std::uint8_t* block, const std::uint8_t* table, unsigned count) {
|
||||
std::uint8_t result[8] = {};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public:
|
|||
bool Add(const char* filename);
|
||||
bool Exists(const char* filename, bool looseOnly) const;
|
||||
void* Read(const char* filename, std::uint32_t* size, int option = 0);
|
||||
__declspec(noinline) void* ReadArchive(const char* filename, std::uint32_t* size);
|
||||
void* ReadArchive(const char* filename, std::uint32_t* size);
|
||||
BOOL Free(void* buffer);
|
||||
void ApplyAuxiliary(const void* data, std::uint32_t size);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,12 @@ char g_moduleBaseName[260] = {};
|
|||
char g_crashString[8096] = {};
|
||||
|
||||
namespace {
|
||||
// INLINED
|
||||
int ReadPlayerJob() {
|
||||
return g_session.m_job;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
const char* ReadPlayerJobName(int jobId) {
|
||||
const char* const* namesBegin = g_session.m_jobNamesBegin;
|
||||
const char* const* namesEnd = g_session.m_jobNamesEnd;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <utility>
|
||||
|
||||
namespace {
|
||||
// INLINED
|
||||
BrowserWindowSizing Sizing(CWebBrowser& owner) {
|
||||
return {owner.browser, owner.screenWidth, owner.screenHeight, owner.rebar, owner.auxiliaryVisible, owner.width, owner.height};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const char* InputCharset::Prefix(bool alternate) const {
|
|||
return prefix;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
unsigned InputCharset::CodePage(unsigned fallback) const {
|
||||
return this->enabled ? LanguageCodePage(this->language) : fallback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,15 @@
|
|||
void TraditionalKeyInput::InitializeMappings() {
|
||||
// STATIC: 0x011594E0
|
||||
// GLOBAL: gl_13427
|
||||
static constexpr std::uint8_t bytes[] = {0xA3, 0x74, 0xA3, 0x78, 0xA3, 0xBE, 0xA3, 0xBF, 0xA3, 0xA4, 0xA3, 0xBD, 0xA3, 0xBB, 0xA3, 0xAB, 0xA3,
|
||||
0xAF, 0xA3, 0xB3, 0xA3, 0x76, 0xA3, 0xA7, 0xA3, 0x74, 0xA3, 0x74, 0xA3, 0x74, 0xA3, 0xA2, 0xA3, 0xA6,
|
||||
0xA3, 0xA9, 0xA3, 0xAC, 0xA3, 0xB9, 0xA3, 0xAD, 0xA3, 0xB1, 0xA3, 0xAA, 0xA3, 0xBA, 0xA3, 0xB0, 0xA3,
|
||||
0xB4, 0xA3, 0x75, 0xA3, 0xA1, 0xA3, 0x7A, 0xA3, 0xA5, 0xA3, 0x74, 0xA3, 0xA3, 0xA3, 0x79, 0xA3, 0x74,
|
||||
0xA3, 0xA8, 0xA3, 0x77, 0xA3, 0xB7, 0xA3, 0xB5, 0xA3, 0xAE, 0xA3, 0xB2, 0xA3, 0xB6};
|
||||
static constexpr std::uint8_t zhuyinBig5[] = {0xA3, 0x74, 0xA3, 0x78, 0xA3, 0xBE, 0xA3, 0xBF, 0xA3, 0xA4, 0xA3, 0xBD, 0xA3, 0xBB, 0xA3, 0xAB, 0xA3,
|
||||
0xAF, 0xA3, 0xB3, 0xA3, 0x76, 0xA3, 0xA7, 0xA3, 0x74, 0xA3, 0x74, 0xA3, 0x74, 0xA3, 0xA2, 0xA3, 0xA6,
|
||||
0xA3, 0xA9, 0xA3, 0xAC, 0xA3, 0xB9, 0xA3, 0xAD, 0xA3, 0xB1, 0xA3, 0xAA, 0xA3, 0xBA, 0xA3, 0xB0, 0xA3,
|
||||
0xB4, 0xA3, 0x75, 0xA3, 0xA1, 0xA3, 0x7A, 0xA3, 0xA5, 0xA3, 0x74, 0xA3, 0xA3, 0xA3, 0x79, 0xA3, 0x74,
|
||||
0xA3, 0xA8, 0xA3, 0x77, 0xA3, 0xB7, 0xA3, 0xB5, 0xA3, 0xAE, 0xA3, 0xB2, 0xA3, 0xB6};
|
||||
static constexpr char categories[] = "11441443331111111132331233111121111133333";
|
||||
static constexpr unsigned char keys[] = "1234567890ABCDEFGHIJKLNMOPQRSTUVWXYZ\xBD\xBA\xBC\xBE\xBF";
|
||||
static constexpr unsigned char keys[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'N', 'M', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
VK_OEM_MINUS, VK_OEM_1, VK_OEM_COMMA, VK_OEM_PERIOD, VK_OEM_2, 0};
|
||||
|
||||
this->unknown04C1 = 0;
|
||||
|
||||
|
|
@ -23,8 +25,8 @@ void TraditionalKeyInput::InitializeMappings() {
|
|||
|
||||
for (unsigned index = 0; index < 41; ++index) {
|
||||
auto& mapping = this->mappings[keys[index]];
|
||||
mapping.bytes[0] = bytes[2 * index];
|
||||
mapping.bytes[1] = bytes[2 * index + 1];
|
||||
mapping.bytes[0] = zhuyinBig5[2 * index];
|
||||
mapping.bytes[1] = zhuyinBig5[2 * index + 1];
|
||||
mapping.bytes[2] = 0;
|
||||
mapping.category = static_cast<std::uint8_t>(categories[index] - '1');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,16 @@ CWorld g_world = {1};
|
|||
|
||||
// OFFSET: 0x00AD6450
|
||||
// FUNCTION: fn_17831
|
||||
CGameMode* CWorld::ActiveGameMode() {
|
||||
CMode* CWorld::ActiveGameMode() {
|
||||
return this->state == 1 ? this->gameMode : nullptr;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AD6700
|
||||
// FUNCTION: fn_17838
|
||||
void CMode::Slot5(int) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AD66D0
|
||||
// FUNCTION: fn_17835
|
||||
void CMode::Slot7(int) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_MODE_ACTIVEGAMEMODE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_MODE_ACTIVEGAMEMODE_H
|
||||
|
||||
class CGameMode;
|
||||
#include "Client/Mode/CMode.h"
|
||||
|
||||
struct CWorld {
|
||||
/* 0000 */ int running;
|
||||
/* 0004 */ CGameMode* gameMode;
|
||||
/* 0004 */ CMode* gameMode;
|
||||
/* 0008 */ unsigned char unknown_0008[0x50];
|
||||
/* 0058 */ int state;
|
||||
|
||||
CGameMode* ActiveGameMode();
|
||||
CMode* ActiveGameMode();
|
||||
};
|
||||
|
||||
extern CWorld g_world;
|
||||
|
|
|
|||
47
Source/Client/Mode/CMode.h
Normal file
47
Source/Client/Mode/CMode.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_MODE_CMODE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_MODE_CMODE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
class UIWindow;
|
||||
|
||||
class CMode {
|
||||
public:
|
||||
/* 0004 */ int cursorType;
|
||||
/* 0008 */ std::uint32_t cursorFrame;
|
||||
/* 000C */ int pendingCursorType;
|
||||
/* 0010 */ int unknown_0010;
|
||||
/* 0014 */ int running;
|
||||
/* 0018 */ int unknown_0018;
|
||||
/* 001C */ UIWindow* tooltip;
|
||||
/* 0020 */ std::uint32_t tooltipTick;
|
||||
/* 0024 */ std::uint32_t cursorTick;
|
||||
/* 0028 */ int unknown_0028;
|
||||
/* 002C */ int unknown_002C;
|
||||
/* 0030 */ int unknown_0030;
|
||||
/* 0034 */ int unknown_0034;
|
||||
/* 0038 */ std::string unknown_0038;
|
||||
/* 0050 */ int unknown_0050;
|
||||
/* 0054 */ int unknown_0054;
|
||||
|
||||
virtual ~CMode();
|
||||
virtual int Run();
|
||||
virtual void Initialize(const char* name);
|
||||
virtual void End();
|
||||
virtual void Update();
|
||||
virtual void Slot5(int value);
|
||||
virtual int SendMsg(int event, int argument1, int argument2, int argument3, int argument4);
|
||||
virtual void Slot7(int value);
|
||||
|
||||
CMode();
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(offsetof(CMode, cursorType) == 0x4);
|
||||
static_assert(offsetof(CMode, unknown_0038) == 0x38);
|
||||
static_assert(sizeof(CMode) == 0x58);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
26
Source/Client/ModeFade.cpp
Normal file
26
Source/Client/ModeFade.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "Client/ModeFade.h"
|
||||
#include "Contents/Sound/SoundMgr.h"
|
||||
#include "Render/Primitives/AlphaRectangle.h"
|
||||
|
||||
#include <timeapi.h>
|
||||
|
||||
// GLOBAL: gl_24680
|
||||
std::uint32_t g_modeFadeTick = 0;
|
||||
|
||||
// OFFSET: 0x00AD6740
|
||||
// FUNCTION: fn_17842
|
||||
void ModeFade::Draw() {
|
||||
if (this->requested != 0) {
|
||||
g_modeFadeTick = timeGetTime();
|
||||
g_soundMgr->FadeIn();
|
||||
this->requested = 0;
|
||||
}
|
||||
|
||||
const std::uint32_t elapsed = timeGetTime() - g_modeFadeTick;
|
||||
if (elapsed < 255) {
|
||||
DrawAlphaRectangle(
|
||||
this->primitives, this->textures, this->queues, 0, 0, this->screenWidth, this->screenHeight, (255 - elapsed) << 24, this->depthAlpha, this->depthStart,
|
||||
this->depthEnd
|
||||
);
|
||||
}
|
||||
}
|
||||
26
Source/Client/ModeFade.h
Normal file
26
Source/Client/ModeFade.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_MODEFADE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_MODEFADE_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class RenderPrimitivePool;
|
||||
class TextureCache;
|
||||
struct RenderQueues;
|
||||
|
||||
extern std::uint32_t g_modeFadeTick;
|
||||
|
||||
struct ModeFade {
|
||||
int& requested;
|
||||
RenderPrimitivePool& primitives;
|
||||
TextureCache& textures;
|
||||
RenderQueues& queues;
|
||||
const int& screenWidth;
|
||||
const int& screenHeight;
|
||||
const bool& depthAlpha;
|
||||
const float& depthStart;
|
||||
const float& depthEnd;
|
||||
|
||||
void Draw();
|
||||
};
|
||||
|
||||
#endif
|
||||
35
Source/Client/ModeFadeOut.cpp
Normal file
35
Source/Client/ModeFadeOut.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include "Client/ModeFadeOut.h"
|
||||
#include "Client/ModeFade.h"
|
||||
#include "Contents/Sound/SoundMgr.h"
|
||||
#include "Render/BitmapDrawing.h"
|
||||
#include "Render/Primitives/AlphaRectangle.h"
|
||||
#include "Render/Renderer.h"
|
||||
#include "Resource/Bitmap/BitmapResource.h"
|
||||
#include "Resource/ResourceMgr.h"
|
||||
#include "Resource/TextureNames.h"
|
||||
|
||||
#include <timeapi.h>
|
||||
|
||||
// OFFSET: 0x00AD6960
|
||||
// FUNCTION: fn_17847
|
||||
std::uint32_t FadeOutMode(CRenderer& renderer, CRenderSystemBase& system, TextureCache& textures, ResourceMgr& resources, TextureNames& names,
|
||||
int showLogo, bool depthAlpha, float depthStart, float depthEnd) {
|
||||
g_soundMgr->FadeOut();
|
||||
g_modeFadeTick = timeGetTime();
|
||||
renderer.CaptureBackBuffer();
|
||||
std::uint32_t elapsed = timeGetTime() - g_modeFadeTick;
|
||||
while (elapsed < 255) {
|
||||
DrawAlphaRectangle(renderer.primitives, textures, renderer.queues, 0, 0, renderer.viewport.width, renderer.viewport.height, elapsed << 24,
|
||||
depthAlpha, depthStart, depthEnd);
|
||||
if (showLogo != 0) {
|
||||
auto* logo = static_cast<CBitmapRes*>(resources.Load(names.Resolve("rag_logo.bmp")));
|
||||
DrawBitmapResource(system, renderer.viewport.width - 192, renderer.viewport.height - 122, logo);
|
||||
}
|
||||
if (renderer.Draw()) {
|
||||
renderer.Present(1);
|
||||
}
|
||||
renderer.RestoreBackBuffer();
|
||||
elapsed = timeGetTime() - g_modeFadeTick;
|
||||
}
|
||||
return elapsed;
|
||||
}
|
||||
15
Source/Client/ModeFadeOut.h
Normal file
15
Source/Client/ModeFadeOut.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_MODEFADEOUT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_MODEFADEOUT_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CRenderer;
|
||||
class CRenderSystemBase;
|
||||
class TextureCache;
|
||||
class ResourceMgr;
|
||||
struct TextureNames;
|
||||
|
||||
std::uint32_t FadeOutMode(CRenderer& renderer, CRenderSystemBase& system, TextureCache& textures, ResourceMgr& resources, TextureNames& names,
|
||||
int showLogo, bool depthAlpha, float depthStart, float depthEnd);
|
||||
|
||||
#endif
|
||||
247
Source/Client/Replay.cpp
Normal file
247
Source/Client/Replay.cpp
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
#include "Client/Replay.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
// GLOBAL: gl_24549
|
||||
int g_replayAnimationScaling = 0;
|
||||
|
||||
// GLOBAL: gl_24630
|
||||
static int g_replayFlushCounter = 0;
|
||||
|
||||
// STRING: st_16831
|
||||
static const char g_replayHeaderText[] = "<< Ragnarok Replay File Version 0.%02d >>\r\n \xA1\xD8 Do not modify file! ";
|
||||
|
||||
// STRING: st_16832
|
||||
static const char g_replayHeaderPrefix[] = "\r\n";
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ReplayTaggedRecordHeader {
|
||||
/* 0000 */ std::uint16_t id;
|
||||
/* 0002 */ std::uint32_t bytes;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static_assert(sizeof(ReplayTaggedRecordHeader) == 6);
|
||||
|
||||
// OFFSET: 0x006DA340
|
||||
// FUNCTION: fn_06623
|
||||
static std::vector<unsigned char> BuildReplayTaggedRecord(std::uint16_t id, const void* data, std::uint32_t bytes) {
|
||||
std::vector<unsigned char> record(bytes + 6u, 0);
|
||||
const ReplayTaggedRecordHeader header{id, bytes};
|
||||
std::memcpy(record.data(), &header, sizeof(header));
|
||||
if (bytes != 0) {
|
||||
std::memcpy(record.data() + sizeof(header), data, bytes);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B839D0
|
||||
// FUNCTION: fn_19302
|
||||
ReplaySection::ReplaySection() : id(0), bytes(0), fileOffset(0) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B83D20
|
||||
// FUNCTION: fn_19306
|
||||
ReplaySection::~ReplaySection() {
|
||||
this->id = 0;
|
||||
this->bytes = 0;
|
||||
this->fileOffset = 0;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B83540
|
||||
// FUNCTION: fn_19300
|
||||
Replay::Replay() : cipherIndex(0), cipherBase(0), cipherKey(0), unknown_01F4(0), unknown_01F8(0) {
|
||||
this->state = 1;
|
||||
this->baseFrame = 0;
|
||||
this->started = 0;
|
||||
this->frame = 0;
|
||||
this->elapsed = 0;
|
||||
this->speed = 1.0f;
|
||||
std::memset(&this->header, 0, sizeof(this->header));
|
||||
std::memset(&this->header.options, 1, sizeof(this->header.options));
|
||||
this->header.Reset();
|
||||
this->records = 0;
|
||||
this->fileMode = -1;
|
||||
this->file = nullptr;
|
||||
this->fileOffset = 0;
|
||||
this->previousTick = timeGetTime();
|
||||
this->unknown_01F8 = 0;
|
||||
this->unknown_01F4 = 0;
|
||||
this->cachedPackets.resize(3143, ReplayCachedPacket{});
|
||||
this->cachedPackets[2459].enabled = true;
|
||||
this->cachedPackets[470].enabled = true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B855B0
|
||||
// FUNCTION: fn_19326
|
||||
bool Replay::WriteSection(int id, std::vector<unsigned char>& bytes, int event) {
|
||||
if (bytes.empty()) {
|
||||
return false;
|
||||
}
|
||||
if (id <= 0 || id >= 26 || bytes.size() == 0 || bytes.data() == nullptr) {
|
||||
return false;
|
||||
}
|
||||
ReplaySection& section = this->sections[id];
|
||||
if (event == 14) {
|
||||
section.id = static_cast<std::uint16_t>(id);
|
||||
section.bytes = bytes.size();
|
||||
section.fileOffset = this->fileOffset;
|
||||
this->fileOffset += bytes.size();
|
||||
}
|
||||
if (section.bytes != 0) {
|
||||
this->cipherBase = this->header.key0 >> 5;
|
||||
this->cipherIndex = 0;
|
||||
this->cipherKey = this->header.key1 >> 3;
|
||||
for (std::uint32_t index = 0; index < section.bytes / 4; ++index) {
|
||||
std::uint32_t word;
|
||||
std::memcpy(&word, bytes.data() + index * 4, sizeof(word));
|
||||
word ^= this->cipherKey * (++this->cipherIndex + this->cipherBase);
|
||||
std::memcpy(bytes.data() + index * 4, &word, sizeof(word));
|
||||
}
|
||||
}
|
||||
std::fseek(this->file, static_cast<long>(section.fileOffset), SEEK_SET);
|
||||
return std::fwrite(bytes.data(), section.bytes, 1, this->file) != 0;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B857E0
|
||||
// FUNCTION: fn_19327
|
||||
int Replay::WriteHeader(int event) {
|
||||
this->header.records = this->records;
|
||||
this->header.fileOffset = this->fileOffset;
|
||||
this->header.closingSignature = 0x52414705;
|
||||
this->header.signature = 0x52414705;
|
||||
switch (event) {
|
||||
case 11: {
|
||||
this->sections[25].id = 111;
|
||||
bool written;
|
||||
{
|
||||
std::vector<unsigned char> metadata = this->BuildMetadata();
|
||||
written = this->WriteSection(2, metadata, 14);
|
||||
}
|
||||
if (!written) {
|
||||
return 0;
|
||||
}
|
||||
char text[100] = {};
|
||||
std::sprintf(text, g_replayHeaderText, 5);
|
||||
std::sprintf(text + 95, g_replayHeaderPrefix);
|
||||
std::fseek(this->file, 0, SEEK_SET);
|
||||
std::fwrite(text, sizeof(text), 1, this->file);
|
||||
std::fwrite(&this->header, 12, 1, this->file);
|
||||
return 1;
|
||||
}
|
||||
case 12: {
|
||||
if (++g_replayFlushCounter != 1200) {
|
||||
return 1;
|
||||
}
|
||||
this->header.closingSignature = 0x51404605;
|
||||
this->header.signature = 0x51404605;
|
||||
bool written;
|
||||
{
|
||||
std::vector<unsigned char> metadata = this->BuildMetadata();
|
||||
written = this->WriteSection(2, metadata, 15);
|
||||
}
|
||||
if (!written) {
|
||||
return 0;
|
||||
}
|
||||
std::fseek(this->file, 112, SEEK_SET);
|
||||
std::fwrite(this->sections, sizeof(this->sections), 1, this->file);
|
||||
g_replayFlushCounter = 0;
|
||||
return 1;
|
||||
}
|
||||
case 13: {
|
||||
bool written;
|
||||
{
|
||||
std::vector<unsigned char> metadata = this->BuildMetadata();
|
||||
written = this->WriteSection(2, metadata, 15);
|
||||
}
|
||||
if (!written) {
|
||||
return 0;
|
||||
}
|
||||
std::fseek(this->file, 112, SEEK_SET);
|
||||
std::fwrite(this->sections, sizeof(this->sections), 1, this->file);
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B85A20
|
||||
// FUNCTION: fn_19328
|
||||
std::vector<unsigned char> Replay::BuildMetadata() {
|
||||
std::vector<unsigned char> metadata;
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(950, nullptr, 0);
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(961, &this->header.service, sizeof(this->header.service));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(962, &this->header.serviceType, sizeof(this->header.serviceType));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(963, &this->header.unknown_0014, sizeof(this->header.unknown_0014));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(964, this->header.characterName, sizeof(this->header.characterName));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(965, this->header.mapName, sizeof(this->header.mapName));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(966, &this->header.accountId, sizeof(this->header.accountId));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(967, &this->header.cellX, sizeof(this->header.cellX));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(968, &this->header.cellY, sizeof(this->header.cellY));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(969, &this->header.unknown_0078, sizeof(this->header.unknown_0078));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(970, &this->header.duration, sizeof(this->header.duration));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(971, &this->header.records, sizeof(this->header.records));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(972, &this->header.fileOffset, sizeof(this->header.fileOffset));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(973, &this->header.options, sizeof(this->header.options));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(960, &this->header.closingSignature, sizeof(this->header.closingSignature));
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
{
|
||||
const auto record = BuildReplayTaggedRecord(951, nullptr, 0);
|
||||
metadata.insert(metadata.end(), record.begin(), record.end());
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B875E0
|
||||
// FUNCTION: fn_19354
|
||||
Replay& Replay::Instance() {
|
||||
// GLOBAL: gl_24631
|
||||
static Replay g_replay;
|
||||
return g_replay;
|
||||
}
|
||||
135
Source/Client/Replay.h
Normal file
135
Source/Client/Replay.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_REPLAY_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_REPLAY_H
|
||||
#include "Client/ReplayRecordOption.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
struct ReplayCachedPacket {
|
||||
/* 0000 */ bool enabled;
|
||||
/* 0004 */ std::vector<unsigned char> bytes;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ReplayOptions {
|
||||
/* 0000 */ unsigned char unknown_0000[6];
|
||||
/* 0006 */ unsigned char recordRestricted;
|
||||
/* 0007 */ unsigned char unknown_0007;
|
||||
/* 0008 */ unsigned char unknown_0008[22];
|
||||
|
||||
unsigned char Get(ReplayRecordOption option) const {
|
||||
return reinterpret_cast<const unsigned char*>(this)[static_cast<std::size_t>(option)];
|
||||
}
|
||||
|
||||
void Set(ReplayRecordOption option, unsigned char value) {
|
||||
reinterpret_cast<unsigned char*>(this)[static_cast<std::size_t>(option)] = value;
|
||||
}
|
||||
};
|
||||
|
||||
struct ReplayHeader {
|
||||
/* 0000 */ std::uint32_t signature;
|
||||
/* 0004 */ std::uint32_t key0;
|
||||
/* 0008 */ std::uint32_t key1;
|
||||
/* 000C */ int service;
|
||||
/* 0010 */ int serviceType;
|
||||
/* 0014 */ int unknown_0014;
|
||||
/* 0018 */ char characterName[64];
|
||||
/* 0058 */ char mapName[20];
|
||||
/* 006C */ int accountId;
|
||||
/* 0070 */ int cellX;
|
||||
/* 0074 */ int cellY;
|
||||
/* 0078 */ int unknown_0078;
|
||||
/* 007C */ std::uint32_t duration;
|
||||
/* 0080 */ std::uint32_t records;
|
||||
/* 0084 */ std::uint32_t fileOffset;
|
||||
/* 0088 */ ReplayOptions options;
|
||||
/* 00A6 */ std::uint32_t closingSignature;
|
||||
|
||||
// INLINED
|
||||
void Reset() {
|
||||
const ReplayOptions savedOptions = this->options;
|
||||
std::memset(this, 0, sizeof(*this));
|
||||
this->options = savedOptions;
|
||||
this->signature = 0x52414705;
|
||||
this->closingSignature = 0x52414705;
|
||||
}
|
||||
};
|
||||
|
||||
struct ReplaySection {
|
||||
/* 0000 */ std::uint16_t id;
|
||||
/* 0002 */ std::uint32_t bytes;
|
||||
/* 0006 */ std::uint32_t fileOffset;
|
||||
|
||||
ReplaySection();
|
||||
~ReplaySection();
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class Replay {
|
||||
public:
|
||||
static Replay& Instance();
|
||||
|
||||
/* 0000 */ std::vector<ReplayCachedPacket> cachedPackets;
|
||||
/* 000C */ int state;
|
||||
/* 0010 */ std::uint32_t baseFrame;
|
||||
/* 0014 */ std::uint32_t started;
|
||||
/* 0018 */ std::uint32_t previousTick;
|
||||
/* 001C */ std::uint32_t frame;
|
||||
/* 0020 */ std::uint32_t elapsed;
|
||||
/* 0024 */ float speed;
|
||||
/* 0028 */ ReplayHeader header;
|
||||
/* 00D2 */ ReplaySection sections[26];
|
||||
/* 01D8 */ int fileMode;
|
||||
/* 01DC */ std::FILE* file;
|
||||
/* 01E0 */ std::uint32_t fileOffset;
|
||||
/* 01E4 */ std::uint32_t records;
|
||||
/* 01E8 */ std::uint32_t cipherIndex;
|
||||
/* 01EC */ std::uint32_t cipherBase;
|
||||
/* 01F0 */ std::uint32_t cipherKey;
|
||||
/* 01F4 */ int unknown_01F4;
|
||||
/* 01F8 */ int unknown_01F8;
|
||||
|
||||
Replay();
|
||||
|
||||
// INLINED
|
||||
~Replay() {
|
||||
if (this->file) {
|
||||
if (this->fileMode == 31) {
|
||||
this->WriteHeader(13);
|
||||
}
|
||||
std::fclose(this->file);
|
||||
this->file = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool WriteSection(int id, std::vector<unsigned char>& bytes, int event);
|
||||
int WriteHeader(int event);
|
||||
std::vector<unsigned char> BuildMetadata();
|
||||
};
|
||||
|
||||
extern int g_replayAnimationScaling;
|
||||
|
||||
static_assert(sizeof(ReplayCachedPacket) == 0x10);
|
||||
static_assert(offsetof(ReplayCachedPacket, bytes) == 0x4);
|
||||
static_assert(sizeof(ReplayOptions) == 0x1E);
|
||||
static_assert(sizeof(ReplayHeader) == 0xAA);
|
||||
static_assert(offsetof(ReplayHeader, options) == 0x88);
|
||||
static_assert(offsetof(ReplayHeader, closingSignature) == 0xA6);
|
||||
static_assert(sizeof(ReplaySection) == 0xA);
|
||||
static_assert(offsetof(ReplaySection, bytes) == 0x2);
|
||||
static_assert(offsetof(ReplaySection, fileOffset) == 0x6);
|
||||
static_assert(sizeof(Replay) == 0x1FC);
|
||||
static_assert(offsetof(Replay, state) == 0xC);
|
||||
static_assert(offsetof(Replay, header) == 0x28);
|
||||
static_assert(offsetof(Replay, header) + offsetof(ReplayHeader, options) + offsetof(ReplayOptions, recordRestricted) == 0xB6);
|
||||
static_assert(offsetof(Replay, header) + offsetof(ReplayHeader, options) + offsetof(ReplayOptions, unknown_0007) == 0xB7);
|
||||
static_assert(offsetof(Replay, sections) == 0xD2);
|
||||
static_assert(offsetof(Replay, fileMode) == 0x1D8);
|
||||
static_assert(offsetof(Replay, file) == 0x1DC);
|
||||
static_assert(offsetof(Replay, cipherIndex) == 0x1E8);
|
||||
static_assert(offsetof(Replay, unknown_01F8) == 0x1F8);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "Client/ReplayPacketRecorder.h"
|
||||
#include "Network/Packets/PacketLengths.h"
|
||||
#include "Network/Packets/PacketId.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
|
@ -16,19 +17,19 @@ bool ReplayPacketRecorder::Record(std::uint16_t bytes, const void* packet, int e
|
|||
std::uint16_t id;
|
||||
std::memcpy(&id, packet, sizeof(id));
|
||||
|
||||
if (id != 2222) {
|
||||
if (id != ID_REPLAY_WINDOW_RESPONSE) {
|
||||
if (this->lengths.IsRecorded(id) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case 141:
|
||||
case 142:
|
||||
case 151:
|
||||
case 265:
|
||||
case 383:
|
||||
case 732:
|
||||
case 3038:
|
||||
case ID_ZC_NOTIFY_CHAT:
|
||||
case ID_ZC_NOTIFY_PLAYERCHAT:
|
||||
case ID_ZC_WHISPER:
|
||||
case ID_ZC_NOTIFY_CHAT_PARTY:
|
||||
case ID_ZC_GUILD_CHAT:
|
||||
case ID_ZC_BATTLEFIELD_CHAT:
|
||||
case ID_ZC_ALLY_CHAT:
|
||||
if (this->recordRestricted == 0) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_REPLAYPACKETRECORDER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_REPLAYPACKETRECORDER_H
|
||||
#include "Client/ReplayRecordOption.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
|
|
|||
30
Source/Client/ReplayRecordOption.h
Normal file
30
Source/Client/ReplayRecordOption.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_REPLAYRECORDOPTION_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_REPLAYRECORDOPTION_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class ReplayRecordOption : std::uint8_t {
|
||||
BasicInfo = 0,
|
||||
Equip = 1,
|
||||
Item = 2,
|
||||
Skill = 3,
|
||||
Guild = 4,
|
||||
Party = 5,
|
||||
Chatting = 6,
|
||||
Shortcut = 7,
|
||||
Status = 8,
|
||||
};
|
||||
|
||||
enum : int {
|
||||
REPLAY_RECORD_BASICINFO = 0,
|
||||
REPLAY_RECORD_EQUIP = 1,
|
||||
REPLAY_RECORD_ITEM = 2,
|
||||
REPLAY_RECORD_SKILL = 3,
|
||||
REPLAY_RECORD_GUILD = 4,
|
||||
REPLAY_RECORD_PARTY = 5,
|
||||
REPLAY_RECORD_CHATTING = 6,
|
||||
REPLAY_RECORD_SHORTCUT = 7,
|
||||
REPLAY_RECORD_STATUS = 8,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -11,7 +11,10 @@ public:
|
|||
/* 0000 */ unsigned char unknown_0000[0xF18];
|
||||
/* 0F18 */ int m_playerX;
|
||||
/* 0F1C */ int m_playerY;
|
||||
/* 0F20 */ unsigned char unknown_0F20[0x88];
|
||||
/* 0F20 */ unsigned char unknown_0F20[0x08];
|
||||
/* 0F28 */ int m_score1;
|
||||
/* 0F2C */ int m_score2;
|
||||
/* 0F30 */ unsigned char unknown_0F30[0x78];
|
||||
/* 0FA8 */ const char* const* m_jobNamesBegin;
|
||||
/* 0FAC */ const char* const* m_jobNamesEnd;
|
||||
/* 0FB0 */ unsigned char unknown_0FB0[0x678];
|
||||
|
|
@ -29,6 +32,8 @@ extern CSession g_session;
|
|||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(offsetof(CSession, m_playerX) == 0xF18);
|
||||
static_assert(offsetof(CSession, m_playerY) == 0xF1C);
|
||||
static_assert(offsetof(CSession, m_score1) == 0xF28);
|
||||
static_assert(offsetof(CSession, m_score2) == 0xF2C);
|
||||
static_assert(offsetof(CSession, m_jobNamesBegin) == 0xFA8);
|
||||
static_assert(offsetof(CSession, m_jobNamesEnd) == 0xFAC);
|
||||
static_assert(offsetof(CSession, m_job) == 0x1628);
|
||||
|
|
|
|||
28
Source/Contents/Actors/MercenaryAI.cpp
Normal file
28
Source/Contents/Actors/MercenaryAI.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include "Contents/Actors/MercenaryAI.h"
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D9E3F0
|
||||
// FUNCTION: fn_22327
|
||||
CMercenaryAI::CMercenaryAI(int kind) : state(nullptr), actionStarted(0), actionDuration(0), kind(kind), lastTick(0) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D9E430
|
||||
// FUNCTION: fn_22328
|
||||
CMercenaryAI::~CMercenaryAI() {
|
||||
if (this->state) {
|
||||
lua_close(this->state);
|
||||
this->state = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D9E570
|
||||
// FUNCTION: fn_22331
|
||||
void CMercenaryAI::Shutdown() {
|
||||
if (this->state) {
|
||||
lua_close(this->state);
|
||||
this->state = nullptr;
|
||||
}
|
||||
}
|
||||
32
Source/Contents/Actors/MercenaryAI.h
Normal file
32
Source/Contents/Actors/MercenaryAI.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_ACTORS_MERCENARYAI_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_ACTORS_MERCENARYAI_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
struct lua_State;
|
||||
|
||||
class CMercenaryAI {
|
||||
public:
|
||||
/* 0004 */ lua_State* state;
|
||||
/* 0008 */ std::uint32_t actionStarted;
|
||||
/* 000C */ std::uint32_t actionDuration;
|
||||
/* 0010 */ int kind;
|
||||
/* 0014 */ std::uint32_t lastTick;
|
||||
|
||||
virtual ~CMercenaryAI();
|
||||
|
||||
explicit CMercenaryAI(int kind);
|
||||
void Shutdown();
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(CMercenaryAI) == 0x18);
|
||||
static_assert(offsetof(CMercenaryAI, state) == 0x4);
|
||||
static_assert(offsetof(CMercenaryAI, actionStarted) == 0x8);
|
||||
static_assert(offsetof(CMercenaryAI, actionDuration) == 0xC);
|
||||
static_assert(offsetof(CMercenaryAI, kind) == 0x10);
|
||||
static_assert(offsetof(CMercenaryAI, lastTick) == 0x14);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -64,6 +64,7 @@ public:
|
|||
void
|
||||
StopRecruiting(std::uint32_t accountId, std::string world, std::string url, std::string token, std::uint32_t masterAccountId, StopRecruitingContext& context);
|
||||
|
||||
// INLINED
|
||||
CAsyncWorkRecycleObjectPoolMgr& Pools() {
|
||||
return *this->m_pools;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@
|
|||
struct ServiceOptions;
|
||||
|
||||
struct CameraState {
|
||||
float target[3];
|
||||
float pitch;
|
||||
float yaw;
|
||||
float distance;
|
||||
float desiredTarget[3];
|
||||
float desiredPitch;
|
||||
float desiredYaw;
|
||||
float desiredDistance;
|
||||
/* 0020 */ float target[3];
|
||||
/* 002C */ float pitch;
|
||||
/* 0030 */ float yaw;
|
||||
/* 0034 */ float distance;
|
||||
/* 0038 */ float desiredTarget[3];
|
||||
/* 0044 */ float desiredPitch;
|
||||
/* 0048 */ float desiredYaw;
|
||||
/* 004C */ float desiredDistance;
|
||||
|
||||
void Reset();
|
||||
void AddDistance(float delta);
|
||||
|
|
@ -30,13 +30,13 @@ struct CameraProjectionOutputs {
|
|||
};
|
||||
|
||||
struct CameraShake {
|
||||
float horizontal;
|
||||
float distance;
|
||||
float pitch;
|
||||
unsigned unknown_0010;
|
||||
int enabled;
|
||||
unsigned start;
|
||||
unsigned duration;
|
||||
/* 0004 */ float horizontal;
|
||||
/* 0008 */ float distance;
|
||||
/* 000C */ float pitch;
|
||||
/* 0010 */ unsigned unknown_0010;
|
||||
/* 0014 */ int enabled;
|
||||
/* 0018 */ unsigned start;
|
||||
/* 001C */ unsigned duration;
|
||||
|
||||
void Apply(CameraState& camera, int& frameLatch);
|
||||
void Start(int enabled, unsigned duration, float horizontal, float distance, float pitch);
|
||||
|
|
@ -44,5 +44,6 @@ struct CameraShake {
|
|||
};
|
||||
|
||||
static_assert(sizeof(CameraState) == 48);
|
||||
static_assert(sizeof(CameraShake) == 28);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ inline void GraphicsConfiguration::Load(LuaScript& script, ScriptOptions& option
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline AdapterConfiguration GraphicsConfiguration::Adapter() const {
|
||||
return {this->backend, this->drawGuid, this->renderGuid, this->deviceGuid, this->deviceName};
|
||||
}
|
||||
|
|
|
|||
7
Source/Contents/Configuration/ServiceConfiguration.cpp
Normal file
7
Source/Contents/Configuration/ServiceConfiguration.cpp
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "Contents/Configuration/ServiceConfiguration.h"
|
||||
|
||||
// GLOBAL: gl_24542
|
||||
signed char g_language = 0;
|
||||
|
||||
// GLOBAL: gl_24529
|
||||
int g_serviceType = 0;
|
||||
7
Source/Contents/Configuration/ServiceConfiguration.h
Normal file
7
Source/Contents/Configuration/ServiceConfiguration.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_CONFIGURATION_SERVICECONFIGURATION_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_CONFIGURATION_SERVICECONFIGURATION_H
|
||||
|
||||
extern signed char g_language;
|
||||
extern int g_serviceType;
|
||||
|
||||
#endif
|
||||
|
|
@ -9,6 +9,7 @@ EffectActorState::~EffectActorState() {
|
|||
this->Attachments().DetachAll();
|
||||
}
|
||||
|
||||
// INLINED
|
||||
EffectAttachments EffectActorState::Attachments() {
|
||||
return {this->effects, this->first, this->second};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ void EffectLists::Add(int actor, CEffect* effect) {
|
|||
case EF_EVILS_PAW:
|
||||
case EF_ANIMATED_EMITTER:
|
||||
case EF_NEW_RANGEDATTACK:
|
||||
case 2343:
|
||||
case EF_UNK_2343:
|
||||
this->indexed[effect->id].push_back(effect);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -6,7 +6,6 @@
|
|||
#include "Render/Textures/TextureCache.h"
|
||||
|
||||
#include <limits>
|
||||
#include <new>
|
||||
|
||||
// OFFSET: 0x00C2CF20
|
||||
// FUNCTION: fn_20088
|
||||
|
|
|
|||
|
|
@ -303,22 +303,22 @@ static void SelectRagEffectResource(RagEffectState& effect, ServiceOptions& opti
|
|||
std::sprintf(name, "Pong%d.str", std::rand() % 3 + 1);
|
||||
break;
|
||||
case 204:
|
||||
std::sprintf(name, "\273\241\260\243\306\367\274\307.str");
|
||||
std::sprintf(name, "빨간포션.str");
|
||||
break;
|
||||
case 205:
|
||||
std::sprintf(name, "\301\326\310\253\306\367\274\307.str");
|
||||
std::sprintf(name, "주홍포션.str");
|
||||
break;
|
||||
case 206:
|
||||
std::sprintf(name, "\263\353\266\365\306\367\274\307.str");
|
||||
std::sprintf(name, "노란포션.str");
|
||||
break;
|
||||
case 207:
|
||||
std::sprintf(name, "\307\317\276\341\306\367\274\307.str");
|
||||
std::sprintf(name, "하얀포션.str");
|
||||
break;
|
||||
case 208:
|
||||
std::sprintf(name, "\306\304\266\365\306\367\274\307.str");
|
||||
std::sprintf(name, "파란포션.str");
|
||||
break;
|
||||
case 209:
|
||||
std::sprintf(name, "\303\312\267\317\306\367\274\307.str");
|
||||
std::sprintf(name, "초록포션.str");
|
||||
break;
|
||||
case 210:
|
||||
std::sprintf(name, "fruit.str");
|
||||
|
|
@ -333,23 +333,23 @@ static void SelectRagEffectResource(RagEffectState& effect, ServiceOptions& opti
|
|||
std::sprintf(name, "Keeping.str");
|
||||
break;
|
||||
case 218:
|
||||
std::sprintf(name, "\301\375\301\337.str");
|
||||
std::sprintf(name, "집중.str");
|
||||
break;
|
||||
case 219:
|
||||
std::sprintf(name, "\260\242\274\272.str");
|
||||
std::sprintf(name, "각성.str");
|
||||
break;
|
||||
case 220:
|
||||
case 756:
|
||||
std::sprintf(name, "\271\366\274\255\305\251.str");
|
||||
std::sprintf(name, "버서크.str");
|
||||
break;
|
||||
case 234:
|
||||
std::sprintf(name, "spell.str");
|
||||
break;
|
||||
case 235:
|
||||
std::sprintf(name, "\265\360\275\272\306\347.str");
|
||||
std::sprintf(name, "디스펠.str");
|
||||
break;
|
||||
case 244:
|
||||
std::sprintf(name, "\270\305\301\367\267\316\265\345.str");
|
||||
std::sprintf(name, "매직로드.str");
|
||||
break;
|
||||
case 245:
|
||||
std::sprintf(name, "holy_cross.str");
|
||||
|
|
@ -391,7 +391,7 @@ static void SelectRagEffectResource(RagEffectState& effect, ServiceOptions& opti
|
|||
std::sprintf(name, "strip_helm.str");
|
||||
break;
|
||||
case 273:
|
||||
std::sprintf(name, "\277\254\310\257.str");
|
||||
std::sprintf(name, "연환.str");
|
||||
break;
|
||||
case 305:
|
||||
std::sprintf(name, "p_success.str");
|
||||
|
|
@ -419,16 +419,16 @@ static void SelectRagEffectResource(RagEffectState& effect, ServiceOptions& opti
|
|||
std::sprintf(name, "sword.str");
|
||||
break;
|
||||
case 406:
|
||||
std::sprintf(name, "\274\322\277\357\271\370.str");
|
||||
std::sprintf(name, "소울번.str");
|
||||
break;
|
||||
case 407:
|
||||
std::sprintf(name, "\273\347\266\367\310\277\260\372.str");
|
||||
std::sprintf(name, "사람효과.str");
|
||||
break;
|
||||
case 440:
|
||||
std::sprintf(name, "asum.str");
|
||||
break;
|
||||
case 491:
|
||||
std::sprintf(name, "\302\375\275\322\266\261.str");
|
||||
std::sprintf(name, "찹쌀떡.str");
|
||||
break;
|
||||
case 492:
|
||||
std::sprintf(name, "ramadan.str");
|
||||
|
|
@ -486,10 +486,10 @@ static void SelectRagEffectResource(RagEffectState& effect, ServiceOptions& opti
|
|||
std::sprintf(name, "icy.str");
|
||||
break;
|
||||
case 646:
|
||||
std::sprintf(name, "\306\256\267\242\305\267.str");
|
||||
std::sprintf(name, "트랙킹.str");
|
||||
break;
|
||||
case 649:
|
||||
std::sprintf(name, "\272\322\275\272\276\306\300\314.str");
|
||||
std::sprintf(name, "불스아이.str");
|
||||
break;
|
||||
case 668:
|
||||
case 670:
|
||||
|
|
@ -523,7 +523,7 @@ static void SelectRagEffectResource(RagEffectState& effect, ServiceOptions& opti
|
|||
std::sprintf(name, "ado.str");
|
||||
break;
|
||||
case 722:
|
||||
std::sprintf(name, "\300\314\261\327\264\317\274\307\272\352\267\271\300\314\305\251.str");
|
||||
std::sprintf(name, "이그니션브레이크.str");
|
||||
break;
|
||||
case 727:
|
||||
std::sprintf(name, "crimson_r.str");
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "Network/Http/CURLPostHander.h"
|
||||
#include "Network/TextEncoding.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ void GroundGeometry::Reset(int columns, int rows) {
|
|||
this->unknown_0058 = 0;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
GroundSpatial GroundGeometry::Spatial() const {
|
||||
return {this->width, this->height, this->cellSize, this->cells};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ float GroundWaterState::Level(int width, int height, int column, int row) const
|
|||
// FUNCTION: fn_17581
|
||||
void GroundWaterState::Update(TextureCache& textures) {
|
||||
// STATIC: 0x01159248
|
||||
constexpr char format[] = "\xBF\xF6\xC5\xCD\\water%d%02d.jpg";
|
||||
constexpr char format[] = "워터\\water%d%02d.jpg";
|
||||
char name[32]{};
|
||||
|
||||
for (GroundWaterSurface& surface : this->surfaces) {
|
||||
|
|
|
|||
|
|
@ -11,18 +11,22 @@ void SaveUserHotkeys();
|
|||
void ChangeUserHotkey(int tab, int index, int key1, int key2, const std::string& description);
|
||||
void LoadUserHotkeyTab(Json::Value& values, int tab);
|
||||
|
||||
// INLINED
|
||||
inline void ClearUserHotkeys(LuaScript&) {
|
||||
ClearUserHotkeys();
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline void SaveUserHotkeys(LuaScript&) {
|
||||
SaveUserHotkeys();
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline void ChangeUserHotkey(LuaScript&, int tab, int index, int key1, int key2, const std::string& description) {
|
||||
ChangeUserHotkey(tab, index, key1, key2, description);
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline void LoadUserHotkeyTab(LuaScript&, Json::Value& values, int tab) {
|
||||
LoadUserHotkeyTab(values, tab);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ ITEM_DESC& ItemDescriptions::Ensure(int id) {
|
|||
void ItemDescriptions::IconPath(char* output, const char* id, int identified) {
|
||||
const ITEM_DESC& value = this->Find(std::atoi(id));
|
||||
const char* resource = identified != 0 ? value.identifiedResource : value.unidentifiedResource;
|
||||
std::sprintf(output, "\xC0\xAF\xC0\xFA\xC0\xCE\xC5\xCD\xC6\xE4\xC0\xCC\xBD\xBA\\item\\%s.bmp", resource);
|
||||
std::sprintf(output, "유저인터페이스\\item\\%s.bmp", resource);
|
||||
}
|
||||
|
||||
// OFFSET: 0x006D5730
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include "Contents/MessageTable.h"
|
||||
#include "Contents/PlayerNameDictionary.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
|
@ -40,6 +39,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
const char* ItemNaming::Message(int id) const {
|
||||
return LookupMessage(id, this->languagePrefix, this->service, this->language);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
// FUNCTION: fn_23391
|
||||
const char* ItemDragResource(ItemDescriptions& descriptions, const char* id, int identified) {
|
||||
static std::string resource;
|
||||
resource = "\xBE\xC6\xC0\xCC\xC5\xDB\\";
|
||||
resource = "아이템\\";
|
||||
const ITEM_DESC& value = descriptions.Find(std::atoi(id));
|
||||
const char* name = identified != 0 ? value.identifiedResource : value.unidentifiedResource;
|
||||
resource += name ? name : "\xBB\xE7\xB0\xFA";
|
||||
resource += name ? name : "사과";
|
||||
|
||||
return resource.c_str();
|
||||
}
|
||||
|
|
@ -21,11 +21,11 @@ const char* ItemDragResource(ItemDescriptions& descriptions, const char* id, int
|
|||
// FUNCTION: fn_23392
|
||||
const char* SkillDragResource(ResourceMgr& resources, const char* name) {
|
||||
static std::string resource;
|
||||
resource = "\xBE\xC6\xC0\xCC\xC5\xDB\\";
|
||||
resource = "아이템\\";
|
||||
resource += name;
|
||||
|
||||
if (!resources.Exists((resource + ".act").c_str())) {
|
||||
resource = "\xBE\xC6\xC0\xCC\xC5\xDB\\am_berserkpitcher";
|
||||
resource = "아이템\\am_berserkpitcher";
|
||||
}
|
||||
|
||||
return resource.c_str();
|
||||
|
|
|
|||
|
|
@ -56,15 +56,15 @@ void JobNames::Initialize(JobNameInitialization& context) {
|
|||
this->names[JT_MER_SERA] = "MER_SERA";
|
||||
|
||||
for (unsigned id = JT_MER_ARCHER01; id <= JT_MER_ARCHER10; ++id) {
|
||||
this->names[id] = "\xBF\xA9\\\xC8\xB0\xBF\xEB\xBA\xB4";
|
||||
this->names[id] = "여\\활용병";
|
||||
}
|
||||
|
||||
for (unsigned id = JT_MER_LANCER01; id <= JT_MER_LANCER10; ++id) {
|
||||
this->names[id] = "\xB3\xB2\\\xC3\xA2\xBF\xEB\xBA\xB4";
|
||||
this->names[id] = "남\\창용병";
|
||||
}
|
||||
|
||||
for (unsigned id = JT_MER_SWORDMAN01; id <= JT_MER_SWORDMAN10; ++id) {
|
||||
this->names[id] = "\xB3\xB2\\\xB0\xCB\xBF\xEB\xBA\xB4";
|
||||
this->names[id] = "남\\검용병";
|
||||
}
|
||||
|
||||
context.sexLabels.resize(2, "F");
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ void C3dNode::Animate(double) {
|
|||
|
||||
// OFFSET: 0x00AB7050
|
||||
// FUNCTION: fn_17482
|
||||
void C3dNodeV1::Initialize(const ModelNode& resource) {
|
||||
void C3dNodeV1::Initialize(const ModelNode& base) {
|
||||
const auto& resource = static_cast<const ModelNodeV1&>(base);
|
||||
this->name = resource.name;
|
||||
this->mesh = resource.mesh.get();
|
||||
this->textures = resource.textures;
|
||||
|
|
@ -80,7 +81,8 @@ void C3dNodeV1::Initialize(const ModelNode& resource) {
|
|||
|
||||
// OFFSET: 0x00AB73F0
|
||||
// FUNCTION: fn_17484
|
||||
void C3dNodeV2::Initialize(const ModelNode& resource) {
|
||||
void C3dNodeV2::Initialize(const ModelNode& base) {
|
||||
const auto& resource = static_cast<const ModelNodeV2&>(base);
|
||||
this->name = resource.name;
|
||||
this->mesh = resource.mesh.get();
|
||||
std::memcpy(this->resourceTransform.values, resource.transform, sizeof(resource.transform));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <windows.h>
|
||||
|
||||
namespace {
|
||||
// INLINED
|
||||
unsigned UnsignedFrame(double value) {
|
||||
if (!(value < 0x1p32) || value <= -1.0) {
|
||||
return 0xFFFFFFFFu;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "Utility/Math/ScalarConversion.h"
|
||||
#include <cstring>
|
||||
|
||||
// INLINED
|
||||
ModelRenderContext::ModelRenderContext(
|
||||
const RenderProjection& projection, RenderCommandPool& commands, RenderVertexPool& vertices, RenderQueues& queues, const int& width, const int& height,
|
||||
const bool& depthAlpha, const float& depthStart, const float& depthEnd, const bool& overrideColor, const bool& integerColor, const float* overrideScale,
|
||||
|
|
|
|||
101
Source/Contents/MovementRoute.cpp
Normal file
101
Source/Contents/MovementRoute.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include "Contents/MovementRouteInterpolation.h"
|
||||
#include "Utility/Math/AffineMatrix.h"
|
||||
|
||||
// OFFSET: 0x00AD7F70
|
||||
// FUNCTION: fn_17861
|
||||
MovementRouteInterpolation::MovementRouteInterpolation() : segment(0), startX(0), startY(0) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AD87A0
|
||||
// FUNCTION: fn_17867
|
||||
void BuildMovementRoute(std::uint32_t tick, const MovementPathNode* last, int stepDuration, MovementRouteInterpolation& route) {
|
||||
std::uint32_t count = 0;
|
||||
for (const MovementPathNode* node = last; node; node = node->parent) {
|
||||
++count;
|
||||
}
|
||||
|
||||
route.points.resize(count);
|
||||
if (static_cast<int>(count) > 1) {
|
||||
const MovementPathNode* node = last;
|
||||
for (std::uint32_t index = count; index != 0;) {
|
||||
--index;
|
||||
route.points[index].x = node->x;
|
||||
route.points[index].y = node->y;
|
||||
route.points[index].metadata = node->metadata;
|
||||
node = node->parent;
|
||||
}
|
||||
|
||||
const int diagonalDuration = static_cast<int>(static_cast<float>(stepDuration) * 1.414f);
|
||||
route.points[0].tick = tick;
|
||||
const float deltaY = static_cast<float>(route.points[1].y) - route.startY;
|
||||
const float deltaX = static_cast<float>(route.points[1].x) - route.startX;
|
||||
const float initialDuration = SquareRoot(deltaY * deltaY + deltaX * deltaX) * static_cast<float>(stepDuration);
|
||||
route.points[1].tick = tick + static_cast<std::uint32_t>(initialDuration);
|
||||
for (std::uint32_t index = 2; index < count; ++index) {
|
||||
const int duration = route.points[index].metadata & 1 ? diagonalDuration : stepDuration;
|
||||
route.points[index].tick = route.points[index - 1].tick + duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AD8D20
|
||||
// FUNCTION: fn_17869
|
||||
bool MovementRouteInterpolation::Point(int index, std::int32_t* x, std::int32_t* y) const {
|
||||
if (this->points.empty() || index < 0 || static_cast<unsigned>(index) >= this->points.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*x = this->points[index].x;
|
||||
*y = this->points[index].y;
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AD8D70
|
||||
// FUNCTION: fn_17870
|
||||
std::uint32_t* MovementRouteInterpolation::EndTick(std::uint32_t* tick) const {
|
||||
*tick = this->points.back().tick;
|
||||
return tick;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AD8D90
|
||||
// FUNCTION: fn_17871
|
||||
int MovementRouteInterpolation::EndMetadata() const {
|
||||
if (this->points.empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this->points.back().metadata;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AD8F20
|
||||
// FUNCTION: fn_17874
|
||||
int MovementRouteInterpolation::NextPoint(std::uint32_t tick, std::uint32_t* nextTick, float* x, float* y) const {
|
||||
if (this->points.empty() || this->points.front().tick == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this->points.front().tick > tick) {
|
||||
*nextTick = this->points[1].tick;
|
||||
*x = static_cast<float>(this->points[1].x);
|
||||
*y = static_cast<float>(this->points[1].y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
const int last = static_cast<int>(this->points.size()) - 1;
|
||||
while (index < last) {
|
||||
if (this->points[index].tick <= tick && tick < this->points[index + 1].tick) {
|
||||
*nextTick = this->points[index + 1].tick;
|
||||
*x = static_cast<float>(this->points[index + 1].x);
|
||||
*y = static_cast<float>(this->points[index + 1].y);
|
||||
return index;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
*nextTick = this->points[index].tick;
|
||||
*x = static_cast<float>(this->points[index].x);
|
||||
*y = static_cast<float>(this->points[index].y);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,9 +1,20 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_MOVEMENTROUTEINTERPOLATION_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_MOVEMENTROUTEINTERPOLATION_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
struct MovementPathNode {
|
||||
/* 0000 */ std::int32_t x;
|
||||
/* 0004 */ std::int32_t y;
|
||||
/* 0008 */ MovementPathNode* parent;
|
||||
/* 000C */ int cost;
|
||||
/* 0010 */ int estimatedCost;
|
||||
/* 0014 */ int state;
|
||||
/* 0018 */ int metadata;
|
||||
};
|
||||
|
||||
struct MovementRoutePoint {
|
||||
/* 0000 */ std::int32_t x;
|
||||
/* 0004 */ std::int32_t y;
|
||||
|
|
@ -12,18 +23,31 @@ struct MovementRoutePoint {
|
|||
};
|
||||
|
||||
struct MovementRouteInterpolation {
|
||||
MovementRouteInterpolation();
|
||||
|
||||
/* 0000 */ std::vector<MovementRoutePoint> points;
|
||||
/* 000C */ std::uint32_t segment;
|
||||
/* 0010 */ float startX;
|
||||
/* 0014 */ float startY;
|
||||
|
||||
bool Point(int index, std::int32_t* x, std::int32_t* y) const;
|
||||
std::uint32_t* EndTick(std::uint32_t* tick) const;
|
||||
int EndMetadata() const;
|
||||
int NextPoint(std::uint32_t tick, std::uint32_t* nextTick, float* x, float* y) const;
|
||||
int Sample(std::uint32_t tick, float* x, float* y, int* metadata);
|
||||
std::uint32_t Segment() const;
|
||||
};
|
||||
|
||||
void BuildMovementRoute(std::uint32_t tick, const MovementPathNode* last, int stepDuration, MovementRouteInterpolation& route);
|
||||
|
||||
static_assert(sizeof(MovementRoutePoint) == 16);
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(MovementPathNode) == 28);
|
||||
static_assert(offsetof(MovementPathNode, metadata) == 0x18);
|
||||
static_assert(sizeof(MovementRouteInterpolation) == 24);
|
||||
static_assert(offsetof(MovementRouteInterpolation, segment) == 0xC);
|
||||
static_assert(offsetof(MovementRouteInterpolation, startX) == 0x10);
|
||||
static_assert(offsetof(MovementRouteInterpolation, startY) == 0x14);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ extern "C" {
|
|||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
// INLINED
|
||||
CPlayerSkillBundle& Bundle(lua_State* state) {
|
||||
return *static_cast<CPlayerSkillBundle*>(lua_touserdata(state, lua_upvalueindex(1)));
|
||||
}
|
||||
|
|
@ -59,6 +60,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
void RegisterSkillTreeCallbacks(lua_State* state, CPlayerSkillBundle& bundle) {
|
||||
lua_pushlightuserdata(state, &bundle);
|
||||
lua_pushcclosure(state, AddSkill, 1);
|
||||
|
|
|
|||
109
Source/Contents/Sound/SoundMaker.cpp
Normal file
109
Source/Contents/Sound/SoundMaker.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
#include "Contents/Sound/SoundMaker.h"
|
||||
|
||||
#include "Contents/Sound/SoundMgr.h"
|
||||
#include "Resource/World/WorldResource.h"
|
||||
#include "Utility/Math/AffineMatrix.h"
|
||||
#include "Utility/Math/ScalarConversion.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
// OFFSET: 0x00DA1E30
|
||||
// FUNCTION: fn_22363
|
||||
CSoundMaker::CSoundMaker(ResourceMgr& resources, JobNames& names, SoundMakerContext& context)
|
||||
: CRenderObject(resources, names), m_context(&context) {
|
||||
this->file.clear();
|
||||
this->volume = 100.0f;
|
||||
this->range = 1.0f;
|
||||
this->width = 3;
|
||||
this->height = 3;
|
||||
this->radius = SquareRoot(18.0f);
|
||||
this->lastTick = timeGetTime() - 4000u;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00DA3A60
|
||||
// FUNCTION: fn_22406
|
||||
bool CSoundMaker::Update() {
|
||||
if (this->width == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const CRenderObject* player = this->m_context->localPlayer;
|
||||
if (!player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const float distance = this->HorizontalDistance(player->render.position[0], player->render.position[2]);
|
||||
if (distance - (this->radius + this->range) > 130.0f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const float deltaX = player->render.position[0] - this->render.position[0];
|
||||
const float deltaZ = player->render.position[2] - this->render.position[2];
|
||||
float signX = 1.0f;
|
||||
float signZ = 1.0f;
|
||||
if (deltaX < 0.0f && deltaZ >= 0.0f) {
|
||||
signX = -1.0f;
|
||||
} else if (deltaX < 0.0f && deltaZ < 0.0f) {
|
||||
signX = -1.0f;
|
||||
signZ = -1.0f;
|
||||
} else if (deltaX >= 0.0f && deltaZ < 0.0f) {
|
||||
signZ = -1.0f;
|
||||
}
|
||||
|
||||
const float slope = deltaZ / std::fmax(deltaX, 0.001f);
|
||||
float offsetX;
|
||||
float offsetZ;
|
||||
if (!(static_cast<float>(this->height / this->width) >= std::fabs(slope))) {
|
||||
offsetZ = static_cast<float>(this->height) * signZ * 0.5f;
|
||||
offsetX = offsetZ / std::fmax(slope, 0.001f);
|
||||
} else {
|
||||
offsetX = static_cast<float>(this->width) * signX * 0.5f;
|
||||
offsetZ = slope * offsetX;
|
||||
}
|
||||
|
||||
const float x = this->render.position[0] + offsetX;
|
||||
const float z = this->render.position[2] + offsetZ;
|
||||
if (player->HorizontalDistance(x, z) - this->range > 75.0f || this->file.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (timeGetTime() > this->lastTick + this->cycle) {
|
||||
this->lastTick = timeGetTime();
|
||||
g_soundMgr->PlayWave(
|
||||
this->file.c_str(), x - player->render.position[0], 0.0f, z - player->render.position[2], TruncateToInt(this->range),
|
||||
TruncateToInt(this->range / 6.0f), this->volume, 0
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00DA4960
|
||||
// FUNCTION: fn_22417
|
||||
void CSoundMaker::Draw(int) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00DA56E0
|
||||
// FUNCTION: fn_22428
|
||||
void CSoundMaker::SendObjectMessage(
|
||||
CGameObject* sender, int message, int a, int b, int c, int d, int e, int f, int g, int h, int i, int, int, int, int
|
||||
) {
|
||||
if (message != 14 || a != 0) {
|
||||
CRenderObject::SendObjectMessage(sender, message, a, b, c, d, e, f, g, h, i, 0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
const WorldSoundRecord& sound = *reinterpret_cast<const WorldSoundRecord*>(b);
|
||||
this->file = sound.file;
|
||||
this->volume = sound.volume;
|
||||
this->width = sound.width;
|
||||
this->height = sound.height;
|
||||
this->range = sound.range;
|
||||
this->render.position[0] = sound.position[0];
|
||||
this->render.position[1] = sound.position[1];
|
||||
this->render.position[2] = sound.position[2];
|
||||
this->radius = SquareRoot(static_cast<float>(this->width * this->width + this->height * this->height));
|
||||
this->cycle = static_cast<std::int64_t>(sound.cycle * 1000.0f);
|
||||
this->lastTick = timeGetTime() - this->cycle;
|
||||
}
|
||||
47
Source/Contents/Sound/SoundMaker.h
Normal file
47
Source/Contents/Sound/SoundMaker.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_SOUND_SOUNDMAKER_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_SOUND_SOUNDMAKER_H
|
||||
|
||||
#include "Contents/Actors/RenderObject.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
struct SoundMakerContext {
|
||||
CRenderObject* const& localPlayer;
|
||||
};
|
||||
|
||||
class CSoundMaker : public CRenderObject {
|
||||
public:
|
||||
CSoundMaker(ResourceMgr& resources, JobNames& names, SoundMakerContext& context);
|
||||
~CSoundMaker() override = default;
|
||||
bool Update() override;
|
||||
void SendObjectMessage(
|
||||
CGameObject* sender, int message, int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m
|
||||
) override;
|
||||
void Draw(int argument) override;
|
||||
|
||||
/* 0138 */ std::string file;
|
||||
/* 0150 */ float volume;
|
||||
/* 0154 */ int width;
|
||||
/* 0158 */ int height;
|
||||
/* 015C */ float range;
|
||||
/* 0160 */ float radius;
|
||||
/* 0164 */ std::uint32_t lastTick;
|
||||
/* 0168 */ std::uint32_t cycle;
|
||||
|
||||
private:
|
||||
alignas(8) SoundMakerContext* m_context;
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(offsetof(CSoundMaker, file) == 0x138);
|
||||
static_assert(offsetof(CSoundMaker, volume) == 0x150);
|
||||
static_assert(offsetof(CSoundMaker, width) == 0x154);
|
||||
static_assert(offsetof(CSoundMaker, height) == 0x158);
|
||||
static_assert(offsetof(CSoundMaker, range) == 0x15C);
|
||||
static_assert(offsetof(CSoundMaker, radius) == 0x160);
|
||||
static_assert(offsetof(CSoundMaker, lastTick) == 0x164);
|
||||
static_assert(offsetof(CSoundMaker, cycle) == 0x168);
|
||||
static_assert(sizeof(CSoundMaker) == 0x178);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -33,7 +33,6 @@ CSoundMgr::CSoundMgr(SoundMgrContext& context) : m_context(&context) {
|
|||
}
|
||||
|
||||
// OFFSET: 0x00638C40
|
||||
// OFFSET: 0x00638D50
|
||||
// FUNCTION: fn_45422
|
||||
CSoundMgr::~CSoundMgr() {
|
||||
this->Shutdown();
|
||||
|
|
@ -553,7 +552,7 @@ void CSoundMgr::PlayWave(const char* name, float x, float y, float z, int maximu
|
|||
return;
|
||||
}
|
||||
|
||||
static constexpr char permittedName[] = "\xB9\xF6\xC6\xB0\xBC\xD2\xB8\xAE.wav";
|
||||
static constexpr char permittedName[] = "버튼소리.wav";
|
||||
|
||||
if (this->unknown != 0 && std::strcmp(name, permittedName) != 0) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ void WorldModelLoading::Run() {
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
void WorldModelLoading::Publish(WorldSpatialTree& root) {
|
||||
C3dActor* const* data = this->models.data();
|
||||
PublishWorldModels(root, data, this->published, this->pending);
|
||||
|
|
|
|||
77
Source/Contents/World/WorldScene.h
Normal file
77
Source/Contents/World/WorldScene.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_WORLD_WORLDSCENE_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_WORLD_WORLDSCENE_H
|
||||
|
||||
#include "Contents/World/WorldSpatialTree.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class BinkMovies;
|
||||
class CGameMode;
|
||||
class CPlayer;
|
||||
class CRenderObject;
|
||||
class GroundGeometry;
|
||||
|
||||
class WorldScene {
|
||||
public:
|
||||
WorldScene();
|
||||
virtual ~WorldScene();
|
||||
WorldScene(const WorldScene&) = delete;
|
||||
WorldScene& operator=(const WorldScene&) = delete;
|
||||
|
||||
/* 0004 */ CGameMode* gameMode;
|
||||
/* 0008 */ std::list<CRenderObject*> objects;
|
||||
/* 0010 */ std::list<CRenderObject*> actors;
|
||||
/* 0018 */ std::list<CRenderObject*> unknown_0018;
|
||||
/* 0020 */ std::list<CRenderObject*> unknown_0020;
|
||||
/* 0028 */ GroundGeometry* ground;
|
||||
/* 002C */ CPlayer* player;
|
||||
/* 0030 */ C3dAttr* terrain;
|
||||
/* 0034 */ std::vector<C3dActor*> models;
|
||||
/* 0040 */ int published;
|
||||
/* 0044 */ int pending;
|
||||
/* 0048 */ int unknown_0048;
|
||||
/* 004C */ int unknown_004C;
|
||||
/* 0050 */ int unknown_0050;
|
||||
/* 0054 */ int unknown_0054;
|
||||
/* 0058 */ WorldSpatialTree spatial;
|
||||
/* 00D4 */ const WorldSpatialTree* serializedSpatial;
|
||||
/* 00D8 */ std::list<std::uint32_t> pendingActorIds;
|
||||
/* 00E0 */ BinkMovies* movies;
|
||||
/* 00E4 */ std::map<float, std::list<std::uint32_t>> actorCells;
|
||||
/* 00EC */ std::list<std::uint32_t> unindexedActorIds;
|
||||
/* 00F4 */ bool unknown_00F4;
|
||||
/* 00F8 */ int nearbyRange;
|
||||
/* 00FC */ bool unknown_00FC;
|
||||
/* 00FD */ bool unknown_00FD;
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(offsetof(WorldScene, gameMode) == 0x04);
|
||||
static_assert(offsetof(WorldScene, objects) == 0x08);
|
||||
static_assert(offsetof(WorldScene, actors) == 0x10);
|
||||
static_assert(offsetof(WorldScene, unknown_0018) == 0x18);
|
||||
static_assert(offsetof(WorldScene, unknown_0020) == 0x20);
|
||||
static_assert(offsetof(WorldScene, ground) == 0x28);
|
||||
static_assert(offsetof(WorldScene, player) == 0x2C);
|
||||
static_assert(offsetof(WorldScene, terrain) == 0x30);
|
||||
static_assert(offsetof(WorldScene, models) == 0x34);
|
||||
static_assert(offsetof(WorldScene, published) == 0x40);
|
||||
static_assert(offsetof(WorldScene, pending) == 0x44);
|
||||
static_assert(offsetof(WorldScene, spatial) == 0x58);
|
||||
static_assert(offsetof(WorldScene, serializedSpatial) == 0xD4);
|
||||
static_assert(offsetof(WorldScene, pendingActorIds) == 0xD8);
|
||||
static_assert(offsetof(WorldScene, movies) == 0xE0);
|
||||
static_assert(offsetof(WorldScene, actorCells) == 0xE4);
|
||||
static_assert(offsetof(WorldScene, unindexedActorIds) == 0xEC);
|
||||
static_assert(offsetof(WorldScene, unknown_00F4) == 0xF4);
|
||||
static_assert(offsetof(WorldScene, nearbyRange) == 0xF8);
|
||||
static_assert(offsetof(WorldScene, unknown_00FC) == 0xFC);
|
||||
static_assert(offsetof(WorldScene, unknown_00FD) == 0xFD);
|
||||
static_assert(sizeof(WorldScene) == 0x100);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,9 +1,43 @@
|
|||
#include "Client/Session.h"
|
||||
#include "Contents/Ground/GroundGeometry.h"
|
||||
#include "Contents/Ground/GroundSpatial.h"
|
||||
#include "Contents/Models/ModelActor.h"
|
||||
#include "Contents/Movies/BinkMovies.h"
|
||||
#include "Contents/World/WorldScene.h"
|
||||
#include "Contents/World/WorldSpatialTree.h"
|
||||
#include "Resource/ResourceByteReader.h"
|
||||
#include "Resource/World/TerrainResource.h"
|
||||
|
||||
// OFFSET: 0x00AC64F0
|
||||
// FUNCTION: fn_17651
|
||||
WorldScene::WorldScene() {
|
||||
this->unknown_00FD = false;
|
||||
this->serializedSpatial = nullptr;
|
||||
this->pending = 0;
|
||||
this->ground = nullptr;
|
||||
this->player = nullptr;
|
||||
this->unknown_0048 = 0;
|
||||
this->unknown_004C = 0;
|
||||
this->unknown_0050 = 0;
|
||||
g_session.m_score1 = -1;
|
||||
g_session.m_score2 = -1;
|
||||
this->unknown_0054 = 0;
|
||||
this->unknown_00F4 = false;
|
||||
this->nearbyRange = 2;
|
||||
this->unknown_00FC = false;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AC6FB0
|
||||
// FUNCTION: fn_17654
|
||||
WorldScene::~WorldScene() {
|
||||
delete this->ground;
|
||||
|
||||
if (this->movies) {
|
||||
delete this->movies;
|
||||
this->movies = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AC66F0
|
||||
// FUNCTION: fn_17652
|
||||
WorldSpatialTree::WorldSpatialTree() : parent(nullptr), children{}, minimum{}, maximum{}, center{}, halfSize{}, dirty(1) {
|
||||
|
|
@ -286,3 +320,58 @@ std::vector<C3dActor*>& WorldSpatialTree::ModelsAt(float x, float z, int depth)
|
|||
|
||||
return node->objects;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00ACB560
|
||||
// FUNCTION: fn_17704
|
||||
void WorldSpatialTree::RefreshModelBounds(int depth) {
|
||||
this->dirty = 0;
|
||||
|
||||
if (depth != 5) {
|
||||
for (WorldSpatialTree* child : this->children) {
|
||||
if (child->dirty) {
|
||||
child->RefreshModelBounds(depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float groundMinimum;
|
||||
float groundMaximum;
|
||||
float terrainMinimum;
|
||||
float terrainMaximum;
|
||||
this->ground->HeightBounds(this->groundCells, groundMinimum, groundMaximum);
|
||||
this->terrain->Grid().HeightBounds(this->terrainCells, terrainMinimum, terrainMaximum);
|
||||
this->maximum[1] = terrainMaximum > groundMaximum ? terrainMaximum : groundMaximum;
|
||||
this->minimum[1] = terrainMinimum < groundMinimum ? terrainMinimum : groundMinimum;
|
||||
|
||||
for (C3dActor* model : this->objects) {
|
||||
if (this->minimum[1] > model->minimum[1]) {
|
||||
this->minimum[1] = model->minimum[1];
|
||||
}
|
||||
|
||||
if (model->maximum[1] > this->maximum[1]) {
|
||||
this->maximum[1] = model->maximum[1];
|
||||
}
|
||||
}
|
||||
|
||||
WorldSpatialTree* node = this;
|
||||
|
||||
do {
|
||||
if (node->minimum[1] > this->minimum[1]) {
|
||||
node->minimum[1] = this->minimum[1];
|
||||
}
|
||||
|
||||
if (this->maximum[1] > node->maximum[1]) {
|
||||
node->maximum[1] = this->maximum[1];
|
||||
}
|
||||
|
||||
node->halfSize[0] = node->maximum[0] - node->center[0];
|
||||
const float halfZ = node->maximum[2] - node->center[2];
|
||||
const float middleY = (node->maximum[1] + node->minimum[1]) * 0.5f;
|
||||
node->center[1] = middleY;
|
||||
node->halfSize[2] = halfZ;
|
||||
node->halfSize[1] = node->maximum[1] - middleY;
|
||||
node = node->parent;
|
||||
} while (node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct WorldSpatialTree {
|
|||
void BindGround(GroundSpatial& resource, int depth);
|
||||
void CopyBounds(int depth, const WorldSpatialTree& source);
|
||||
void RefreshBounds(int depth);
|
||||
void RefreshModelBounds(int depth);
|
||||
void InsertModel(C3dActor& model, int depth);
|
||||
void RemoveModel(C3dActor* model, int depth);
|
||||
std::vector<C3dActor*>& ModelsAt(float x, float z, int depth);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
#include "Client/Application/ErrorDialog.h"
|
||||
#include "File/File.h"
|
||||
#include "File/ResourcePath.h"
|
||||
#include "Archive/PakRegistry.h"
|
||||
#include "Render/DeviceContext/DCSurface.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
|
@ -7,7 +10,7 @@
|
|||
CFile::CFile() : m_handle(INVALID_HANDLE_VALUE), m_data(nullptr), m_position(0), m_size(0) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x005222F0
|
||||
// OFFSET: 0x00522230
|
||||
// FUNCTION: fn_01124
|
||||
CFile::~CFile() {
|
||||
this->Close();
|
||||
|
|
@ -29,6 +32,38 @@ bool CFile::OpenWrite(const char* path, CRenderSystemBase* renderSystem) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x0057C030
|
||||
// FUNCTION: fn_02597
|
||||
bool CFile::Open(const char* path, int mode, bool resourcePath, bool option) {
|
||||
if (mode == 0) {
|
||||
if (resourcePath) {
|
||||
this->m_path = MakeResourcePath(path);
|
||||
} else {
|
||||
this->m_path = path;
|
||||
}
|
||||
|
||||
this->m_position = 0;
|
||||
this->m_data = g_pakRegistry.Read(this->m_path.c_str(), &this->m_size, option);
|
||||
return this->m_data != nullptr;
|
||||
}
|
||||
|
||||
if ((mode & 1) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->m_path = path;
|
||||
this->m_handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (this->m_handle == INVALID_HANDLE_VALUE) {
|
||||
ShowErrorDialog(GetRenderSystemHolder()->system, this->m_path.c_str(), 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
LARGE_INTEGER size;
|
||||
GetFileSizeEx(this->m_handle, &size);
|
||||
this->m_size = size.LowPart;
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x0057C340
|
||||
// FUNCTION: fn_02601
|
||||
bool CFile::Write(const void* data, std::uint32_t bytes) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ public:
|
|||
virtual ~CFile();
|
||||
|
||||
bool OpenWrite(const char* path, CRenderSystemBase* renderSystem);
|
||||
bool Open(const char* path, int mode, bool resourcePath, bool option);
|
||||
// INLINED
|
||||
bool Open(const char* path) {
|
||||
this->m_path = path;
|
||||
this->m_handle = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
|
|
|||
|
|
@ -46,12 +46,15 @@ public:
|
|||
void ResetBuffers();
|
||||
void SetDeferred(unsigned char value);
|
||||
|
||||
// INLINED
|
||||
SOCKET NativeSocket() const {
|
||||
return this->m_socket;
|
||||
}
|
||||
// INLINED
|
||||
ConnectionBuffer& Input() {
|
||||
return this->m_input;
|
||||
}
|
||||
// INLINED
|
||||
unsigned& SendDeadline() {
|
||||
return this->m_sendDeadline;
|
||||
}
|
||||
|
|
|
|||
845
Source/Network/Packets/PacketId.h
Normal file
845
Source/Network/Packets/PacketId.h
Normal file
|
|
@ -0,0 +1,845 @@
|
|||
#ifndef RAGNAROK_SOURCE_NETWORK_PACKETS_PACKETID_H
|
||||
#define RAGNAROK_SOURCE_NETWORK_PACKETS_PACKETID_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum PacketId : std::int16_t {
|
||||
ID_ZC_PAR_4JOB_CHANGE = 0xb25,
|
||||
ID_ZC_PAR_CHANGE = 0xb0,
|
||||
ID_ZC_LONGPAR_CHANGE = 0xb1,
|
||||
ID_ZC_STATUS_CHANGE = 0xbe,
|
||||
ID_ZC_NOTIFY_CARTITEM_COUNTINFO = 0x121,
|
||||
ID_ZC_ATTACK_RANGE = 0x13a,
|
||||
ID_ZC_COUPLESTATUS = 0x141,
|
||||
ID_ZC_LONGLONGPAR_CHANGE = 0xacb,
|
||||
ID_ZC_ITEM_PICKUP_ACK = 0xb41,
|
||||
ID_ZC_BROADCASTING_SPECIAL_ITEM_OBTAIN_item = 0xbba,
|
||||
ID_ZC_INVENTORY_START = 0xb08,
|
||||
ID_ZC_INVENTORY_END = 0xb0b,
|
||||
ID_ZC_REQ_WEAR_EQUIP_ACK = 0x999,
|
||||
ID_ZC_EQUIPWIN_MICROSCOPE = 0xb37,
|
||||
ID_CZ_NPC_MARKET_PURCHASE = 0x9d6,
|
||||
ID_ZC_NPC_MARKET_OPEN = 0xb7a,
|
||||
ID_ZC_SHORTCUT_KEY_LIST = 0xb20,
|
||||
ID_CZ_SHORTCUT_KEY_CHANGE1 = 0x2ba,
|
||||
ID_CZ_SHORTCUT_KEY_CHANGE2 = 0xb21,
|
||||
ID_CZ_SHORTCUTKEYBAR_ROTATE1 = 0xa01,
|
||||
ID_CZ_SHORTCUTKEYBAR_ROTATE2 = 0xb22,
|
||||
ID_ZC_ACK_ADD_ITEM_RODEX = 0xb3f,
|
||||
ID_CZ_CHECKNAME1 = 0xa13,
|
||||
ID_CZ_CHECKNAME2 = 0xb97,
|
||||
ID_ZC_CHECKNAME = 0xa51,
|
||||
ID_ZC_ACK_READ_RODEX = 0xb63,
|
||||
ID_ZC_CLANINFO = 0x98a,
|
||||
ID_ZC_UI_OPEN = 0xae2,
|
||||
ID_ZC_UI_OPEN2 = 0xb9a,
|
||||
ID_ZC_ADD_ITEM_TO_STORE = 0xb44,
|
||||
ID_ZC_ACK_TOUSESKILL = 0x110,
|
||||
ID_ZC_ADD_ITEM_TO_CART = 0xb45,
|
||||
ID_ZC_ADD_EXCHANGE_ITEM = 0xb42,
|
||||
ID_ZC_ITEM_PICKUP_PARTY = 0xb67,
|
||||
ID_ZC_PROPERTY_HOMUN = 0xba4,
|
||||
ID_CZ_REQ_ITEMREPAIR2 = 0xb66,
|
||||
ID_CZ_REQ_ITEMREPAIR1 = 0x1fd,
|
||||
ID_ZC_PC_PURCHASE_MYITEMLIST = 0xb40,
|
||||
ID_ZC_PC_PURCHASE_ITEMLIST = 0xb77,
|
||||
ID_ZC_PC_PURCHASE_ITEMLIST_FROMMC = 0xb3d,
|
||||
ID_ZC_MAKINGARROW_LIST = 0x1ad,
|
||||
ID_ZC_SKILL_SELECT_REQUEST = 0x442,
|
||||
ID_ZC_REPAIRITEMLIST = 0xb65,
|
||||
ID_ZC_MAKINGITEM_LIST = 0x25a,
|
||||
ID_ZC_SEARCH_STORE_INFO_FAILED = 0x837,
|
||||
ID_ZC_OPEN_SEARCH_STORE_INFO = 0x83a,
|
||||
ID_ZC_SSILIST_ITEM_CLICK_ACK = 0x83d,
|
||||
ID_ZC_SEARCH_STORE_INFO_ACK = 0xb64,
|
||||
ID_ZC_ACK_REQNAMEALL = 0xa30,
|
||||
ID_ZC_ACK_REQNAMEALL_NPC = 0xadf,
|
||||
ID_ZC_MOVE_ITEM_FAILED = 0xaa7,
|
||||
ID_ZC_VIEW_CAMERAINFO = 0xa78,
|
||||
ID_CZ_VIEW_CAMERAINFO = 0xa77,
|
||||
ID_ZC_AUTOSPELLLIST = 0xafb,
|
||||
ID_ZC_CHANGE_ITEM_OPTION = 0xb43,
|
||||
ID_ZC_UPDATE_CARDSLOT = 0xa3f,
|
||||
ID_ZC_DEBUGMSG = 0xadb,
|
||||
ID_CZ_USE_SKILL_START = 0xb10,
|
||||
ID_CZ_USE_SKILL_END = 0xb11,
|
||||
ID_ZC_EXTEND_BODYITEM_SIZE = 0xb18,
|
||||
ID_ZC_ACK_OPEN_MSGBOX_EXTEND_BODYITEM_SIZE = 0xb15,
|
||||
ID_ZC_ACK_EXTEND_BODYITEM_SIZE = 0xb17,
|
||||
ID_CZ_REQ_OPEN_MSGBOX_EXTEND_BODYITEM_SIZE = 0xb14,
|
||||
ID_CZ_REQ_EXTEND_BODYITEM_SIZE = 0xb16,
|
||||
ID_CZ_CLOSE_MSGBOX_EXTEND_BODYITEM_SIZE = 0xb19,
|
||||
ID_CZ_REQ_REMAINTIME = 0x1c0,
|
||||
ID_CZ_PARTY_CONFIG = 0x2c8,
|
||||
ID_ZC_NPC_BARTER_MARKET_ITEMINFO = 0xb78,
|
||||
ID_CZ_NPC_BARTER_MARKET_CLOSE = 0xb12,
|
||||
ID_CZ_NPC_BARTER_MARKET_PURCHASE = 0xb0f,
|
||||
ID_ZC_USESKILL_ACK = 0xb1a,
|
||||
ID_CZ_CLIENT_VERSION = 0x44a,
|
||||
ID_CZ_PING_LIVE = 0xb1c,
|
||||
ID_ZC_PING_LIVE = 0xb1d,
|
||||
ID_CZ_CMD_RESETCOOLTIME = 0xa88,
|
||||
ID_CZ_CLOSE_UI_STYLINGSHOP = 0xa48,
|
||||
ID_ZC_NOTIFY_ACTORINIT = 0xb1b,
|
||||
ID_ZC_PARTY_CONFIG = 0x2c9,
|
||||
ID_ZC_ROLE_CHANGE = 0xe1,
|
||||
ID_ZC_BAN_LIST = 0xb7c,
|
||||
ID_ZC_ACK_CLOSE_ROULETTE = 0xa1e,
|
||||
ID_ZC_ACK_MERGE_ITEM = 0x96f,
|
||||
ID_ZC_MERGE_ITEM_OPEN = 0x96d,
|
||||
ID_ZC_SE_PC_BUY_CASHITEM_RESULT = 0x849,
|
||||
ID_ZC_OPEN_REFINING_UI = 0xaa0,
|
||||
ID_CZ_REFINING_SELECT_ITEM = 0xaa1,
|
||||
ID_ZC_REFINING_MATERIAL_LIST = 0xaa2,
|
||||
ID_CZ_REQ_REFINING = 0xaa3,
|
||||
ID_CZ_CLOSE_REFINING_UI = 0xaa4,
|
||||
ID_ZC_BROADCAST_ITEMREFINING_RESULT = 0xada,
|
||||
ID_ZC_STATUS_CHANGE_ACK = 0xbc,
|
||||
ID_ZC_EQUIPMENT_EFFECT = 0xa3b,
|
||||
ID_ZC_ADD_SKILL = 0x111,
|
||||
ID_ZC_SKILLINFO_LIST = 0x10f,
|
||||
ID_ZC_SKILLINFO_UPDATE2 = 0x7e1,
|
||||
ID_ZC_NPC_MARKET_PURCHASE_RESULT = 0xb4e,
|
||||
ID_ZC_TALKBOX_CHATCONTENTS = 0x191,
|
||||
ID_ZC_GUILD_AGIT_INFO = 0xb27,
|
||||
ID_CZ_REQ_MOVE_GUILD_AGIT = 0xb28,
|
||||
ID_ZC_REQ_ACK_MOVE_GUILD_AGIT = 0xb2e,
|
||||
ID_ZC_REQ_ACK_AGIT_INVESTMENT = 0xb2d,
|
||||
ID_CZ_REQ_AGIT_INVESTMENT = 0xb2c,
|
||||
ID_ZC_RANDOM_COMBINE_ITEM_UI_OPEN = 0xa4e,
|
||||
ID_CZ_RANDOM_COMBINE_ITEM_UI_CLOSE = 0xa70,
|
||||
ID_CZ_REQ_RANDOM_COMBINE_ITEM = 0xa4f,
|
||||
ID_ZC_ACK_RANDOM_COMBINE_ITEM = 0xa50,
|
||||
ID_CZ_UNINSTALLATION = 0xb35,
|
||||
ID_ZC_NOTIFY_EFFECT3 = 0xb69,
|
||||
ID_CZ_SE_CASHSHOP_OPEN1 = 0x844,
|
||||
ID_CZ_SE_CASHSHOP_OPEN2 = 0xb6d,
|
||||
ID_CZ_GET_ACCOUNT_LIMTIED_SALE_LIST = 0xb4c,
|
||||
ID_ZC_SE_CASHSHOP_OPEN = 0xb6e,
|
||||
ID_CZ_NPC_EXPANDED_BARTER_MARKET_CLOSE = 0xb58,
|
||||
ID_CZ_NPC_EXPANDED_BARTER_MARKET_PURCHASE = 0xb57,
|
||||
ID_ZC_STATE_CHANGE = 0x229,
|
||||
ID_ZC_AUTORUN_SKILL = 0x147,
|
||||
ID_ZC_RANDOM_UPGRADE_ITEM_UI_OPEN = 0xab4,
|
||||
ID_ZC_ACK_RANDOM_UPGRADE_ITEM = 0xab7,
|
||||
ID_CZ_RANDOM_UPGRADE_ITEM_UI_CLOSE = 0xab5,
|
||||
ID_CZ_REQ_RANDOM_UPGRADE_ITEM = 0xab6,
|
||||
ID_ZC_PERSONAL_INFOMATION = 0x97b,
|
||||
ID_ZC_NOTIFY_SKILL = 0x1de,
|
||||
ID_ZC_USE_SKILL = 0x9cb,
|
||||
ID_ZC_NOTIFY_GROUNDSKILL = 0x117,
|
||||
ID_ZC_SKILL_POSTDELAY = 0x43d,
|
||||
ID_ZC_NOTIFY_SKILL_POSITION = 0x115,
|
||||
ID_ZC_C_MARKERINFO = 0x9c1,
|
||||
ID_ZC_MEMBERMGR_INFO = 0xb7d,
|
||||
ID_ZC_GUILD_INFO = 0xb7b,
|
||||
ID_ZC_POSITION_ID_NAME_INFO = 0x166,
|
||||
ID_ZC_POSITION_INFO = 0x160,
|
||||
ID_ZC_GUILD_SKILLINFO = 0x162,
|
||||
ID_ZC_MYGUILD_BASIC_INFO = 0x14c,
|
||||
ID_CZ_REQ_UPLOAD_MACRO_DETECTOR = 0xa52,
|
||||
ID_ZC_ACK_UPLOAD_MACRO_DETECTOR = 0xa53,
|
||||
ID_CZ_UPLOAD_MACRO_DETECTOR_CAPTCHA = 0xa54,
|
||||
ID_ZC_COMPLETE_UPLOAD_MACRO_DETECTOR_CAPTCHA = 0xa55,
|
||||
ID_CZ_REQ_APPLY_MACRO_DETECTOR = 0xa56,
|
||||
ID_ZC_ACK_APPLY_MACRO_DETECTOR = 0xa57,
|
||||
ID_ZC_APPLY_MACRO_DETECTOR = 0xa58,
|
||||
ID_ZC_APPLY_MACRO_DETECTOR_CAPTCHA = 0xa59,
|
||||
ID_CZ_COMPLETE_APPLY_MACRO_DETECTOR_CAPTCHA = 0xa5a,
|
||||
ID_ZC_REQ_ANSWER_MACRO_DETECTOR = 0xa5b,
|
||||
ID_CZ_ACK_ANSWER_MACRO_DETECTOR = 0xa5c,
|
||||
ID_ZC_CLOSE_MACRO_DETECTOR = 0xa5d,
|
||||
ID_CZ_REQ_PREVIEW_MACRO_DETECTOR = 0xa69,
|
||||
ID_ZC_ACK_PREVIEW_MACRO_DETECTOR = 0xa6a,
|
||||
ID_ZC_PREVIEW_MACRO_DETECTOR_CAPTCHA = 0xa6b,
|
||||
ID_CZ_REQ_PLAYER_AID_IN_RANGE = 0xa6c,
|
||||
ID_ZC_ACK_PLAYER_AID_IN_RANGE = 0xa6d,
|
||||
ID_ZC_ACK_MAKE_GROUP = 0xfa,
|
||||
ID_ZC_PARTY_JOIN_REQ = 0x2c6,
|
||||
ID_ZC_PARTY_JOIN_REQ_ACK = 0x2c5,
|
||||
ID_ZC_NOTIFY_CHAT_PARTY = 0x109,
|
||||
ID_ZC_NOTIFY_POSITION_TO_GROUPM = 0x107,
|
||||
ID_ZC_NOTIFY_HP_TO_GROUPM = 0x80e,
|
||||
ID_ZC_NOTIFY_MEMBERINFO_TO_GROUPM = 0xabd,
|
||||
ID_ZC_DELETE_MEMBER_FROM_GROUP = 0x105,
|
||||
ID_CZ_REQ_TAKEOFF_EQUIP_ALL = 0xbf5,
|
||||
ID_ZC_ACK_TAKEOFF_EQUIP_ALL = 0xbae,
|
||||
ID_ZC_BATTLEFIELD_NOTIFY_HP = 0xa0e,
|
||||
ID_CZ_CHOOSE_MENU_ZERO = 0xba8,
|
||||
ID_ZC_DIALOG_TEXT_ALIGN = 0xba1,
|
||||
ID_CZ_GRADE_ENCHANT_SELECT_EQUIPMENT = 0xb59,
|
||||
ID_ZC_GRADE_ENCHANT_MATERIAL_LIST = 0xb5a,
|
||||
ID_CZ_GRADE_ENCHANT_REQUEST = 0xb5b,
|
||||
ID_CZ_GRADE_ENCHANT_CLOSE_UI = 0xb5c,
|
||||
ID_ZC_GRADE_ENCHANT_ACK = 0xb5d,
|
||||
ID_ZC_GRADE_ENCHANT_BROADCAST_RESULT = 0xb5e,
|
||||
ID_ZC_SHOW_IMAGE = 0x1b3,
|
||||
ID_ZC_WHISPER = 0x97,
|
||||
ID_ZC_WHISPER2 = 0x9de,
|
||||
ID_ZC_UPDATE_GDID = 0x2f7,
|
||||
ID_CZ_APPROXIMATE_ACTOR = 0xbb0,
|
||||
ID_CZ_CONTACTNPC = 0x90,
|
||||
ID_ZC_ATTACK_FAILURE_FOR_DISTANCE = 0x139,
|
||||
ID_ZC_START_CAPTURE = 0x19e,
|
||||
ID_ZC_TRYCAPTURE_MONSTER = 0x1a0,
|
||||
ID_ZC_PROPERTY_PET = 0x1a2,
|
||||
ID_ZC_CHANGESTATE_PET = 0x1a4,
|
||||
ID_ZC_SPIRITS = 0x1d0,
|
||||
ID_ZC_SPIRITS2 = 0x1e1,
|
||||
ID_ZC_SOULENERGY = 0xb73,
|
||||
ID_ZC_SAY_DIALOG = 0xb4,
|
||||
ID_ZC_SAY_DIALOG2 = 0x972,
|
||||
ID_ZC_WAIT_DIALOG = 0xb5,
|
||||
ID_ZC_WAIT_DIALOG2 = 0x973,
|
||||
ID_ZC_DIALOG_WINDOW_SIZE = 0xba2,
|
||||
ID_ZC_DIALOG_WINDOW_POS = 0xba3,
|
||||
ID_ZC_DIALOG_WINDOW_POS2 = 0xbb5,
|
||||
ID_ZC_PLAY_NPC_BGM = 0xb8c,
|
||||
ID_CZ_MOVE_ITEM_FROM_BODY_TO_CART = 0x126,
|
||||
ID_ZC_SOUND = 0x1d3,
|
||||
ID_ZC_BUYING_STORE_ENTRY = 0x814,
|
||||
ID_ZC_STORE_ENTRY = 0x131,
|
||||
ID_CZ_PC_PURCHASE_ITEMLIST_FROMMC = 0x134,
|
||||
ID_CZ_PC_PURCHASE_ITEMLIST_FROMMC2 = 0x801,
|
||||
ID_ZC_DISAPPEAR_BUYING_STORE_ENTRY = 0x816,
|
||||
ID_ZC_OPEN_REFORM_UI = 0xb8f,
|
||||
ID_CZ_CLOSE_REFORM_UI = 0xb90,
|
||||
ID_CZ_ITEM_REFORM = 0xb91,
|
||||
ID_ZC_ITEM_REFORM_ACK = 0xb92,
|
||||
ID_CZ_USE_PACKAGEITEM = 0xbaf,
|
||||
ID_CZ_REQUEST_RANDOM_ENCHANT = 0xb9b,
|
||||
ID_CZ_REQUEST_PERFECT_ENCHANT = 0xb9c,
|
||||
ID_CZ_REQUEST_UPGRADE_ENCHANT = 0xb9d,
|
||||
ID_CZ_REQUEST_RESET_ENCHANT = 0xb9e,
|
||||
ID_ZC_RESPONSE_ENCHANT = 0xb9f,
|
||||
ID_CZ_CLOSE_UI_ENCHANT = 0xba0,
|
||||
ID_ZC_SPECIALPOPUP = 0xbbe,
|
||||
ID_ZC_GOLDPCCAFE_POINT = 0xa15,
|
||||
ID_CZ_DYNAMICNPC_CREATE_REQUEST = 0xa16,
|
||||
ID_ZC_DYNAMICNPC_CREATE_RESULT = 0xa17,
|
||||
ID_CZ_REQ_GUILD_EMBLEM_IMG1 = 0x151,
|
||||
ID_CZ_REQ_GUILD_EMBLEM_IMG3 = 0xb46,
|
||||
ID_CZ_REQ_GUILD_EMBLEM_IMG2 = 0xb1e,
|
||||
ID_ZC_CHANGE_GUILD = 0xb47,
|
||||
ID_ZC_GUILD_EMBLEM_IMG = 0xb36,
|
||||
ID_CZ_ADVENTURER_AGENCY_JOIN_REQ = 0xae6,
|
||||
ID_ZC_ADVENTURER_AGENCY_JOIN_RESULT = 0xafa,
|
||||
ID_ZC_ADVENTURER_AGENCY_JOIN_REQ = 0xae7,
|
||||
ID_CZ_ADVENTURER_AGENCY_JOIN_RESULT = 0xaf8,
|
||||
ID_ZC_USER_COUNT = 0xc2,
|
||||
ID_ZC_PC_PURCHASE_RESULT = 0xca,
|
||||
ID_CZ_REQ_MAKINGARROW = 0x1ae,
|
||||
ID_CZ_SE_PC_BUY_CASHITEM_LIST = 0x848,
|
||||
ID_CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO = 0x9ac,
|
||||
ID_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO = 0x9ad,
|
||||
ID_CZ_REQ_APPLY_BARGAIN_SALE_ITEM = 0x9ae,
|
||||
ID_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM = 0x9b0,
|
||||
ID_ZC_NOTIFY_BARGAIN_SALE_SELLING = 0x9b2,
|
||||
ID_ZC_NOTIFY_BARGAIN_SALE_CLOSE = 0x9b3,
|
||||
ID_ZC_ACK_COUNT_BARGAIN_SALE_ITEM = 0x9c4,
|
||||
ID_ZC_ACK_GUILDSTORAGE_LOG = 0x9da,
|
||||
ID_CZ_ADVANCED_STATUS_CHANGE = 0xb24,
|
||||
ID_CZ_REQ_ADD_NEW_EMBLEM = 0xb46,
|
||||
ID_ZC_BROADCAST = 0x9a,
|
||||
ID_ZC_BROADCAST2 = 0x1c3,
|
||||
ID_ZC_ENTRY_QUEUE_INIT = 0x90e,
|
||||
ID_CZ_RODEX_RETURN = 0xb98,
|
||||
ID_CZ_REQ_STYLE_CLOSE = 0xa48,
|
||||
ID_ZC_SUMMON_HP_INIT = 0xb6b,
|
||||
ID_ZC_SUMMON_HP_UPDATE = 0xb6c,
|
||||
ID_ZC_REPUTE_INFO = 0xb8d,
|
||||
ID_ZC_UI_OPEN_V3 = 0xb9a,
|
||||
ID_ZC_TARGET_SPIRITS = 0xb68,
|
||||
ID_ZC_FRIENDS_LIST = 0x201,
|
||||
ID_CZ_PC_SELL_ITEMLIST = 0xc9,
|
||||
ID_CZ_REQ_CHANGE_MEMBERPOS = 0x155,
|
||||
ID_ZC_CLEAR_DIALOG = 0x8d6,
|
||||
ID_ZC_NOTIFY_BIND_ON_EQUIP = 0x2d3,
|
||||
ID_ZC_BANKING_CHECK = 0x9a6,
|
||||
ID_ZC_ACK_BANKING_WITHDRAW = 0x9aa,
|
||||
ID_ZC_ACK_BANKING_DEPOSIT = 0x9a8,
|
||||
ID_ZC_ACK_CLOSE_BANKING = 0x9b9,
|
||||
ID_ZC_ACK_OPEN_BANKING = 0x9b7,
|
||||
ID_ZC_REQ_EXCHANGE_ITEM = 0x1f4,
|
||||
ID_ZC_ACK_EXCHANGE_ITEM = 0x1f5,
|
||||
ID_ZC_ACK_ADD_EXCHANGE_ITEM = 0xea,
|
||||
ID_ZC_COUPLENAME = 0x1e6,
|
||||
ID_CZ_PARTY_REQ_MASTER_TO_JOIN = 0xae6,
|
||||
ID_ZC_PARTY_REQ_MASTER_TO_JOIN = 0xae7,
|
||||
ID_CZ_PARTY_REQ_ACK_MASTER_TO_JOIN = 0xaf8,
|
||||
ID_ZC_PARTY_JOIN_REQ_ACK_FROM_MASTER = 0xafa,
|
||||
ID_CZ_REQ_SE_CASH_TAB_CODE = 0x846,
|
||||
ID_ZC_ACK_SE_CASH_ITEM_LIST2 = 0x8c0,
|
||||
ID_CZ_REQ_MERGE_ITEM = 0x96e,
|
||||
ID_CZ_RESET_SKILL = 0xbb1,
|
||||
ID_ZC_SKILLINFO_UPDATE = 0x10e,
|
||||
ID_ZC_BOSS_INFO = 0x293,
|
||||
ID_CZ_INVENTORY_TAB = 0x907,
|
||||
ID_ZC_INVENTORY_TAB = 0x908,
|
||||
ID_ZC_ACCEPT_ENTER = 0x2eb,
|
||||
ID_ZC_REFUSE_ENTER = 0x74,
|
||||
ID_SC_NOTIFY_BAN = 0x81,
|
||||
ID_ZC_RESTART_ACK = 0xb3,
|
||||
ID_ZC_NOTIFY_VANISH = 0x80,
|
||||
ID_ZC_ITEM_DISAPPEAR = 0xa1,
|
||||
ID_ZC_MILLENNIUMSHIELD = 0x440,
|
||||
ID_ZC_SPIRITS_ATTRIBUTE = 0x8cf,
|
||||
ID_ZC_CHANGESTATE_MER = 0x230,
|
||||
ID_ZC_HOSKILLINFO_LIST = 0x235,
|
||||
ID_ZC_HOSKILLINFO_UPDATE = 0x239,
|
||||
ID_ZC_NOTIFY_PLAYERMOVE = 0x87,
|
||||
ID_ZC_CHANGE_DIRECTION = 0x9c,
|
||||
ID_ZC_NPCACK_MAPMOVE = 0x91,
|
||||
ID_ZC_NPCACK_SERVERMOVE = 0xac7,
|
||||
ID_ZC_STOPMOVE = 0x88,
|
||||
ID_ZC_SELECT_DEALTYPE = 0xc4,
|
||||
ID_ZC_PC_SELL_ITEMLIST = 0xc7,
|
||||
ID_ZC_CLOSE_DIALOG = 0xb6,
|
||||
ID_ZC_MENU_LIST = 0xb7,
|
||||
ID_ZC_OPEN_EDITDLG = 0x142,
|
||||
ID_ZC_OPEN_EDITDLGSTR = 0x1d4,
|
||||
ID_ZC_ACK_REQ_ALLY_GUILD = 0x173,
|
||||
ID_ZC_DELETE_RELATED_GUILD = 0x184,
|
||||
ID_ZC_REQ_ALLY_GUILD = 0x171,
|
||||
ID_ZC_ACK_REQ_HOSTILE_GUILD = 0x181,
|
||||
ID_ZC_COMPASS = 0x144,
|
||||
ID_ZC_ITEM_THROW_ACK = 0xaf,
|
||||
ID_ZC_DELETE_ITEM_FROM_BODY = 0x7fa,
|
||||
ID_ZC_CARTOFF = 0x12b,
|
||||
ID_ZC_ACK_GUILD_MENUINTERFACE = 0x14e,
|
||||
ID_ZC_ACK_CHANGE_GUILD_POSITIONINFO = 0x174,
|
||||
ID_ZC_NOTIFY_POSITION_TO_GUILDM = 0x1eb,
|
||||
ID_ZC_GUILD_CHAT = 0x17f,
|
||||
ID_ZC_UPDATE_CHARSTAT = 0x1f2,
|
||||
ID_ZC_ACK_REQ_CHANGE_MEMBERS = 0x156,
|
||||
ID_ZC_STATUS = 0xbd,
|
||||
ID_ZC_NOTIFY_MAPINFO = 0x189,
|
||||
ID_ZC_ACK_REMEMBER_WARPPOINT = 0x11e,
|
||||
ID_ZC_DISPEL = 0x1b9,
|
||||
ID_ZC_RESURRECTION = 0x148,
|
||||
ID_ZC_NOTIFY_MAPPROPERTY2 = 0x1d6,
|
||||
ID_ZC_ACK_ITEMREFINING = 0x188,
|
||||
ID_ZC_PAR_CHANGE_USER = 0x1ab,
|
||||
ID_ZC_CHANGE_CHATROOM = 0xdf,
|
||||
ID_ZC_EQUIP_ARROW = 0x13c,
|
||||
ID_ZC_REQ_TAKEOFF_EQUIP_ACK = 0x99a,
|
||||
ID_ZC_MAPPROPERTY_R2 = 0x99b,
|
||||
ID_ZC_CLOSE_STORE = 0xf8,
|
||||
ID_ZC_DELETE_ITEM_FROM_STORE = 0xf6,
|
||||
ID_ZC_NOTIFY_STOREITEM_COUNTINFO = 0xf2,
|
||||
ID_ZC_EXCHANGEITEM_UNDO = 0xf1,
|
||||
ID_ZC_EXEC_EXCHANGE_ITEM = 0xf0,
|
||||
ID_ZC_CANCEL_EXCHANGE_ITEM = 0xee,
|
||||
ID_ZC_ACK_CREATE_CHATROOM = 0xd6,
|
||||
ID_ZC_CONCLUDE_EXCHANGE_ITEM = 0xec,
|
||||
ID_ZC_REFUSE_ENTER_ROOM = 0xda,
|
||||
ID_ZC_DESTROY_ROOM = 0xd8,
|
||||
ID_ZC_ENTER_ROOM = 0xdb,
|
||||
ID_ZC_NPC_SHOWEFST_UPDATE = 0x28a,
|
||||
ID_ZC_ACTION_FAILURE = 0x13b,
|
||||
ID_ZC_NOTIFY_EFFECT = 0x19b,
|
||||
ID_ZC_ACK_ITEMCOMPOSITION = 0x17d,
|
||||
ID_ZC_ACK_ITEMIDENTIFY = 0x179,
|
||||
ID_ZC_ACK_ITEMREPAIR = 0x1fe,
|
||||
ID_ZC_EQUIPITEM_DAMAGED = 0x2bb,
|
||||
ID_ZC_DELETE_ITEM_FROM_CART = 0x125,
|
||||
ID_ZC_OPENSTORE = 0x12d,
|
||||
ID_ZC_PC_PURCHASE_RESULT_FROMMC = 0x135,
|
||||
ID_ZC_ACK_OPENSTORE2 = 0xa28,
|
||||
ID_ZC_SKILL_DISAPPEAR = 0x120,
|
||||
ID_ZC_SKILLINFO_DELETE = 0x441,
|
||||
ID_ZC_SKILL_UPDATE = 0x1ac,
|
||||
ID_ZC_HIGHJUMP = 0x1ff,
|
||||
ID_ZC_RECOVERY = 0xa27,
|
||||
ID_ZC_ACK_WHISPER = 0x9df,
|
||||
ID_ZC_ACK_ADDITEM_TO_CART = 0x12c,
|
||||
ID_ZC_DELETEITEM_FROM_MCSTORE = 0x9e5,
|
||||
ID_CZ_REQ_BAN_GUILD = 0x15b,
|
||||
ID_CZ_REQ_LEAVE_GUILD = 0x159,
|
||||
ID_CZ_REQ_DISORGANIZE_GUILD = 0x15d,
|
||||
ID_ZC_ACK_DISORGANIZE_GUILD_RESULT = 0x15e,
|
||||
ID_ZC_RESULT_MAKE_GUILD = 0x167,
|
||||
ID_CZ_REQ_JOIN_GUILD = 0x168,
|
||||
ID_ZC_ACK_REQ_JOIN_GUILD = 0x169,
|
||||
ID_ZC_REQ_JOIN_GUILD = 0x16a,
|
||||
ID_CZ_JOIN_GUILD = 0x16b,
|
||||
ID_ZC_GUILD_NOTICE = 0x16f,
|
||||
ID_CZ_REQ_JOIN_GUILD2 = 0x916,
|
||||
ID_CZ_REQ_JOIN_GROUP = 0xfc,
|
||||
ID_CZ_JOIN_GROUP = 0xff,
|
||||
ID_CZ_REQ_LEAVE_GROUP = 0x100,
|
||||
ID_CZ_REQ_EXPEL_GROUP_MEMBER = 0x103,
|
||||
ID_CZ_PARTY_JOIN_REQ = 0x2c4,
|
||||
ID_CZ_PARTY_JOIN_REQ_ACK = 0x2c7,
|
||||
ID_ZC_HO_PAR_CHANGE = 0xba5,
|
||||
ID_ZC_EL_PAR_CHANGE = 0x81e,
|
||||
ID_CZ_REQ_EMOTION = 0xbf,
|
||||
ID_ZC_NOTIFY_ACT = 0x8c8,
|
||||
ID_CZ_REQUEST_MOVENPC = 0x232,
|
||||
ID_ZC_NPCSPRITE_CHANGE = 0x1b0,
|
||||
ID_ZC_MEMBER_NEWENTRY = 0xdc,
|
||||
ID_ZC_MEMBER_EXIT = 0xdd,
|
||||
ID_CZ_MOVETO_MAP = 0x140,
|
||||
ID_CZ_BROADCAST = 0x99,
|
||||
ID_CZ_REQ_WEAR_EQUIP = 0xa9,
|
||||
ID_CZ_ACK_SELECT_DEALTYPE = 0xc5,
|
||||
ID_CZ_CREATE_CHATROOM = 0xd5,
|
||||
ID_CZ_BLACKSMITH_RANK = 0x217,
|
||||
ID_CZ_ALCHEMIST_RANK = 0x218,
|
||||
ID_ZC_BLACKSMITH_RANK = 0x219,
|
||||
ID_ZC_ALCHEMIST_RANK = 0x21a,
|
||||
ID_ZC_BLACKSMITH_POINT = 0x21b,
|
||||
ID_ZC_ALCHEMIST_POINT = 0x21c,
|
||||
ID_ZC_TAEKWON_POINT = 0x224,
|
||||
ID_CZ_TAEKWON_RANK = 0x225,
|
||||
ID_ZC_TAEKWON_RANK = 0x226,
|
||||
ID_ZC_KILLER_POINT = 0x236,
|
||||
ID_CZ_KILLER_RANK = 0x237,
|
||||
ID_ZC_KILLER_RANK = 0x238,
|
||||
ID_CZ_REQ_RANKING = 0x97c,
|
||||
ID_ZC_ACK_RANKING = 0x97d,
|
||||
ID_ZC_UPDATE_RANKING_POINT = 0x97e,
|
||||
ID_ZC_ACK_RANKING2 = 0xaf6,
|
||||
ID_CZ_LESSEFFECT = 0x21d,
|
||||
ID_CZ_ACTIVE_QUEST = 0x2b6,
|
||||
ID_CZ_JOIN_BABY = 0x1f7,
|
||||
ID_CZ_AUCTION_ITEM_SEARCH = 0x251,
|
||||
ID_CZ_AUCTION_BUY = 0x24f,
|
||||
ID_CZ_AUCTION_ADD = 0x24d,
|
||||
ID_ZC_DRESSROOM_OPEN = 0xa02,
|
||||
ID_ZC_ROOM_NEWENTRY = 0xd7,
|
||||
ID_ZC_MONSTER_INFO = 0x18c,
|
||||
ID_ZC_ACK_REQNAME_BYGID = 0xaf7,
|
||||
ID_ZC_PET_ACT = 0x1aa,
|
||||
ID_ZC_COMBODELAY = 0x1d2,
|
||||
ID_ZC_BLADESTOP = 0x1d1,
|
||||
ID_ZC_MVP = 0x10c,
|
||||
ID_ZC_MVP_GETTING_SPECIAL_EXP = 0x10b,
|
||||
ID_ZC_THROW_MVPITEM = 0x10d,
|
||||
ID_ZC_UPDATE_MAPINFO = 0x192,
|
||||
ID_CZ_REQ_ENTER_ROOM = 0xd9,
|
||||
ID_CZ_CHANGE_CHATROOM = 0xde,
|
||||
ID_CZ_ADD_EXCHANGE_ITEM = 0xe8,
|
||||
ID_CZ_MOVE_ITEM_FROM_CART_TO_BODY = 0x127,
|
||||
ID_CZ_SELECT_WARPPOINT = 0x11b,
|
||||
ID_CZ_INPUT_EDITDLG = 0x143,
|
||||
ID_CZ_INPUT_EDITDLGSTR = 0x1d5,
|
||||
ID_CZ_CLOSE_DIALOG = 0x146,
|
||||
ID_CZ_RESET = 0x197,
|
||||
ID_CZ_MOVE_ITEM_FROM_STORE_TO_CART = 0x128,
|
||||
ID_CZ_REQ_ITEMIDENTIFY = 0x178,
|
||||
ID_CZ_SELECTAUTOSPELL = 0x1ce,
|
||||
ID_CZ_REQ_ITEMCOMPOSITION_LIST = 0x17a,
|
||||
ID_CZ_REQ_ITEMCOMPOSITION = 0x17c,
|
||||
ID_CZ_LOCALBROADCAST = 0x19c,
|
||||
ID_CZ_MOVE_ITEM_FROM_CART_TO_STORE = 0x129,
|
||||
ID_ZC_FRIENDS_STATE = 0x206,
|
||||
ID_CZ_MAKE_GROUP = 0xf9,
|
||||
ID_CZ_MAKE_GROUP2 = 0x1e8,
|
||||
ID_CZ_GM_CHECKER = 0xc0b,
|
||||
ID_ZC_GM_CHECKER = 0xc0c,
|
||||
ID_ZC_CONFIG_NOTIFY = 0x2da,
|
||||
ID_ZC_CONGRATULATION = 0x1ea,
|
||||
ID_ZC_DIVORCE = 0x205,
|
||||
ID_ZC_EMOTION = 0xc0,
|
||||
ID_ZC_MSG = 0x291,
|
||||
ID_ZC_MSG_SKILL = 0x7e6,
|
||||
ID_ZC_MSG_VALUE = 0x7e2,
|
||||
ID_ZC_NOTIFY_MANNER_POINT_GIVEN = 0x14b,
|
||||
ID_ZC_NOTIFY_TIME = 0x7f,
|
||||
ID_ZC_SETTING_WHISPER_PC = 0xd1,
|
||||
ID_ZC_SETTING_WHISPER_STATE = 0xd2,
|
||||
ID_ZC_SKILLMSG = 0x215,
|
||||
ID_CZ_REQ_EMOTION_EXPANSION = 0xbe9,
|
||||
ID_ZC_DISAPPEAR_ENTRY = 0x132,
|
||||
ID_ZC_EFST_SET_ENTER = 0x984,
|
||||
ID_CZ_SETTING_WHISPER_STATE = 0xd0,
|
||||
ID_ZC_WHISPER_LIST = 0xd4,
|
||||
ID_CZ_ALLY_CHAT = 0xbdd,
|
||||
ID_CZ_REQ_REPORT_USER = 0xbe2,
|
||||
ID_CZ_QUEST_STATUS_REQ = 0xbf3,
|
||||
ID_CZ_MOVE_ITEM_TO_PERSONAL = 0xc22,
|
||||
ID_ZC_NPC_EXPANDED_BARTER_MARKET_ITEMINFO = 0xb79,
|
||||
ID_ZC_NOTIFY_CHAT = 0x8d,
|
||||
ID_ZC_ITEM_ENTRY = 0x9d,
|
||||
ID_ZC_MVP_GETTING_ITEM = 0x10a,
|
||||
ID_ZC_MAKABLEITEMLIST = 0x18d,
|
||||
ID_CZ_REQMAKINGITEM = 0x18e,
|
||||
ID_ZC_ACK_REQMAKINGITEM = 0x18f,
|
||||
ID_CZ_REQ_ITEMREPAIR = 0x1fd,
|
||||
ID_ZC_NOTIFY_WEAPONITEMLIST = 0x221,
|
||||
ID_ZC_ACK_WEAPONREFINE = 0x223,
|
||||
ID_CZ_REQ_MAKINGITEM = 0x25b,
|
||||
ID_ZC_PC_CASH_POINT_ITEMLIST = 0x287,
|
||||
ID_ZC_CASH_TIME_COUNTER = 0x298,
|
||||
ID_ZC_CASH_ITEM_DELETE = 0x299,
|
||||
ID_CZ_SKILL_SELECT_RESPONSE = 0x443,
|
||||
ID_ZC_MYITEMLIST_BUYING_STORE = 0x813,
|
||||
ID_ZC_ACK_ITEMLIST_BUYING_STORE = 0x818,
|
||||
ID_ZC_FAILED_TRADE_BUYING_STORE_TO_SELLER = 0x824,
|
||||
ID_CZ_SSILIST_ITEM_CLICK = 0x83c,
|
||||
ID_ZC_ACK_SCHEDULER_CASHITEM = 0x8ca,
|
||||
ID_ZC_NOTIFY_CLAN_CONNECTINFO = 0x988,
|
||||
ID_ZC_ACK_CLAN_LEAVE = 0x989,
|
||||
ID_ZC_NOTIFY_CLAN_CHAT = 0x98e,
|
||||
ID_CZ_REQ_BANKING_DEPOSIT = 0x9a7,
|
||||
ID_CZ_REQ_BANKING_WITHDRAW = 0x9a9,
|
||||
ID_CZ_REQ_BANKING_CHECK = 0x9ab,
|
||||
ID_CZ_REQ_OPEN_BANKING = 0x9b6,
|
||||
ID_CZ_REQ_CLOSE_BANKING = 0x9b8,
|
||||
ID_CZ_REQ_APPLY_BARGAIN_SALE_ITEM2 = 0xa3d,
|
||||
ID_CZ_REQ_STYLE_CHANGE = 0xa46,
|
||||
ID_ZC_STYLE_CHANGE_RES = 0xa47,
|
||||
ID_ZC_GROUP_ISALIVE = 0xab2,
|
||||
ID_CZ_REQ_STYLE_CHANGE2 = 0xafc,
|
||||
ID_ZC_GUILD_POSITION = 0xafd,
|
||||
ID_ZC_REMOVE_EFFECT = 0xb0d,
|
||||
ID_ZC_FEED_MER = 0x22f,
|
||||
ID_ZC_FEED_PET = 0x1a3,
|
||||
ID_ZC_WARPLIST = 0xabe,
|
||||
ID_ZC_MSG_COLOR = 0x9cd,
|
||||
ID_CZ_SSILIST_ITEM_CLICK3 = 0x8a2,
|
||||
ID_CZ_SSILIST_ITEM_CLICK4 = 0x838,
|
||||
ID_CZ_SSILIST_ITEM_CLICK5 = 0x365,
|
||||
ID_CZ_PRIVATE_AIRSHIP_REQUEST = 0xa49,
|
||||
ID_CZ_SHORTCUT_KEY_CHANGE3 = 0xb21,
|
||||
ID_CZ_SHORTCUTKEYBAR_ROTATE3 = 0xb22,
|
||||
ID_CZ_SSILIST_ITEM_CLICK2 = 0x83c,
|
||||
ID_CZ_REQ_WHISPER_LIST = 0xd3,
|
||||
ID_CZ_ENTER = 0x72,
|
||||
ID_CZ_NOTIFY_ACTORINIT = 0x7d,
|
||||
ID_CZ_REQUEST_TIME = 0xf7,
|
||||
ID_CZ_REQUEST_QUIT = 0x82,
|
||||
ID_CZ_REQUEST_MOVE = 0x85,
|
||||
ID_CZ_REQUEST_ACT = 0x89,
|
||||
ID_CZ_REQUEST_CHAT2 = 0x8c,
|
||||
ID_CZ_REQNAME = 0x94,
|
||||
ID_CZ_WHISPER = 0x96,
|
||||
ID_CZ_CHANGE_DIRECTION = 0x9b,
|
||||
ID_CZ_ITEM_PICKUP = 0x9f,
|
||||
ID_CZ_ITEM_THROW = 0xa2,
|
||||
ID_CZ_USE_ITEM = 0xa7,
|
||||
ID_CZ_REQ_TAKEOFF_EQUIP = 0xab,
|
||||
ID_CZ_REQ_ITEM_EXPLANATION_BYNAME = 0xad,
|
||||
ID_CZ_RESTART = 0xb2,
|
||||
ID_CZ_CHOOSE_MENU = 0xb8,
|
||||
ID_CZ_REQ_NEXT_SCRIPT = 0xb9,
|
||||
ID_CZ_REQ_STATUS = 0xba,
|
||||
ID_CZ_STATUS_CHANGE = 0xbb,
|
||||
ID_CZ_REQ_USER_COUNT = 0xc1,
|
||||
ID_CZ_PC_PURCHASE_ITEMLIST = 0xc8,
|
||||
ID_CZ_DISCONNECT_CHARACTER = 0xcc,
|
||||
ID_CZ_DISCONNECT_ALL_CHARACTER = 0xce,
|
||||
ID_CZ_SETTING_WHISPER_PC = 0xcf,
|
||||
ID_CZ_REQ_ROLE_CHANGE = 0xe0,
|
||||
ID_CZ_REQ_EXPEL_MEMBER = 0xe2,
|
||||
ID_CZ_EXIT_ROOM = 0xe3,
|
||||
ID_CZ_REQ_EXCHANGE_ITEM = 0xe4,
|
||||
ID_CZ_ACK_EXCHANGE_ITEM = 0xe6,
|
||||
ID_CZ_CONCLUDE_EXCHANGE_ITEM = 0xeb,
|
||||
ID_CZ_CANCEL_EXCHANGE_ITEM = 0xed,
|
||||
ID_CZ_EXEC_EXCHANGE_ITEM = 0xef,
|
||||
ID_CZ_REQUEST_CHAT = 0xf3,
|
||||
ID_CZ_MOVE_ITEM_FROM_STORE_TO_BODY = 0xf5,
|
||||
ID_CZ_CHANGE_GROUPEXPOPTION = 0x102,
|
||||
ID_CZ_REQUEST_CHAT_PARTY = 0x108,
|
||||
ID_CZ_UPGRADE_SKILLLEVEL = 0x112,
|
||||
ID_CZ_USE_SKILL = 0x113,
|
||||
ID_CZ_USE_SKILL_TOGROUND = 0x116,
|
||||
ID_CZ_CANCEL_LOCKON = 0x118,
|
||||
ID_CZ_REMEMBER_WARPPOINT = 0x11d,
|
||||
ID_CZ_REQ_CARTOFF = 0x12a,
|
||||
ID_CZ_REQ_CLOSESTORE = 0x12e,
|
||||
ID_CZ_REQ_OPENSTORE = 0x12f,
|
||||
ID_CZ_REQ_BUY_FROMMC = 0x130,
|
||||
ID_CZ_PKMODE_CHANGE = 0x138,
|
||||
ID_CZ_ITEM_CREATE = 0x13f,
|
||||
ID_CZ_REQ_GIVE_MANNER_POINT = 0x149,
|
||||
ID_CZ_REQ_GUILD_MENUINTERFACE = 0x14d,
|
||||
ID_CZ_REQ_GUILD_MENU = 0x14f,
|
||||
ID_CZ_REQ_GUILD_EMBLEM_IMG = 0x151,
|
||||
ID_CZ_REGISTER_GUILD_EMBLEM_IMG = 0x153,
|
||||
ID_CZ_REQ_OPEN_MEMBER_INFO = 0x157,
|
||||
ID_CZ_REG_CHANGE_GUILD_POSITIONINFO = 0x161,
|
||||
ID_CZ_REQ_MAKE_GUILD = 0x165,
|
||||
ID_CZ_GUILD_NOTICE = 0x16e,
|
||||
ID_CZ_REQ_ALLY_GUILD = 0x170,
|
||||
ID_CZ_ALLY_GUILD = 0x172,
|
||||
ID_CZ_REQ_GUILD_MEMBER_INFO = 0x175,
|
||||
ID_CZ_GUILD_CHAT = 0x17e,
|
||||
ID_CZ_REQ_HOSTILE_GUILD = 0x180,
|
||||
ID_CZ_REQ_DELETE_RELATED_GUILD = 0x183,
|
||||
ID_CZ_REQ_DISCONNECT = 0x18a,
|
||||
ID_CZ_USE_SKILL_TOGROUND_WITHTALKBOX = 0x190,
|
||||
ID_CZ_REQNAME_BYGID = 0x193,
|
||||
ID_CZ_CHANGE_MAPTYPE = 0x198,
|
||||
ID_CZ_CHANGE_EFFECTSTATE = 0x19d,
|
||||
ID_CZ_TRYCAPTURE_MONSTER = 0x19f,
|
||||
ID_CZ_COMMAND_PET = 0x1a1,
|
||||
ID_CZ_RENAME_PET = 0x1a5,
|
||||
ID_CZ_SELECT_PETEGG = 0x1a7,
|
||||
ID_CZ_PETEGG_INFO = 0x1a8,
|
||||
ID_CZ_PET_ACT = 0x1a9,
|
||||
ID_CZ_REQ_CHANGECART = 0x1af,
|
||||
ID_CZ_REQ_OPENSTORE2 = 0x1b2,
|
||||
ID_CZ_GUILD_ZENY = 0x1b7,
|
||||
ID_CZ_REMOVE_AID = 0x1ba,
|
||||
ID_CZ_SHIFT = 0x1bb,
|
||||
ID_CZ_RECALL = 0x1bc,
|
||||
ID_CZ_RECALL_GID = 0x1bd,
|
||||
ID_CZ_REQMAKINGHOMUN = 0x1ca,
|
||||
ID_CZ_MONSTER_TALK = 0x1cb,
|
||||
ID_CZ_REQ_ACCOUNTNAME = 0x1df,
|
||||
ID_CZ_JOIN_COUPLE = 0x1e3,
|
||||
ID_CZ_REQ_JOIN_COUPLE = 0x1e5,
|
||||
ID_CZ_DORIDORI = 0x1e7,
|
||||
ID_CZ_CHOPOKGI = 0x1ed,
|
||||
ID_CZ_REQ_JOIN_BABY = 0x1f9,
|
||||
ID_CZ_ADD_FRIENDS = 0x202,
|
||||
ID_CZ_DELETE_FRIENDS = 0x203,
|
||||
ID_CZ_ACK_REQ_ADD_FRIENDS = 0x208,
|
||||
ID_CZ_REQ_GIVE_MANNER_BYNAME = 0x212,
|
||||
ID_CZ_REQ_STATUS_GM = 0x213,
|
||||
ID_CZ_REQ_PVPPOINT = 0x20f,
|
||||
ID_CZ_REQ_WEAPONREFINE = 0x222,
|
||||
ID_CZ_ACK_GAME_GUARD = 0x228,
|
||||
ID_CZ_COMMAND_MER = 0x22d,
|
||||
ID_CZ_REQUEST_ACTNPC = 0x233,
|
||||
ID_CZ_REQUEST_MOVETOOWNER = 0x234,
|
||||
ID_CZ_RENAME_MER = 0x231,
|
||||
ID_CZ_ACK_STORE_PASSWORD = 0x23b,
|
||||
ID_CZ_MAIL_GET_LIST = 0x23f,
|
||||
ID_CZ_MAIL_OPEN = 0x241,
|
||||
ID_CZ_MAIL_DELETE = 0x243,
|
||||
ID_CZ_MAIL_GET_ITEM = 0x244,
|
||||
ID_CZ_MAIL_RESET_ITEM = 0x246,
|
||||
ID_CZ_MAIL_ADD_ITEM = 0x247,
|
||||
ID_CZ_MAIL_SEND = 0x248,
|
||||
ID_CZ_AUCTION_CREATE = 0x24b,
|
||||
ID_CZ_AUCTION_ADD_ITEM = 0x24c,
|
||||
ID_CZ_AUCTION_ADD_CANCEL = 0x24e,
|
||||
ID_CZ_AGREE_STARPLACE = 0x254,
|
||||
ID_CZ_AUCTION_REQ_MY_INFO = 0x25c,
|
||||
ID_CZ_AUCTION_REQ_MY_SELL_STOP = 0x25d,
|
||||
ID_CZ_REQ_MAIL_RETURN = 0x273,
|
||||
ID_CZ_HUNTINGLIST = 0x279,
|
||||
ID_CZ_GANGSI_RANK = 0x281,
|
||||
ID_CZ_DEATH_QUESTION = 0x286,
|
||||
ID_CZ_PC_BUY_CASH_POINT_ITEM = 0x288,
|
||||
ID_CZ_STANDING_RESURRECTION = 0x292,
|
||||
ID_CZ_MER_COMMAND = 0x29f,
|
||||
ID_CZ_UNUSED_MER_USE_SKILL = 0x2a0,
|
||||
ID_CZ_UNUSED_MER_UPGRADE_SKILLLEVEL = 0x2a1,
|
||||
ID_CZ_GAMEGUARD_LINGO_READY = 0x2a4,
|
||||
ID_CZ_KSY_EVENT = 0x2a5,
|
||||
ID_CZ_ACK_CASH_PASSWORD = 0x2ab,
|
||||
ID_CZ_HACKSH_CPX_MSG = 0x2a7,
|
||||
ID_CZ_HACKSHIELD_CRC_MSG = 0x2a9,
|
||||
ID_CZ_SHORTCUT_KEY_CHANGE = 0x2ba,
|
||||
ID_CZ_SRPACKETR2_START = 0x2c0,
|
||||
ID_CZ_MEMORIALDUNGEON_COMMAND = 0x2cf,
|
||||
ID_CZ_EQUIPWIN_MICROSCOPE = 0x2d6,
|
||||
ID_CZ_CONFIG = 0x2d8,
|
||||
ID_CZ_BATTLEFIELD_CHAT = 0x2db,
|
||||
ID_CZ_USE_ITEM_NEW_JAPEN = 0x2e2,
|
||||
ID_CZ_USE_SKILL_NEW_JAPEN = 0x2e3,
|
||||
ID_CZ_ITEM_PICKUP_NEW_JAPEN = 0x2e4,
|
||||
ID_CZ_REQUEST_MOVE_NEW_JAPEN = 0x2e5,
|
||||
ID_CZ_BOT_CHECK = 0x2e6,
|
||||
ID_CZ_PROGRESS = 0x2f1,
|
||||
ID_CZ_IRMAIL_SEND = 0x2f3,
|
||||
ID_CZ_IRMAIL_LIST = 0x2f6,
|
||||
ID_CZ_OPEN_SIMPLE_CASHSHOP_ITEMLIST = 0x35c,
|
||||
ID_CZ_CLOSE_WINDOW = 0x35e,
|
||||
ID_CZ_REQUEST_MOVE2 = 0x35f,
|
||||
ID_CZ_ENTER2 = 0x436,
|
||||
ID_CZ_REQUEST_ACT2 = 0x437,
|
||||
ID_CZ_USE_SKILL2 = 0x438,
|
||||
ID_CZ_USE_ITEM2 = 0x439,
|
||||
ID_CZ_SIMPLE_BUY_CASH_POINT_ITEM = 0x445,
|
||||
ID_CZ_CLOSE_SIMPLECASH_SHOP = 0x44b,
|
||||
ID_CZ_ES_GET_LIST = 0x7d1,
|
||||
ID_CZ_ES_CHOOSE = 0x7d3,
|
||||
ID_CZ_ES_CANCEL = 0x7d4,
|
||||
ID_CZ_BLOCKING_PLAY_CANCEL = 0x447,
|
||||
ID_CZ_GROUPINFO_CHANGE_V2 = 0x7d7,
|
||||
ID_CZ_CHANGE_GROUP_MASTER = 0x7da,
|
||||
ID_CZ_SEEK_PARTY = 0x7dc,
|
||||
ID_CZ_SEEK_PARTY_MEMBER = 0x7de,
|
||||
ID_CZ_ITEMLISTWIN_RES = 0x7e4,
|
||||
ID_CZ_BATTLE_FIELD_LIST = 0x7ea,
|
||||
ID_CZ_JOIN_BATTLE_FIELD = 0x7ec,
|
||||
ID_CZ_CANCEL_BATTLE_FIELD = 0x7ee,
|
||||
ID_CZ_REQ_BATTLE_STATE_MONITOR = 0x7f0,
|
||||
ID_CZ_GM_FULLSTRIP = 0x7f5,
|
||||
ID_CZ_PARTY_BOOKING_REQ_REGISTER = 0x802,
|
||||
ID_CZ_PARTY_BOOKING_REQ_SEARCH = 0x804,
|
||||
ID_CZ_PARTY_BOOKING_REQ_DELETE = 0x806,
|
||||
ID_CZ_PARTY_BOOKING_REQ_UPDATE = 0x808,
|
||||
ID_CZ_SIMPLE_CASH_BTNSHOW = 0x80c,
|
||||
ID_CZ_REQ_OPEN_BUYING_STORE = 0x811,
|
||||
ID_CZ_REQ_CLOSE_BUYING_STORE = 0x815,
|
||||
ID_CZ_REQ_CLICK_TO_BUYING_STORE = 0x817,
|
||||
ID_CZ_REQ_TRADE_BUYING_STORE = 0x819,
|
||||
ID_CZ_SEARCH_STORE_INFO = 0x835,
|
||||
ID_CZ_SEARCH_STORE_INFO_NEXT_PAGE = 0x838,
|
||||
ID_CZ_CLOSE_SEARCH_STORE_INFO = 0x83b,
|
||||
ID_CZ_RECALL_SSO = 0x842,
|
||||
ID_CZ_REMOVE_AID_SSO = 0x843,
|
||||
ID_CZ_REQUEST_TIME2 = 0x360,
|
||||
ID_CZ_CHANGE_DIRECTION2 = 0x361,
|
||||
ID_CZ_ITEM_PICKUP2 = 0x362,
|
||||
ID_CZ_ITEM_THROW2 = 0x363,
|
||||
ID_CZ_MOVE_ITEM_FROM_BODY_TO_STORE2 = 0x364,
|
||||
ID_CZ_MOVE_ITEM_FROM_STORE_TO_BODY2 = 0x365,
|
||||
ID_CZ_USE_SKILL_TOGROUND2 = 0x366,
|
||||
ID_CZ_USE_SKILL_TOGROUND_WITHTALKBOX2 = 0x367,
|
||||
ID_CZ_REQNAME2 = 0x368,
|
||||
ID_CZ_REQNAME_BYGID2 = 0x369,
|
||||
ID_CZ_TRYCOLLECTION = 0x8b5,
|
||||
ID_CZ_MACRO_START = 0x8c1,
|
||||
ID_CZ_MACRO_STOP = 0x8c2,
|
||||
ID_CZ_REQ_SCHEDULER_CASHITEM = 0x8c9,
|
||||
ID_CZ_SE_CASHSHOP_OPEN = 0x844,
|
||||
ID_CZ_SE_CASHSHOP_CLOSE = 0x84a,
|
||||
ID_CZ_REASSEMBLY_AUTH02 = 0x885,
|
||||
ID_CZ_REASSEMBLY_AUTH16 = 0x893,
|
||||
ID_CZ_REASSEMBLY_AUTH20 = 0x897,
|
||||
ID_CZ_REASSEMBLY_AUTH42 = 0x8ad,
|
||||
ID_CZ_REASSEMBLY_AUTH07 = 0x88a,
|
||||
ID_CZ_REQ_ENTRY_QUEUE_APPLY = 0x8d7,
|
||||
ID_CZ_REQ_ENTRY_QUEUE_RANKING = 0x90a,
|
||||
ID_CZ_REQ_ENTRY_QUEUE_CANCEL = 0x8da,
|
||||
ID_CZ_REPLY_LOBBY_ADMISSION = 0x8e0,
|
||||
ID_CZ_REASSEMBLY_AUTH21 = 0x898,
|
||||
ID_CZ_REASSEMBLY_AUTH10 = 0x88d,
|
||||
ID_CZ_REASSEMBLY_AUTH39 = 0x8aa,
|
||||
ID_CZ_REASSEMBLY_AUTH34 = 0x8a5,
|
||||
ID_CZ_REASSEMBLY_AUTH24 = 0x89b,
|
||||
ID_CZ_REASSEMBLY_AUTH30 = 0x8a1,
|
||||
ID_CZ_REASSEMBLY_AUTH27 = 0x89e,
|
||||
ID_CZ_REASSEMBLY_AUTH40 = 0x8ab,
|
||||
ID_CZ_REASSEMBLY_AUTH08 = 0x88b,
|
||||
ID_CZ_REASSEMBLY_AUTH31 = 0x8a2,
|
||||
ID_CZ_REASSEMBLY_AUTH15 = 0x892,
|
||||
ID_CZ_REASSEMBLY_AUTH22 = 0x899,
|
||||
ID_CZ_REASSEMBLY_AUTH04 = 0x887,
|
||||
ID_CZ_REASSEMBLY_AUTH13 = 0x890,
|
||||
ID_CZ_REASSEMBLY_AUTH77 = 0x963,
|
||||
ID_CZ_REASSEMBLY_AUTH84 = 0x96a,
|
||||
ID_CZ_REASSEMBLY_AUTH06 = 0x889,
|
||||
ID_CZ_REASSEMBLY_AUTH01 = 0x884,
|
||||
ID_CZ_REASSEMBLY_AUTH25 = 0x89c,
|
||||
ID_CZ_REASSEMBLY_AUTH75 = 0x961,
|
||||
ID_CZ_REASSEMBLY_AUTH53 = 0x94b,
|
||||
ID_CZ_REASSEMBLY_AUTH47 = 0x945,
|
||||
ID_CZ_REASSEMBLY_AUTH03 = 0x886,
|
||||
ID_CZ_REASSEMBLY_AUTH14 = 0x891,
|
||||
ID_CZ_REASSEMBLY_AUTH35 = 0x8a6,
|
||||
ID_CZ_PARTY_RECRUIT_REQ_REGISTER = 0x8e5,
|
||||
ID_CZ_PARTY_RECRUIT_REQ_SEARCH = 0x8e7,
|
||||
ID_CZ_PARTY_RECRUIT_REQ_DELETE = 0x8e9,
|
||||
ID_CZ_PARTY_RECRUIT_REQ_UPDATE = 0x8eb,
|
||||
ID_CZ_PARTY_RECRUIT_ADD_FILTERLINGLIST = 0x8ef,
|
||||
ID_CZ_PARTY_RECRUIT_SUB_FILTERLINGLIST = 0x8f0,
|
||||
ID_CZ_PARTY_RECRUIT_REQ_VOLUNTEER = 0x8f1,
|
||||
ID_CZ_PARTY_RECRUIT_SHOW_EQUIPMENT = 0x8f4,
|
||||
ID_CZ_UNKNOWN_BOOKING_SOMMON_MEMBER_08f5 = 0x8f5,
|
||||
ID_CZ_PARTY_RECRUIT_ACK_RECALL = 0x8f7,
|
||||
ID_CZ_PARTY_RECRUIT_REFUSE_VOLUNTEER = 0x8f9,
|
||||
ID_CZ_PARTY_RECRUIT_CANCEL_VOLUNTEER = 0x8fb,
|
||||
ID_CZ_REASSEMBLY_AUTH37 = 0x8a8,
|
||||
ID_CZ_SELECTCART = 0x980,
|
||||
ID_CZ_REASSEMBLY_AUTH28 = 0x89f,
|
||||
ID_CZ_REASSEMBLY_AUTH29 = 0x8a0,
|
||||
ID_CZ_REASSEMBLY_AUTH52 = 0x94a,
|
||||
ID_CZ_REASSEMBLY_AUTH61 = 0x953,
|
||||
ID_CZ_REASSEMBLY_AUTH74 = 0x960,
|
||||
ID_CZ_REQ_WEAR_EQUIP_V5 = 0x998,
|
||||
ID_CZ_REASSEMBLY_AUTH11 = 0x88e,
|
||||
ID_CZ_REASSEMBLY_AUTH41 = 0x8ac,
|
||||
ID_CZ_REASSEMBLY_AUTH67 = 0x959,
|
||||
ID_CZ_REASSEMBLY_AUTH54 = 0x94c,
|
||||
ID_CZ_REASSEMBLY_AUTH56 = 0x94e,
|
||||
ID_CZ_REASSEMBLY_AUTH05 = 0x888,
|
||||
ID_CZ_REASSEMBLY_AUTH49 = 0x947,
|
||||
ID_CZ_REASSEMBLY_AUTH68 = 0x95a,
|
||||
ID_CZ_REASSEMBLY_AUTH46 = 0x944,
|
||||
ID_CZ_REASSEMBLY_AUTH45 = 0x943,
|
||||
ID_CZ_REASSEMBLY_AUTH76 = 0x962,
|
||||
ID_CZ_REASSEMBLY_AUTH70 = 0x95c,
|
||||
ID_CZ_REASSEMBLY_AUTH72 = 0x95e,
|
||||
ID_CZ_REASSEMBLY_AUTH32 = 0x8a3,
|
||||
ID_CZ_REASSEMBLY_AUTH78 = 0x964,
|
||||
ID_CZ_REASSEMBLY_AUTH69 = 0x95b,
|
||||
ID_CZ_REASSEMBLY_AUTH60 = 0x952,
|
||||
ID_CZ_REASSEMBLY_AUTH38 = 0x8a9,
|
||||
ID_CZ_REASSEMBLY_AUTH58 = 0x950,
|
||||
ID_CZ_REASSEMBLY_AUTH79 = 0x965,
|
||||
ID_CZ_REASSEMBLY_AUTH59 = 0x951,
|
||||
ID_CZ_REASSEMBLY_AUTH18 = 0x895,
|
||||
ID_CZ_REASSEMBLY_AUTH36 = 0x8a7,
|
||||
ID_CZ_REASSEMBLY_AUTH65 = 0x957,
|
||||
ID_CZ_REASSEMBLY_AUTH43 = 0x941,
|
||||
ID_CZ_REASSEMBLY_AUTH66 = 0x958,
|
||||
ID_CZ_REASSEMBLY_AUTH64 = 0x956,
|
||||
ID_CZ_REASSEMBLY_AUTH57 = 0x94f,
|
||||
ID_CZ_REASSEMBLY_AUTH44 = 0x942,
|
||||
ID_CZ_REASSEMBLY_AUTH55 = 0x94d,
|
||||
ID_CZ_REASSEMBLY_AUTH17 = 0x894,
|
||||
ID_CZ_REASSEMBLY_AUTH09 = 0x88c,
|
||||
ID_CZ_REASSEMBLY_AUTH12 = 0x88f,
|
||||
ID_CZ_OPEN_BARGAIN_SALE_TOOL = 0x9b4,
|
||||
ID_CZ_REQ_OPEN_GUILD_STORAGE = 0x9ba,
|
||||
ID_CZ_CLOSE_BARGAIN_SALE_TOOL = 0x9bc,
|
||||
ID_CZ_REQ_CLOSE_GUILD_STORAGE = 0x9be,
|
||||
ID_CZ_REQ_COUNT_BARGAIN_SALE_ITEM = 0x9c3,
|
||||
ID_CZ_REASSEMBLY_AUTH73 = 0x95f,
|
||||
ID_CZ_REASSEMBLY_AUTH33 = 0x8a4,
|
||||
ID_CZ_REASSEMBLY_AUTH19 = 0x896,
|
||||
ID_CZ_ITEM_CREATE_EX = 0x9ce,
|
||||
ID_CZ_NPROTECTGAMEGUARDCSAUTH = 0x9d0,
|
||||
ID_CZ_NPC_TRADE_QUIT = 0x9d4,
|
||||
ID_CZ_NPC_MARKET_CLOSE = 0x9d8,
|
||||
ID_CZ_REQ_GUILDSTORAGE_LOG = 0x9d9,
|
||||
ID_CZ_MOVE_ITEM_FROM_BODY_TO_GUILDSTORAGE = 0x9e1,
|
||||
ID_CZ_MOVE_ITEM_FROM_GUILDSTORAGE_TO_BODY = 0x9e2,
|
||||
ID_CZ_MOVE_ITEM_FROM_CART_TO_GUILDSTORAGE = 0x9e3,
|
||||
ID_CZ_MOVE_ITEM_FROM_GUILDSTORAGE_TO_CART = 0x9e4,
|
||||
ID_CZ_OPEN_RODEXBOX = 0xac0,
|
||||
ID_CZ_CLOSE_RODEXBOX = 0x9e9,
|
||||
ID_CZ_REQ_NEXT_RODEX = 0x9ee,
|
||||
ID_CZ_REQ_READ_RODEX = 0x9ea,
|
||||
ID_CZ_REQ_REFRESH_RODEX = 0xac1,
|
||||
ID_CZ_REQ_DELETE_RODEX = 0x9f5,
|
||||
ID_CZ_REASSEMBLY_AUTH82 = 0x968,
|
||||
ID_CZ_REASSEMBLY_AUTH83 = 0x969,
|
||||
ID_CZ_REASSEMBLY_AUTH51 = 0x949,
|
||||
ID_CZ_REQ_SEND_RODEX = 0xa6e,
|
||||
ID_CZ_REQ_ZENY_FROM_RODEX = 0x9f1,
|
||||
ID_CZ_REQ_ITEM_FROM_RODEX = 0x9f3,
|
||||
ID_CZ_PET_EVOLUTION = 0x9fb,
|
||||
ID_CZ_SHORTCUTKEYBAR_ROTATE = 0xa01,
|
||||
ID_CZ_REQ_CANCEL_WRITE_RODEX = 0xa03,
|
||||
ID_CZ_REQ_ADD_ITEM_RODEX = 0xa04,
|
||||
ID_CZ_REQ_REMOVE_RODEX_ITEM = 0xa06,
|
||||
ID_CZ_REQ_OPEN_WRITE_RODEX = 0xa08,
|
||||
ID_CZ_CHECK_RECEIVE_CHARACTER_NAME = 0xa13,
|
||||
ID_CZ_REQ_OPEN_ROULETTE = 0xa19,
|
||||
ID_CZ_REQ_ROULETTE_INFO = 0xa1b,
|
||||
ID_CZ_REQ_CLOSE_ROULETTE = 0xa1d,
|
||||
ID_CZ_REQ_GENERATE_ROULETTE = 0xa1f,
|
||||
ID_CZ_RECV_ROULETTE_ITEM = 0xa21,
|
||||
ID_CZ_REQ_ACH_REWARD = 0xa25,
|
||||
ID_CZ_ACK_AU_BOT = 0xa2a,
|
||||
ID_CZ_REQ_CHANGE_TITLE = 0xa2e,
|
||||
ID_CZ_REQ_ONECLICK_ITEMIDENTIFY = 0xa35,
|
||||
ID_CZ_OFFLINE_STORE_CREATE = 0xa7f,
|
||||
ID_ZC_SPECIALEFFECT = 0x1f3,
|
||||
ID_ZC_NOTIFY_PLAYERCHAT = 0x8e,
|
||||
ID_ZC_BATTLEFIELD_CHAT = 0x2dc,
|
||||
ID_ZC_ALLY_CHAT = 0xbde,
|
||||
ID_REPLAY_WINDOW_RESPONSE = 0x8ae,
|
||||
};
|
||||
|
||||
#endif
|
||||
38
Source/Render/AlphaRectangle.cpp
Normal file
38
Source/Render/AlphaRectangle.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "Render/Primitives/AlphaRectangle.h"
|
||||
#include "Render/Primitives/RenderPrimitivePool.h"
|
||||
#include "Render/Primitives/RenderQueues.h"
|
||||
#include "Render/Textures/TextureCache.h"
|
||||
|
||||
// OFFSET: 0x0054E460
|
||||
// FUNCTION: fn_01952
|
||||
void DrawAlphaRectangle(
|
||||
RenderPrimitivePool& primitives, TextureCache& textures, RenderQueues& queues, int x, int y, int width, int height, std::uint32_t color, bool depthAlpha,
|
||||
float depthStart, float depthEnd
|
||||
) {
|
||||
if ((color & 0xFF000000u) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderPrimitive* primitive = primitives.Acquire();
|
||||
primitive->texture = textures.Default();
|
||||
const float left = static_cast<float>(x);
|
||||
const float top = static_cast<float>(y);
|
||||
const float right = static_cast<float>(x + width);
|
||||
const float bottom = static_cast<float>(y + height);
|
||||
primitive->quad[0].x = left;
|
||||
primitive->quad[0].y = top;
|
||||
primitive->quad[1].x = right;
|
||||
primitive->quad[1].y = top;
|
||||
primitive->quad[2].x = left;
|
||||
primitive->quad[2].y = bottom;
|
||||
primitive->quad[3].x = right;
|
||||
primitive->quad[3].y = bottom;
|
||||
for (RenderVertex& vertex : primitive->quad) {
|
||||
vertex.z = 0.000001f;
|
||||
vertex.rhw = 0.999999f;
|
||||
vertex.diffuse = color;
|
||||
vertex.u = 0.0f;
|
||||
vertex.v = 0.0f;
|
||||
}
|
||||
queues.Submit(primitive, 513, depthAlpha, depthStart, depthEnd);
|
||||
}
|
||||
16
Source/Render/BitmapDrawing.cpp
Normal file
16
Source/Render/BitmapDrawing.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#include "Render/BitmapDrawing.h"
|
||||
#include "Render/DeviceContext/DCBitmap.h"
|
||||
#include "Resource/Bitmap/BitmapResource.h"
|
||||
|
||||
// OFFSET: 0x00A8FC30
|
||||
// FUNCTION: fn_17148
|
||||
void DrawBitmapResource(CRenderSystemBase& system, int x, int y, const CBitmapRes* bitmap) {
|
||||
if (!bitmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
CDCBitmap* surface = CreateBitmapDC(bitmap->image.width, bitmap->image.height, true);
|
||||
surface->Copy(0, 0, bitmap->image.width, bitmap->image.height, bitmap->image.pixels, true);
|
||||
surface->Draw(system, x, y, bitmap->image.width, bitmap->image.height, 0xFFFFFFFF);
|
||||
delete surface;
|
||||
}
|
||||
9
Source/Render/BitmapDrawing.h
Normal file
9
Source/Render/BitmapDrawing.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef RAGNAROK_SOURCE_RENDER_BITMAPDRAWING_H
|
||||
#define RAGNAROK_SOURCE_RENDER_BITMAPDRAWING_H
|
||||
|
||||
class CRenderSystemBase;
|
||||
class CBitmapRes;
|
||||
|
||||
void DrawBitmapResource(CRenderSystemBase& system, int x, int y, const CBitmapRes* bitmap);
|
||||
|
||||
#endif
|
||||
|
|
@ -9,6 +9,7 @@ struct DirectDrawEnumeration::AdapterContext {
|
|||
DirectDrawDeviceRecord record{};
|
||||
};
|
||||
|
||||
// INLINED
|
||||
DirectDrawEnumeration::DirectDrawEnumeration(const GUID& selectedDraw, RECT& monitor) : m_selectedDraw(selectedDraw), m_monitor(monitor) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public:
|
|||
HRESULT TestDevice() override;
|
||||
HRESULT Present(bool option) override;
|
||||
|
||||
// INLINED
|
||||
DeviceOwnerDX7* Device() const {
|
||||
return this->m_device;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ namespace {
|
|||
return static_cast<std::uint16_t>((value >> (channel.expansion & 31)) << (channel.shift & 31));
|
||||
}
|
||||
|
||||
// OFFSET: 0x00543220
|
||||
// FUNCTION: fn_01787
|
||||
// INLINED
|
||||
std::uint16_t Color(DeviceOwnerDX7& owner, unsigned red, unsigned green, unsigned blue) {
|
||||
return static_cast<std::uint16_t>(Channel(red, owner.red) + Channel(green, owner.green) + Channel(blue, owner.blue));
|
||||
}
|
||||
|
|
@ -229,6 +228,16 @@ void CSurfaceDX7::Stretch(int, int, int width, int height) {
|
|||
this->m_owner->renderTarget->Blt(&destination, this->m_surface, nullptr, DDBLT_WAIT, nullptr);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00543220
|
||||
// FUNCTION: fn_01787
|
||||
std::uint16_t DeviceOwnerDX7::PackColor(int red, int green, int blue) {
|
||||
return static_cast<std::uint16_t>(
|
||||
(static_cast<std::uint16_t>(red >> (this->red.expansion & 31)) << (this->red.shift & 31)) +
|
||||
(static_cast<std::uint16_t>(green >> (this->green.expansion & 31)) << (this->green.shift & 31)) +
|
||||
(static_cast<std::uint16_t>(blue >> (this->blue.expansion & 31)) << (this->blue.shift & 31))
|
||||
);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00543270
|
||||
// FUNCTION: fn_01788
|
||||
DWORD DeviceOwnerDX7::BlueMask() {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ struct TextureBindingDX7 {
|
|||
/* 0274 */ IDirect3DDevice7* device = nullptr;
|
||||
|
||||
void Set(unsigned stage, CTextureDX7* texture);
|
||||
// INLINED
|
||||
void Set(IDirect3DDevice7* dev, unsigned stage, CTextureDX7* texture) {
|
||||
this->device = dev;
|
||||
this->Set(stage, texture);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ private:
|
|||
HMODULE m_module;
|
||||
};
|
||||
|
||||
// INLINED
|
||||
inline D3DX9Runtime::D3DX9Runtime() : m_module(LoadLibraryA("D3DX9_43.dll")) {
|
||||
|
||||
if (!this->m_module) {
|
||||
|
|
@ -43,6 +44,7 @@ inline D3DX9Runtime::D3DX9Runtime() : m_module(LoadLibraryA("D3DX9_43.dll")) {
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline D3DX9Runtime::~D3DX9Runtime() {
|
||||
FreeLibrary(this->m_module);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,10 +269,12 @@ HRESULT DeviceOwnerDX9::Present(int) {
|
|||
return this->lastPresent;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
SurfaceDX9Context DeviceOwnerDX9::SurfaceContext() const {
|
||||
return {this->device, this->backBufferDescription, this->backBuffer};
|
||||
}
|
||||
|
||||
// INLINED
|
||||
TextureDX9Context DeviceOwnerDX9::TextureContext(
|
||||
D3DX9Runtime& d3dx, RenderPrimitivePool& primitives, RenderQueues& queues, bool depthAlpha, float depthStart, float depthEnd
|
||||
) const {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ CRenderSystemDX9::~CRenderSystemDX9() {
|
|||
delete this->m_defaultTexture;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
void CRenderSystemDX9::RefreshContexts() {
|
||||
this->m_surfaceContext = this->m_device->SurfaceContext();
|
||||
auto& context = this->m_textureContext;
|
||||
|
|
@ -43,6 +44,7 @@ std::int32_t CRenderSystemDX9::Backend() {
|
|||
return 2;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
HRESULT CRenderSystemDX9::Initialize(HWND window) {
|
||||
const HRESULT result =
|
||||
InitializeConfiguredDeviceDX9(*this->m_device, window, this->m_context->deviceOptions, this->m_context->adapter, this->m_context->serviceUsesDX7);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
HRESULT TestDevice() override;
|
||||
HRESULT Present(bool option) override;
|
||||
|
||||
// INLINED
|
||||
DeviceOwnerDX9& Device() {
|
||||
return *this->m_device;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
namespace {
|
||||
class ScreenshotOverlay : public UIRPData {
|
||||
public:
|
||||
// INLINED
|
||||
const std::list<RenderPrimitive*>& Primitives() const {
|
||||
return this->m_primitives;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ CDCBitmap* CreateBitmapDC(int width, int height, bool fill) {
|
|||
return bitmap;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
void CDCBitmap::UploadTexture(CRenderSystemBase& system, CTexture*& texture) {
|
||||
this->m_bitmap.UploadTexture(system, texture);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ struct RenderSystemHolder {
|
|||
|
||||
// OFFSET: 0x0055D340
|
||||
// FUNCTION: fn_02102
|
||||
__declspec(noinline) inline RenderSystemHolder* GetRenderSystemHolder() {
|
||||
inline RenderSystemHolder* GetRenderSystemHolder() {
|
||||
// GLOBAL: gl_24491
|
||||
static RenderSystemHolder holder;
|
||||
return &holder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
// INLINED
|
||||
void Append(std::vector<RenderVertex>& block, unsigned count) {
|
||||
const unsigned first = static_cast<unsigned>(block.size());
|
||||
block.resize(first + count);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ void RendererViewport::SetSize(int columns, int rows, const float& projectionSca
|
|||
cotangent = projectionScale / this->uiScaleY;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
RenderProjection RendererViewport::Projection() const {
|
||||
return {this->scaleX, this->scaleY, this->centerX, this->centerY};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include "Render/Text/FontCache.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <objidl.h>
|
||||
|
||||
#include <gdiplus.h>
|
||||
|
|
@ -11,7 +10,6 @@
|
|||
|
||||
namespace {
|
||||
// STATIC: 0x01311F00
|
||||
// STATIC: 0x01311ED0
|
||||
const char* const primary[] = {
|
||||
"\xB1\xBC\xB8\xB2",
|
||||
"Arial",
|
||||
|
|
@ -27,6 +25,7 @@ namespace {
|
|||
"Arial",
|
||||
"Tahoma"
|
||||
};
|
||||
// STATIC: 0x01311ED0
|
||||
const char* const fallback[] = {"Gulim", "Arial", "MS Gothic", "SimSun", "MingLiU", "Tahoma", "Arial", "Verdana", "Verdana", "Arial", "Arial", "Tahoma"};
|
||||
|
||||
// OFFSET: 0x0054F2C0
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef RAGNAROK_SOURCE_RENDER_TEXT_TEXTCONTEXT_H
|
||||
#define RAGNAROK_SOURCE_RENDER_TEXT_TEXTCONTEXT_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <windows.h>
|
||||
|
||||
class CDC;
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
// INLINED
|
||||
static inline std::span<const TextureStageWrite> TextureStageModeWrites(int mode) {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
|
|
|
|||
|
|
@ -26,16 +26,19 @@ private:
|
|||
IDirectDraw7* const& m_directDraw;
|
||||
};
|
||||
|
||||
// INLINED
|
||||
inline ClientTextureSources::ClientTextureSources(
|
||||
TextureNames& names, const int& modeType, BinkMovies* const& movies, CRenderSystemBase*& system, IDirectDraw7* const& directDraw
|
||||
)
|
||||
: m_names(names), m_modeType(modeType), m_movies(movies), m_system(system), m_directDraw(directDraw) {
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline const char* ClientTextureSources::Resolve(const char* name) {
|
||||
return this->m_names.Resolve(name);
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline bool ClientTextureSources::MovieSize(const char* name, int& width, int& height) {
|
||||
if (this->m_modeType != 1 || !this->m_movies) {
|
||||
return false;
|
||||
|
|
@ -52,6 +55,7 @@ inline bool ClientTextureSources::MovieSize(const char* name, int& width, int& h
|
|||
return true;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline void ClientTextureSources::CleanupTextures() {
|
||||
if (this->m_system && this->m_system->Backend() == 1 && this->m_directDraw) {
|
||||
this->m_directDraw->Compact();
|
||||
|
|
|
|||
|
|
@ -83,11 +83,13 @@ private:
|
|||
HMODULE m_module;
|
||||
};
|
||||
|
||||
// INLINED
|
||||
inline MilesRuntime& MilesRuntime::Get() {
|
||||
static MilesRuntime instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline MilesRuntime::MilesRuntime() : m_module(LoadLibraryA("Mss32.dll")) {
|
||||
if (!this->m_module) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "Mss32.dll");
|
||||
|
|
@ -158,6 +160,7 @@ inline MilesRuntime::MilesRuntime() : m_module(LoadLibraryA("Mss32.dll")) {
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline MilesRuntime::~MilesRuntime() {
|
||||
FreeLibrary(this->m_module);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ private:
|
|||
HMODULE m_module;
|
||||
};
|
||||
|
||||
// INLINED
|
||||
inline BinkRuntime::BinkRuntime() : m_module(LoadLibraryA("binkw32.dll")) {
|
||||
if (!this->m_module) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "binkw32.dll");
|
||||
|
|
@ -55,6 +56,7 @@ inline BinkRuntime::BinkRuntime() : m_module(LoadLibraryA("binkw32.dll")) {
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline BinkRuntime::~BinkRuntime() {
|
||||
FreeLibrary(this->m_module);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include <bit>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <windows.h>
|
||||
|
||||
namespace {
|
||||
|
|
@ -57,6 +56,62 @@ void BitmapImage::Clear() {
|
|||
this->auxiliary = nullptr;
|
||||
}
|
||||
|
||||
// OFFSET: 0x0074A680
|
||||
// FUNCTION: fn_07866
|
||||
bool BitmapImage::CreateAuxiliary(int mode) {
|
||||
if (!this->pixels || this->auxiliary) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->auxiliary = std::malloc(PixelBytes(this->width, this->height));
|
||||
std::memset(this->auxiliary, 255, 4u * this->width * this->height);
|
||||
auto* output = static_cast<std::uint32_t*>(this->auxiliary);
|
||||
for (int y = 0; y < this->height; ++y) {
|
||||
for (int x = 0; x < this->width; ++x) {
|
||||
const int index = x + y * this->width;
|
||||
const std::uint32_t value = this->pixels[index];
|
||||
unsigned red = (value >> 16) & 255;
|
||||
unsigned green = (value >> 8) & 255;
|
||||
unsigned blue = value & 255;
|
||||
if (red != 255 || blue != 255 || green != 0) {
|
||||
unsigned intensity = (red + green + blue) / 3;
|
||||
const unsigned minimum = mode == 1 ? 120 : 100;
|
||||
if (intensity < minimum) {
|
||||
intensity = minimum;
|
||||
}
|
||||
red = green = blue = intensity;
|
||||
if (mode == 2) {
|
||||
red = 200;
|
||||
} else if (mode == 3) {
|
||||
green = 200;
|
||||
} else if (mode == 4) {
|
||||
blue = 200;
|
||||
}
|
||||
}
|
||||
output[index] = (value & 0xFF000000u) | (red << 16) | (green << 8) | blue;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x0074A7F0
|
||||
// FUNCTION: fn_07867
|
||||
std::uint32_t BitmapImage::Pixel(int x, int y) const {
|
||||
if (x < 0 || x >= this->width || y < 0 || y >= this->height) {
|
||||
return 0x00FF0000;
|
||||
}
|
||||
return this->pixels[x + y * this->width];
|
||||
}
|
||||
|
||||
// OFFSET: 0x0074C540
|
||||
// FUNCTION: fn_07874
|
||||
void BitmapImage::ClearAuxiliary() {
|
||||
if (this->auxiliary) {
|
||||
std::free(this->auxiliary);
|
||||
this->auxiliary = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x0074AB00
|
||||
// FUNCTION: fn_07869
|
||||
bool BitmapImage::DecodeBitmap(const void* input, int, bool iconOnly) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ struct BitmapImage {
|
|||
|
||||
BitmapImage();
|
||||
void Clear();
|
||||
bool CreateAuxiliary(int mode);
|
||||
std::uint32_t Pixel(int x, int y) const;
|
||||
void ClearAuxiliary();
|
||||
bool DecodeBitmap(const void* data, int bytes, bool iconOnly);
|
||||
bool DecodeTga(const void* data, int bytes);
|
||||
bool DecodePng(const void* data, int bytes, const char* name);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "Client/Application/ErrorDialog.h"
|
||||
#include "Resource/Bitmap/BitmapResource.h"
|
||||
#include "Resource/Bitmap/IJL15Runtime.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ private:
|
|||
IJL15Runtime& operator=(const IJL15Runtime&) = delete;
|
||||
};
|
||||
|
||||
// INLINED
|
||||
inline IJL15Runtime::IJL15Runtime() : m_module(LoadLibraryA("ijl15.dll")) {
|
||||
if (!this->m_module) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "ijl15.dll");
|
||||
|
|
@ -61,6 +62,7 @@ inline IJL15Runtime::IJL15Runtime() : m_module(LoadLibraryA("ijl15.dll")) {
|
|||
}
|
||||
}
|
||||
|
||||
// INLINED
|
||||
inline IJL15Runtime::~IJL15Runtime() {
|
||||
FreeLibrary(this->m_module);
|
||||
}
|
||||
|
|
|
|||
4240
Source/Resource/MSGSTRINGID.h
Normal file
4240
Source/Resource/MSGSTRINGID.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -5,8 +5,6 @@
|
|||
#include "Resource/Bitmap/BitmapResource.h"
|
||||
#include "Resource/ResourceByteReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
// INLINED
|
||||
AnimatedModelNode::AnimatedModelNode(TextureCache& textures)
|
||||
: model(nullptr), parent(nullptr), unknown_0040(0), vertexCount(0), textureVertexCount(0), faceCount(0), sharedTextureVertices(0), m_textures(textures) {
|
||||
|
|
@ -20,11 +18,11 @@ AnimatedModelNode::~AnimatedModelNode() {
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x007521F0
|
||||
// OFFSET: 0x007550E0
|
||||
// FUNCTION: fn_07979
|
||||
C3dAnimModelRes::C3dAnimModelRes(ModelResourceContext& context)
|
||||
: shade(2), frameCount(0), animationLength(0), speed(1.0f), unknown_0150(0), unknown_0154(0.0f), unknown_0158(0.0f), unknown_015C(0.0f), alpha(255),
|
||||
m_context(&context) {
|
||||
: unknown_0110(0), unknown_0114(0), shade(2), frameCount(0), animationLength(0), speed(1.0f), unknown_0150(0), unknown_0154(0.0f), unknown_0158(0.0f),
|
||||
unknown_015C(0.0f), alpha(255), m_context(&context) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00753510
|
||||
|
|
|
|||
|
|
@ -47,18 +47,20 @@ public:
|
|||
bool Load(const char* name) override;
|
||||
void Unload() override;
|
||||
|
||||
std::list<AnimatedModelNode*> nodes;
|
||||
std::list<std::string> rootNames;
|
||||
std::string sourceName;
|
||||
int shade;
|
||||
int frameCount;
|
||||
int animationLength;
|
||||
float speed;
|
||||
std::uint32_t unknown_0150;
|
||||
float unknown_0154;
|
||||
float unknown_0158;
|
||||
float unknown_015C;
|
||||
std::uint32_t alpha;
|
||||
/* 0110 */ std::uint32_t unknown_0110;
|
||||
/* 0114 */ std::uint32_t unknown_0114;
|
||||
/* 0118 */ std::list<AnimatedModelNode*> nodes;
|
||||
/* 0120 */ std::list<std::string> rootNames;
|
||||
/* 0128 */ std::string sourceName;
|
||||
/* 0140 */ int shade;
|
||||
/* 0144 */ int frameCount;
|
||||
/* 0148 */ int animationLength;
|
||||
/* 014C */ float speed;
|
||||
/* 0150 */ std::uint32_t unknown_0150;
|
||||
/* 0154 */ float unknown_0154;
|
||||
/* 0158 */ float unknown_0158;
|
||||
/* 015C */ float unknown_015C;
|
||||
/* 0160 */ std::uint32_t alpha;
|
||||
|
||||
private:
|
||||
ModelResourceContext* m_context;
|
||||
|
|
|
|||
|
|
@ -9,32 +9,47 @@
|
|||
#include <cstring>
|
||||
|
||||
// OFFSET: 0x00755630
|
||||
// OFFSET: 0x00750B10
|
||||
// FUNCTION: fn_07985
|
||||
ModelNode::ModelNode(TextureCache& textures) : model(nullptr), parent(nullptr), alpha(255), m_textures(textures) {
|
||||
ModelNode::ModelNode() : model(nullptr), parent(nullptr), alpha(255) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x007570F0
|
||||
// OFFSET: 0x007568E0
|
||||
// FUNCTION: fn_07996
|
||||
ModelNode::~ModelNode() {
|
||||
for (CTexture* texture : this->textures) {
|
||||
if (texture) {
|
||||
texture->Release();
|
||||
this->m_textures.Remove(texture);
|
||||
this->model->m_context->textures.Remove(texture);
|
||||
}
|
||||
}
|
||||
|
||||
this->textures.clear();
|
||||
this->mesh.reset();
|
||||
this->children.clear();
|
||||
}
|
||||
|
||||
// INLINED
|
||||
ModelNodeV1::ModelNodeV1() = default;
|
||||
|
||||
// INLINED
|
||||
ModelNodeV1::~ModelNodeV1() = default;
|
||||
|
||||
// INLINED
|
||||
ModelNodeV2::ModelNodeV2() = default;
|
||||
|
||||
// INLINED
|
||||
ModelNodeV2::~ModelNodeV2() = default;
|
||||
|
||||
// OFFSET: 0x007553E0
|
||||
// FUNCTION: fn_07982
|
||||
C3dModelRes::C3dModelRes(ModelResourceContext& context) : major(0), shade(0), alpha(255), m_context(&context) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00757090
|
||||
// OFFSET: 0x007567B0
|
||||
// FUNCTION: fn_07995
|
||||
C3dModelRes::~C3dModelRes() = default;
|
||||
|
||||
// OFFSET: 0x00750A70
|
||||
// OFFSET: 0x00755560
|
||||
// FUNCTION: fn_07983
|
||||
C3dModelResV1::C3dModelResV1(ModelResourceContext& context) : C3dModelRes(context), animationLength(0) {
|
||||
}
|
||||
|
|
@ -81,7 +96,7 @@ void C3dModelRes::Unload() {
|
|||
|
||||
// INLINED
|
||||
inline void C3dModelResV1::ReadNode(ResourceByteReader& input, unsigned minor, const std::vector<std::string>& textureNames) {
|
||||
auto node = std::make_unique<ModelNode>(this->m_context->textures);
|
||||
auto node = std::make_unique<ModelNodeV1>();
|
||||
node->model = this;
|
||||
node->alpha = this->alpha;
|
||||
char field[40]{};
|
||||
|
|
@ -190,8 +205,7 @@ bool C3dModelResV1::Load(const char* name) {
|
|||
input.Read(magic, 4);
|
||||
|
||||
if (std::strcmp(magic, "GRSM") != 0) {
|
||||
constexpr char message[] = "\xB8\xF0\xB5\xA8\xC6\xC4\xC0\xCF\xC0\xCC \xBE\xC6\xB4\xD5\xB4\xCF\xB4\xD9. \xC7\xFC\xBD\xC4\xC0\xBB "
|
||||
"\xB4\xD9\xBD\xC3\xC7\xD1\xB9\xF8 \xC8\xAE\xC0\xCE\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4.";
|
||||
constexpr char message[] = "모델파일이 아닙니다. 형식을 다시한번 확인해주세요.";
|
||||
ShowErrorDialog(this->m_context->renderSystem, message, 0);
|
||||
file.Close();
|
||||
|
||||
|
|
@ -205,8 +219,7 @@ bool C3dModelResV1::Load(const char* name) {
|
|||
input.Read(&minor, 1);
|
||||
|
||||
if (major != 1 || minor > 5) {
|
||||
constexpr char message[] = "\xC1\xF6\xBF\xF8\xB5\xC7\xC1\xF6 \xBE\xCA\xB4\xC2 \xB9\xF6\xC1\xAF\xC0\xD4\xB4\xCF\xB4\xD9. "
|
||||
"\xB3\xBB\xBF\xEB\xB9\xB0\xC0\xCC \xB1\xFA\xC1\xAE\xC0\xD6\xC0\xBB \xBC\xF6 \xC0\xD6\xBD\xC0\xB4\xCF\xB4\xD9";
|
||||
constexpr char message[] = "지원되지 않는 버젼입니다. 내용물이 깨져있을 수 있습니다";
|
||||
ShowErrorDialog(this->m_context->renderSystem, message, 0);
|
||||
file.Close();
|
||||
|
||||
|
|
|
|||
|
|
@ -50,33 +50,44 @@ struct ModelVolume {
|
|||
|
||||
class ModelNode {
|
||||
public:
|
||||
explicit ModelNode(TextureCache& textures);
|
||||
~ModelNode();
|
||||
ModelNode();
|
||||
virtual ~ModelNode();
|
||||
ModelNode(const ModelNode&) = delete;
|
||||
ModelNode& operator=(const ModelNode&) = delete;
|
||||
|
||||
std::string name;
|
||||
std::string parentName;
|
||||
C3dModelRes* model;
|
||||
ModelNode* parent;
|
||||
std::list<ModelNode*> children;
|
||||
std::vector<class CTexture*> textures;
|
||||
std::unique_ptr<ModelMesh> mesh;
|
||||
unsigned char alpha;
|
||||
unsigned char unknown_0055[3];
|
||||
float position[3];
|
||||
float scale[3];
|
||||
float angle;
|
||||
float axis[3];
|
||||
float transform[12];
|
||||
std::vector<ModelPositionKey> legacyPositionKeys;
|
||||
std::vector<ModelRotationKey> rotationKeys;
|
||||
std::vector<ModelRotationKey> scaleKeys;
|
||||
std::vector<ModelRotationKey> positionKeys;
|
||||
std::map<int, ModelTextureChannels> textureKeys;
|
||||
/* 0004 */ std::string name;
|
||||
/* 001C */ std::string parentName;
|
||||
/* 0034 */ C3dModelRes* model;
|
||||
/* 0038 */ ModelNode* parent;
|
||||
/* 003C */ std::list<ModelNode*> children;
|
||||
/* 0044 */ std::vector<class CTexture*> textures;
|
||||
/* 0050 */ std::unique_ptr<ModelMesh> mesh;
|
||||
/* 0054 */ unsigned char alpha;
|
||||
};
|
||||
|
||||
private:
|
||||
TextureCache& m_textures;
|
||||
class ModelNodeV1 : public ModelNode {
|
||||
public:
|
||||
ModelNodeV1();
|
||||
~ModelNodeV1() override;
|
||||
|
||||
/* 0058 */ float position[3];
|
||||
/* 0064 */ float axis[3];
|
||||
/* 0070 */ float angle;
|
||||
/* 0074 */ float scale[3];
|
||||
/* 0080 */ std::vector<ModelPositionKey> legacyPositionKeys;
|
||||
/* 008C */ std::vector<ModelRotationKey> rotationKeys;
|
||||
};
|
||||
|
||||
class ModelNodeV2 : public ModelNode {
|
||||
public:
|
||||
ModelNodeV2();
|
||||
~ModelNodeV2() override;
|
||||
|
||||
/* 0058 */ float transform[12];
|
||||
/* 0088 */ std::vector<ModelRotationKey> scaleKeys;
|
||||
/* 0094 */ std::vector<ModelRotationKey> rotationKeys;
|
||||
/* 00A0 */ std::vector<ModelRotationKey> positionKeys;
|
||||
/* 00AC */ std::map<int, ModelTextureChannels> textureKeys;
|
||||
};
|
||||
|
||||
struct ModelResourceContext {
|
||||
|
|
@ -86,6 +97,7 @@ struct ModelResourceContext {
|
|||
};
|
||||
|
||||
class C3dModelRes : public CRes {
|
||||
friend class ModelNode;
|
||||
public:
|
||||
explicit C3dModelRes(ModelResourceContext& context);
|
||||
~C3dModelRes() override;
|
||||
|
|
@ -93,15 +105,15 @@ public:
|
|||
ModelNode* FindNode(const char* name) const;
|
||||
void RegisterMovies(class BinkMovies& movies, const float* position) const;
|
||||
|
||||
int major;
|
||||
std::list<ModelNode*> nodes;
|
||||
std::list<std::string> rootNames;
|
||||
std::map<std::string, ModelMesh*> meshes;
|
||||
std::list<ModelVolume*> volumes;
|
||||
std::string sourceName;
|
||||
int shade;
|
||||
unsigned char alpha;
|
||||
std::list<std::string> movieNames;
|
||||
/* 0110 */ int major;
|
||||
/* 0114 */ std::list<ModelNode*> nodes;
|
||||
/* 011C */ std::list<std::string> rootNames;
|
||||
/* 0124 */ std::map<std::string, ModelMesh*> meshes;
|
||||
/* 012C */ std::list<ModelVolume*> volumes;
|
||||
/* 0134 */ std::string sourceName;
|
||||
/* 014C */ int shade;
|
||||
/* 0150 */ unsigned char alpha;
|
||||
/* 0154 */ std::list<std::string> movieNames;
|
||||
|
||||
protected:
|
||||
ModelResourceContext* m_context;
|
||||
|
|
@ -139,4 +151,10 @@ static_assert(sizeof(ModelScaleKey) == 32);
|
|||
static_assert(sizeof(ModelRotationKey) == 20);
|
||||
static_assert(sizeof(ModelVolume) == 232);
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(ModelNode) == 0x58);
|
||||
static_assert(sizeof(ModelNodeV1) == 0x98);
|
||||
static_assert(sizeof(ModelNodeV2) == 0xB4);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace {
|
|||
return name;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
void ReadKeys(ResourceByteReader& input, std::vector<ModelRotationKey>& keys, bool scale) {
|
||||
int count = 0;
|
||||
input.Read(&count, 4);
|
||||
|
|
@ -36,7 +37,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00751ED0
|
||||
// OFFSET: 0x007555C0
|
||||
// FUNCTION: fn_07984
|
||||
C3dModelResV2::C3dModelResV2(ModelResourceContext& context) : C3dModelRes(context), framesPerSecond(0.0f), animationLength(0) {
|
||||
}
|
||||
|
|
@ -65,8 +66,7 @@ bool C3dModelResV2::Load(const char* name) {
|
|||
input.Read(magic, 4);
|
||||
|
||||
if (std::strcmp(magic, "GRSM") != 0) {
|
||||
constexpr char message[] = "\xB8\xF0\xB5\xA8\xC6\xC4\xC0\xCF\xC0\xCC \xBE\xC6\xB4\xD5\xB4\xCF\xB4\xD9. \xC7\xFC\xBD\xC4\xC0\xBB "
|
||||
"\xB4\xD9\xBD\xC3\xC7\xD1\xB9\xF8 \xC8\xAE\xC0\xCE\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4.";
|
||||
constexpr char message[] = "모델파일이 아닙니다. 형식을 다시한번 확인해주세요.";
|
||||
ShowErrorDialog(this->m_context->renderSystem, message, 0);
|
||||
file.Close();
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ bool C3dModelResV2::Load(const char* name) {
|
|||
|
||||
// INLINED
|
||||
inline void C3dModelResV2::ReadNode(ResourceByteReader& input, unsigned minor, const std::vector<std::string>& textureNames) {
|
||||
auto node = std::make_unique<ModelNode>(this->m_context->textures);
|
||||
auto node = std::make_unique<ModelNodeV2>();
|
||||
node->model = this;
|
||||
node->mesh = std::make_unique<ModelMesh>();
|
||||
node->name = ReadName(input);
|
||||
|
|
|
|||
41
Source/Resource/PaletteResource.cpp
Normal file
41
Source/Resource/PaletteResource.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "Resource/PaletteResource.h"
|
||||
#include "Client/Application/ErrorDialog.h"
|
||||
#include "File/File.h"
|
||||
#include "Render/DeviceContext/DCSurface.h"
|
||||
#include "Resource/Sprites/SpriteResource.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
// INLINED
|
||||
CPaletteRes::CPaletteRes() : sourcePalette{}, palette{} {
|
||||
}
|
||||
|
||||
// INLINED
|
||||
CPaletteRes::~CPaletteRes() = default;
|
||||
|
||||
// OFFSET: 0x0075D730
|
||||
// FUNCTION: fn_08039
|
||||
CPaletteRes* CPaletteRes::Create() {
|
||||
return new CPaletteRes;
|
||||
}
|
||||
|
||||
// OFFSET: 0x0075D7D0
|
||||
// FUNCTION: fn_08040
|
||||
bool CPaletteRes::Load(const char* name) {
|
||||
CFile file;
|
||||
if (file.Open(name, 0, true, false)) {
|
||||
file.Read(this->sourcePalette, sizeof(this->sourcePalette));
|
||||
ConvertSpritePalette(this->palette, this->sourcePalette, 256);
|
||||
file.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string message = std::string("CPaletteRes :: Cannot find File : ") + name;
|
||||
ShowErrorDialog(GetRenderSystemHolder()->system, message.c_str(), 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// OFFSET: 0x0075DAF0
|
||||
// FUNCTION: fn_08041
|
||||
void CPaletteRes::Unload() {
|
||||
}
|
||||
24
Source/Resource/PaletteResource.h
Normal file
24
Source/Resource/PaletteResource.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef RAGNAROK_SOURCE_RESOURCE_PALETTERESOURCE_H
|
||||
#define RAGNAROK_SOURCE_RESOURCE_PALETTERESOURCE_H
|
||||
|
||||
#include "Resource/Resource.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CPaletteRes : public CRes {
|
||||
public:
|
||||
CPaletteRes();
|
||||
~CPaletteRes() override;
|
||||
CPaletteRes* Create() override;
|
||||
bool Load(const char* name) override;
|
||||
void Unload() override;
|
||||
|
||||
/* 0110 */ std::uint8_t sourcePalette[1024];
|
||||
/* 0510 */ std::uint32_t palette[256];
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(CPaletteRes) == 0x910);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -11,6 +11,7 @@ ResourceName::ResourceName(const char* name) {
|
|||
this->Assign(name);
|
||||
}
|
||||
|
||||
// INLINED
|
||||
void ResourceName::Assign(const char* name) {
|
||||
myGPack::AssignNameKey(this->hash, this->text, name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "Resource/ResourceAliases.h"
|
||||
#include "File/File.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// OFFSET: 0x00AEF500
|
||||
|
|
@ -32,3 +34,52 @@ std::string AddResourcePrefix(const char* name, const char* prefix) {
|
|||
|
||||
return std::string(prefix) + name;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AEF3A0
|
||||
// FUNCTION: fn_18179
|
||||
std::string ResourceAliases::ResolveMapName(const char* name) const {
|
||||
std::string filename(name);
|
||||
filename += ".gat";
|
||||
const char* resolved = this->Resolve(filename.c_str());
|
||||
const char* extension = std::strstr(resolved, ".gat");
|
||||
return std::string(resolved, extension);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AEFE50
|
||||
// FUNCTION: fn_18187
|
||||
void ResourceAliases::Load(int) {
|
||||
this->names.clear();
|
||||
CFile file;
|
||||
if (!file.Open("ResNameTable.txt", 0, true, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::uint32_t bytes = file.GetSize();
|
||||
auto* contents = static_cast<char*>(std::malloc(bytes + 1));
|
||||
file.Read(contents, bytes);
|
||||
contents[bytes] = '\0';
|
||||
file.Close();
|
||||
|
||||
std::string name;
|
||||
std::string replacement;
|
||||
const char* token = contents;
|
||||
for (int index = 0; index < static_cast<int>(bytes); ++index) {
|
||||
if (contents[index] == '\n' || contents[index] == '\r') {
|
||||
contents[index] = '\0';
|
||||
token = contents + index + 1;
|
||||
} else if (contents[index] == '#') {
|
||||
contents[index] = '\0';
|
||||
if (name.empty()) {
|
||||
name = token;
|
||||
} else {
|
||||
replacement = token;
|
||||
this->names.insert(std::make_pair(name, replacement));
|
||||
name.clear();
|
||||
replacement.clear();
|
||||
}
|
||||
token = contents + index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::free(contents);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ struct ResourceAliases {
|
|||
std::map<std::string, std::string> names;
|
||||
|
||||
const char* Resolve(const char* name) const;
|
||||
std::string ResolveMapName(const char* name) const;
|
||||
void Load(int option);
|
||||
};
|
||||
|
||||
std::string AddResourcePrefix(const char* name, const char* prefix);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ struct ResourceByteReader {
|
|||
unsigned size;
|
||||
unsigned position = 0;
|
||||
|
||||
// INLINED
|
||||
bool Read(void* output, unsigned bytes) {
|
||||
if (position + bytes > size) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
#include <cstring>
|
||||
|
||||
// INLINED
|
||||
ResourceFailures::ResourceFailures(ResourceMessages& messages) : m_messages(&messages) {
|
||||
InitializeCriticalSection(&this->m_lock);
|
||||
}
|
||||
|
||||
// INLINED
|
||||
ResourceFailures::~ResourceFailures() {
|
||||
DeleteCriticalSection(&this->m_lock);
|
||||
}
|
||||
|
|
|
|||
29
Source/Resource/SkinPalette.cpp
Normal file
29
Source/Resource/SkinPalette.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "Resource/SkinPalette.h"
|
||||
#include "Resource/Bitmap/BitmapResource.h"
|
||||
#include "Resource/ResourceMgr.h"
|
||||
#include "Resource/TextureNames.h"
|
||||
|
||||
// OFFSET: 0x007E0F40
|
||||
// FUNCTION: fn_09684
|
||||
std::uint32_t SkinPaletteColor(ResourceMgr& resources, TextureNames& names, const SkinPaletteCell& cell, bool resolveSkin) {
|
||||
const char* filename = "유저인터페이스\\colorchip.bmp";
|
||||
if (resolveSkin) {
|
||||
filename = names.Resolve(filename);
|
||||
}
|
||||
auto* bitmap = static_cast<CBitmapRes*>(resources.Load(filename));
|
||||
if (!bitmap) {
|
||||
return 0;
|
||||
}
|
||||
const std::uint32_t color = bitmap->image.Pixel(4 * cell.column + 2, 4 * cell.row + 2);
|
||||
return ((color & 255) << 16) | (color & 0xFF00) | ((color >> 16) & 255);
|
||||
}
|
||||
|
||||
// OFFSET: 0x007E0FC0
|
||||
// FUNCTION: fn_09685
|
||||
void SkinPaletteChannels(ResourceMgr& resources, TextureNames& names, int x, int y, unsigned& red, unsigned& green, unsigned& blue) {
|
||||
auto* bitmap = static_cast<CBitmapRes*>(resources.Load(names.Resolve("유저인터페이스\\colorchip.bmp")));
|
||||
const std::uint32_t color = bitmap->image.Pixel(x, y);
|
||||
red = (color >> 16) & 255;
|
||||
green = (color >> 8) & 255;
|
||||
blue = color & 255;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue