#ifndef D2CHAR_H #define D2CHAR_H #include #include #include #include #include "d2quest.h" #include "d2strings.h" #include "d2waypoints.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 80 #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 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 { VER_106 = 71, VER_107 = 87, VER_108XP = 87, VER_108 = 89, VER_109 = 92, VER_110 = 96 } D2S_VERSION; typedef 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 } 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 { D2S_ACT1 = 0, D2S_ACT2, D2S_ACT3, D2S_ACT4, D2S_ACT5 } D2S_ACT; // 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; D2WaypointsData waypointsData; uint8_t unknown7; // TODO. Apparently this is always 0x01 uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO: Not implemented // TODO Add stats // TODO Add skills } D2CharHeader; // 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,) uint32_t calcChecksum(D2CharHeader* c, void* charData); int checkChecksum(D2CharHeader* c, void* charData); int isHardcore(D2CharHeader* c); void setHardcore(D2CharHeader* c); int hasDied(D2CharHeader* c); void setDied(D2CharHeader* c); int isExpansion(D2CharHeader* c); void setExpansion(D2CharHeader* c); int isLadder(D2CharHeader* c); void setLadder(D2CharHeader* c); // 0 = Act I, 4 = Act V (Expansion) D2S_ACT 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); // 0 = Normal, 2 = Hell D2S_DIFFICULTY getCurrentDifficulty(D2CharHeader* c); int setProgress(D2S_ACT act, D2S_DIFFICULTY difficulty); int getAttribute(D2S_STAT attr); int setAttribute(D2S_STAT attr, unsigned int value); #endif