d2char.h 3.61 KB
#ifndef D2CHAR_H
#define D2CHAR_H

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "d2quest.h"
#include "d2strings.h"

#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
#define D2S_WAYPOINTS_LENGTH 81
#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

#define D2S_DIFFICULTY_ACTIVE 0x80
#define D2S_DIFFICULTY_NORMAL 0
#define D2S_DIFFICULTY_NIGHTMARE 1
#define D2S_DIFFICULTY_HELL 2
#define D2S_DIFFICULTY_UNKNOWN -1

enum D2S_VERSION {
    VER_106 = 71,
    VER_107 = 87,
    VER_108XP = 87,
    VER_108 = 89,
    VER_109 = 92,
    VER_110 = 96
};

enum D2S_CHARCLASS {
    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
};

enum D2S_ACT {
    D2S_ACT1 = 0,
    D2S_ACT2,
    D2S_ACT3,
    D2S_ACT4,
    D2S_ACT5
};

// TODO: Add file hex offsets for each field
typedef struct __attribute__((packed)){
    uint32_t signature;
    uint32_t versionID;
    uint32_t fileSize;
    uint32_t checksum;
    uint32_t activeWeapon; // Determines which weapon set (I or II in inventory) is currently in use
    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
    uint8_t hotkeys[D2S_HOTKEYS_LENGTH]; // TODO: Not implemented
    uint32_t leftAbility;
    uint32_t rightAbility;
    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!
    uint8_t difficulty[D2S_DIFFICULTY_LENGTH];
    uint32_t mapID; // Not implemented. Too bad!
    uint16_t unknown5; // TODO
    uint16_t mercenaryDead;
    uint32_t mercenarySeed;
    uint16_t mercenaryNameID;
    uint16_t mercenaryType;
    uint32_t mercenaryExp;
    uint8_t unknown6[144]; // TODO
    D2QuestData questData;
    uint8_t waypointData[D2S_WAYPOINTS_LENGTH];
    uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO: Not implemented
} D2CharHeader;

// TODO: All setX functions

uint32_t calcChecksum(D2CharHeader* c, void* charData);
int checkChecksum(D2CharHeader* c, void* charData);
int isHardcore(D2CharHeader* c);
int hasDied(D2CharHeader* c);
int isExpansion(D2CharHeader* c);
int isLadder(D2CharHeader* c);

// 0 = Act I, 4 = Act V (Expansion)
int getCurrentAct(D2CharHeader* c);

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);

// Returns static string from library memory, no need to free
const char* getSkillName(int skillID);

// 0 = Normal, 2 = Hell
int getCurrentDifficulty(D2CharHeader* c);

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

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

#endif