Blame view

d2char.h 4.48 KB
Imanol-Mikel Barba Sabariego authored
1
2
3
4
#ifndef D2CHAR_H
#define D2CHAR_H

#include <stdint.h>
5
#include <stdlib.h>
6
7
8
9
#include <string.h>
#include <time.h>

#include "d2quest.h"
Imanol-Mikel Barba Sabariego authored
10
#include "d2strings.h"
11
#include "d2waypoints.h"
Imanol-Mikel Barba Sabariego authored
12
13
14
15
16
17
18
19
20

#define D2S_HEADER_LENGTH 765
#define D2S_SIGNATURE 0xAA55AA55
#define D2S_CHECKSUM_OFFSET 12
#define D2S_CHECKSUM_LENGTH 4
#define D2S_CHARNAME_LENGTH 16
#define D2S_HOTKEYS_LENGTH 64
#define D2S_CHAR_APPEARANCE_LENGTH 32
#define D2S_DIFFICULTY_LENGTH 3
21
#define D2S_WAYPOINTS_LENGTH 80
Imanol-Mikel Barba Sabariego authored
22
23
24
25
26
27
28
#define D2S_NPCDATA_LENGTH 51

#define D2S_CHARSTATUS_HARDCORE 0x04
#define D2S_CHARSTATUS_DIED 0x08
#define D2S_CHARSTATUS_EXPANSION 0x20
#define D2S_CHARSTATUS_LADDER 0x40
29
30
#define D2S_DIFFICULTY_ACTIVE 0x80
31
32
33
34
35
36
37
38
typedef enum D2S_DIFFICULTY {
    D2S_DIFFICULTY_UNKNOWN = -1,
    D2S_DIFFICULTY_NORMAL = 0,
    D2S_DIFFICULTY_NIGHTMARE = 1,
    D2S_DIFFICULTY_HELL = 2
} D2S_DIFFICULTY;

typedef enum D2S_VERSION {
Imanol-Mikel Barba Sabariego authored
39
40
41
42
43
44
    VER_106 = 71,
    VER_107 = 87,
    VER_108XP = 87,
    VER_108 = 89,
    VER_109 = 92,
    VER_110 = 96
45
} D2S_VERSION;
Imanol-Mikel Barba Sabariego authored
46
47
typedef enum D2S_CHARCLASS {
48
49
50
51
52
53
54
    D2S_CHARCLASS_AMAZON = 0,
    D2S_CHARCLASS_SORCERESS = 1,
    D2S_CHARCLASS_NECROMANCER = 2,
    D2S_CHARCLASS_PALADIN = 3,
    D2S_CHARCLASS_BARBARIAN = 4,
    D2S_CHARCLASS_DRUID = 5,
    D2S_CHARCLASS_ASSASSIN = 6
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
} D2S_CHARCLASS;

typedef enum D2S_STAT {
    D2S_STAT_STRENGTH = 0x00,
    D2S_STAT_ENERGY = 0x01,
    D2S_STAT_DEXTERITY = 0x02,
    D2S_STAT_VITALITY = 0x03,
    D2S_STAT_STATPTS = 0x04,
    D2S_STAT_SKILLPTS = 0x05,
    D2S_STAT_LIFE = 0x06,
    D2S_STAT_MAXLIFE = 0x07,
    D2S_STAT_MANA = 0x08,
    D2S_STAT_MAXMANA = 0x09,
    D2S_STAT_STAMINA = 0x0a,
    D2S_STAT_MAXSTAMINA = 0x0b,
    D2S_STAT_LEVEL = 0x0c,
    D2S_STAT_EXPERIENCE = 0x0d,
    D2S_STAT_GOLD = 0x0e,
    D2S_STAT_GOLDSTASH = 0x0f,
} D2S_STAT;

typedef enum D2S_ACT {
Imanol-Mikel Barba Sabariego authored
77
    D2S_ACT1 = 0,
78
79
80
81
    D2S_ACT2,
    D2S_ACT3,
    D2S_ACT4,
    D2S_ACT5
82
} D2S_ACT;
Imanol-Mikel Barba Sabariego authored
83
Imanol-Mikel Barba Sabariego authored
84
// TODO: Add file hex offsets for each field
Imanol-Mikel Barba Sabariego authored
85
86
87
88
89
typedef struct __attribute__((packed)){
    uint32_t signature;
    uint32_t versionID;
    uint32_t fileSize;
    uint32_t checksum;
90
    uint32_t activeWeapon; // Determines which weapon set (I or II in inventory) is currently in use
Imanol-Mikel Barba Sabariego authored
91
92
93
94
95
96
97
98
99
100
    char name[D2S_CHARNAME_LENGTH];
    uint8_t charStatus;
    uint8_t charProgress;
    uint16_t unknown1; // TODO
    uint8_t charClass;
    uint16_t unknown2; // TODO
    uint8_t charLevel;
    uint32_t unknown3; // TODO
    uint32_t lastPlayed;
    uint32_t unknown4; // TODO
Imanol-Mikel Barba Sabariego authored
101
    uint8_t hotkeys[D2S_HOTKEYS_LENGTH]; // TODO: Not implemented
Imanol-Mikel Barba Sabariego authored
102
103
    uint32_t leftAbility;
    uint32_t rightAbility;
104
105
106
    uint32_t leftAbilityAlt; // Left ability when alternative weapon set (II) is selected
    uint32_t rightAbilityAlt; // Right ability when alternative weapon set (II) is selected
    uint8_t charAppearance[D2S_CHAR_APPEARANCE_LENGTH]; // Not implemented. Too bad!
Imanol-Mikel Barba Sabariego authored
107
    uint8_t difficulty[D2S_DIFFICULTY_LENGTH];
108
109
110
    uint32_t mapID; // Not implemented. Too bad!
    uint16_t unknown5; // TODO
    uint16_t mercenaryDead;
Imanol-Mikel Barba Sabariego authored
111
112
113
114
    uint32_t mercenarySeed;
    uint16_t mercenaryNameID;
    uint16_t mercenaryType;
    uint32_t mercenaryExp;
115
    uint8_t unknown6[144]; // TODO
116
    D2QuestData questData;
117
    D2WaypointsData waypointsData;
118
    uint8_t unknown7; // TODO. Apparently this is always 0x01
Imanol-Mikel Barba Sabariego authored
119
    uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO: Not implemented
120
121
    // TODO Add stats
    // TODO Add skills
Imanol-Mikel Barba Sabariego authored
122
123
} D2CharHeader;
124
Imanol-Mikel Barba Sabariego authored
125
126
127
128
129
130
131
// TODO: Load from file.
// int loadD2CharFromFile(const char* file, D2CharHeader** header, void** data);

// TODO: Write to file.
// int writeD2CharToFile(const char* file, D2CharHeader* header, void* charData,)
Imanol-Mikel Barba Sabariego authored
132
133
134
uint32_t calcChecksum(D2CharHeader* c, void* charData);
int checkChecksum(D2CharHeader* c, void* charData);
int isHardcore(D2CharHeader* c);
135
void setHardcore(D2CharHeader* c);
Imanol-Mikel Barba Sabariego authored
136
int hasDied(D2CharHeader* c);
137
void setDied(D2CharHeader* c);
Imanol-Mikel Barba Sabariego authored
138
int isExpansion(D2CharHeader* c);
139
void setExpansion(D2CharHeader* c);
Imanol-Mikel Barba Sabariego authored
140
int isLadder(D2CharHeader* c);
141
void setLadder(D2CharHeader* c);
Imanol-Mikel Barba Sabariego authored
142
143
// 0 = Act I, 4 = Act V (Expansion)
144
D2S_ACT getCurrentAct(D2CharHeader* c);
145
146
147
148
149
150
151
152
153
154

int isFemale(D2CharHeader* c);

// Returns static string from library memory, no need to free
const char* getCharacterTitle(D2CharHeader* c);

// Writes to user-allocated string. Format is default locale's time representation
size_t getLastPlayed(D2CharHeader* c, char* buf, size_t bufLen);

// 0 = Normal, 2 = Hell
155
D2S_DIFFICULTY getCurrentDifficulty(D2CharHeader* c);
156
157
int setProgress(D2S_ACT act, D2S_DIFFICULTY difficulty);
158
159
160
int getAttribute(D2S_STAT attr);
int setAttribute(D2S_STAT attr, unsigned int value);
161
Imanol-Mikel Barba Sabariego authored
162
#endif