This commit is contained in:
Hash Borgir 2024-05-27 09:17:54 -06:00
parent cce65db976
commit c0f1e91e4a
53 changed files with 591 additions and 45 deletions

Binary file not shown.

View File

@ -1,2 +1,4 @@
 loot_filter_settings_toggle_menu.cpp
 autosort_client.cpp
D:\VSCode\d2tweaks-rnd2k\src\d2tweaks\client\modules\autosort\autosort_client.cpp(197,15): warning C4018: '<': signed/unsigned mismatch
D:\VSCode\d2tweaks-rnd2k\src\d2tweaks\client\modules\autosort\autosort_client.cpp(197,66): warning C4018: '<=': signed/unsigned mismatch
D2tweaks.vcxproj -> D:\Diablo II\MODS\ironman-dev\D2tweaks.dll

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -119,7 +119,7 @@ namespace d2_tweaks {
bool quality_settings[static_cast<size_t>(diablo2::structures::item_quality_t::ITEM_QUALITY_COUNT)];
char reserved[1004];
char reserved[888];
static loot_filter_settings& get();

View File

@ -241,6 +241,7 @@ namespace d2_tweaks {
uint32_t bag_guid = 0;
bool updateBag;
bool removeFromBag;
bool summon;
int prop;
int val;
int tmog;
@ -306,7 +307,16 @@ namespace d2_tweaks {
uint32_t currentHp; // New field for current hit points
uint32_t maxHp; // New field for maximum hit points
damage_info_sc() : unit_type(0), guid(0), damage_type(DAMAGE_TYPE_UNKNOWN), damage(0), currentHp(0), maxHp(0) {
// You can add these details to the packet if needed
// packet.isChampion = isChampion;
// packet.isUnique = isUnique;
// packet.isSuperUnique = isSuperUnique
bool isChampion;
bool isUnique;
bool isSuperUnique;
damage_info_sc() : unit_type(0), guid(0), damage_type(DAMAGE_TYPE_UNKNOWN), damage(0), currentHp(0), maxHp(0), isChampion(0), isUnique(0), isSuperUnique(0) {
message_type = MESSAGE_TYPE_DAMAGE_INFO;
}
};

View File

@ -75,13 +75,7 @@
//
//extern DataTables* sgptDataTables;
struct D2PropertyStrc
{
int32_t nProperty; //0x00
int32_t nLayer; //0x04
int32_t nMin; //0x08
int32_t nMax; //0x0C
};
@ -95,6 +89,14 @@ namespace diablo2 {
struct items_line;
struct item_types_line;
struct D2PropertyStrc
{
int32_t nProperty; //0x00
int32_t nLayer; //0x04
int32_t nMin; //0x08
int32_t nMax; //0x0C
};
struct D2RunesTxt
{
char szName[64]; //0x00
@ -373,10 +375,10 @@ namespace diablo2 {
UNIT_STAT_ITEM_SKILLONLEVELUP = 0xC7,
UNIT_STAT_UNUSED200 = 0xC8,
UNIT_STAT_ITEM_SKILLONGETHIT = 0xC9,
UNIT_STAT_UNUSED202 = 0xCA,
UNIT_STAT_UNUSED203 = 0xCB,
UNIT_STAT_ITEM_CHARGED_SKILL = 0xCC,
UNIT_STAT_UNUSED204 = 0xCD,
UNIT_STAT_is_champion = 0xCA, // 202
UNIT_STAT_is_unique = 0xCB, // 203
UNIT_STAT_ITEM_CHARGED_SKILL = 0xCC, // 204
UNIT_STAT_is_super_unique = 0xCD, // 205
UNIT_STAT_UNUSED205 = 0xCE,
UNIT_STAT_UNUSED206 = 0xCF,
UNIT_STAT_UNUSED207 = 0xD0,
@ -969,7 +971,7 @@ namespace diablo2 {
UNIT_STAT_gembag_Stones_Sulpher = 491,
UNIT_STAT_gembag_Stones_Quartz = 492,
UNIT_STAT_gembag_Stones_TigerEye = 493,
UNIT_STAT_BoH_Desc = 494,
UNIT_STAT_UNUSED_68 = 494,
UNIT_STAT_runebag_RunesE = 495,
UNIT_STAT_runebag_RunesF = 496,
UNIT_STAT_passive_sum_mastery = 497,
@ -1051,7 +1053,7 @@ namespace diablo2 {
static void diablo2::d2_common::update_trade(structures::inventory* inventory, structures::unit* item);
//static void diablo2::d2_common::set_item_flags(structures::unit* item, structures::itemflags_t dwFlag, bool bSet);
static void diablo2::d2_common::add_property(structures::unit* item, D2PropertyStrc* pProperty, int nUnused);
static void diablo2::d2_common::add_property(structures::unit* item, diablo2::structures::D2PropertyStrc* pProperty, int nUnused);
static void diablo2::d2_common::ITEMS_SetItemFlag(structures::unit* item, uint32_t dwFlag, BOOL bSet);
//D2Common.0x6FDA42B0
@ -1074,5 +1076,6 @@ namespace diablo2 {
//D2Common.0x6FD57680 (#10600)
//D2ItemsTxt* __stdcall DATATBLS_GetItemsTxtRecord(int nItemId)
static structures::items_line* get_items_txt_record(int nItemId);
};
}

View File

@ -3,6 +3,7 @@
#include <cstdint>
#include <functional>
#include <diablo2/structures/unit.h>
#include "d2common.h"
namespace diablo2 {
namespace structures {
@ -10,6 +11,205 @@ namespace diablo2 {
struct net_client;
struct game;
struct unit;
struct D2MonPropTxt
{
uint32_t dwId; //0x00
diablo2::structures::D2PropertyStrc props[3][6]; //0x04
uint8_t nChance[3][6]; //0x124
uint16_t pad0x136; //0x136
};
#pragma pack(1)
enum D2C_AiSpecialState : uint32_t
{
AISPECIALSTATE_NONE = 0,
AISPECIALSTATE_NO_MON_STATS = 1, // Set when classid > nMonStatsRecord
AISPECIALSTATE_2 = 2, // Unused
AISPECIALSTATE_3 = 3, // Unused
AISPECIALSTATE_4 = 4, // Unused
AISPECIALSTATE_ROGUE_HIREABLE_NON_PLAYER_OWNER = 5,
AISPECIALSTATE_HIREABLE_NON_PLAYER_OWNER = 6,
AISPECIALSTATE_REVIVED = 7, // as necromancer pet
AISPECIALSTATE_8 = 8, // Unused
AISPECIALSTATE_9 = 9, // Unused
// Curses
AISPECIALSTATE_DIMVISION = 10,
AISPECIALSTATE_TERROR = 11,
AISPECIALSTATE_TAUNT = 12,
AISPECIALSTATE_COUNTESS = 13,
AISPECIALSTATE_14 = 14, // Unused
AISPECIALSTATE_WHIPPED = 15, // When whipped by overseer, for suicide minions
AISPECIALSTATE_MOUNTING_UNIT = 16, // When a unit is mounting another (tower / siege beast)
AISPECIALSTATE_17 = 17, // Unused
AISPECIALSTATE_TABLE_COUNT = 18,
AISPECIALSTATE_INVALID = 19, // Could be for objects ?
};
struct D2SkillsTxt
{
int16_t nSkillId; //0x00
uint16_t unk0x02; //0x02
uint32_t dwFlags[2]; //0x04 D2C_SkillsTxtFlags
int8_t nCharClass; //0x0C
uint8_t unk0x0D[3]; //0x0D
uint8_t nAnim; //0x10
uint8_t nMonAnim; //0x11
uint8_t nSeqTrans; //0x12
uint8_t nSeqNum; //0x13
uint8_t nRange; //0x14
uint8_t nSelectProc; //0x15
uint8_t nSeqInput; //0x16
uint8_t pad0x17; //0x17
int16_t nITypeA[3]; //0x18
int16_t nITypeB[3]; //0x1E
int16_t nETypeA[2]; //0x24
int16_t nETypeB[2]; //0x28
int16_t wSrvStartFunc; //0x2C
uint16_t wSrvDoFunc; //0x2E
uint16_t wSrvPrgFunc[3]; //0x30
uint16_t pad0x36; //0x36
uint32_t dwPrgCalc[3]; //0x38
uint8_t nPrgDamage; //0x44
uint8_t pad0x45; //0x45
int16_t wSrvMissile; //0x46
int16_t wSrvMissileA; //0x48
int16_t wSrvMissileB; //0x4A
int16_t wSrvMissileC; //0x4C
int16_t wSrvOverlay; //0x4E
uint32_t dwAuraFilter; //0x50
int16_t wAuraStat[6]; //0x54
uint32_t dwAuraLenCalc; //0x60
uint32_t dwAuraRangeCalc; //0x64
int32_t dwAuraStatCalc[6]; //0x68
int16_t nAuraState; //0x80
int16_t wAuraTargetState; //0x82
int16_t wAuraEvent[3]; //0x84
int16_t wAuraEventFunc[3]; //0x8A
uint16_t wAuraTgtEvent; //0x90
uint16_t wAuraTgtEventFunc; //0x92
int16_t nPassiveState; //0x94
int16_t nPassiveIType; //0x96
int16_t nPassiveStat[5]; //0x98
uint16_t pad0xA2; //0xA2
uint32_t dwPassiveCalc[5]; //0xA4
uint16_t wPassiveEvent; //0xB8
uint16_t wPassiveEventFunc; //0xBA
uint16_t wSummon; //0xBC
int8_t nPetType; //0xBE
int8_t nSumMode; //0xBF
uint32_t dwPetMax; //0xC0
uint16_t wSumSkill[5]; //0xC4
uint16_t pad0xCE; //0xCE
uint32_t dwSumSkCalc[5]; //0xD0
int16_t wSumUMod; //0xE4
int16_t wSumOverlay; //0xE6
uint16_t wCltMissile; //0xE8
uint16_t wCltMissileA; //0xEA
uint16_t wCltMissileB; //0xEC
uint16_t wCltMissileC; //0xEE
uint16_t wCltMissileD; //0xF0
uint16_t wCltStFunc; //0xF2
uint16_t wCltDoFunc; //0xF4
uint16_t wCltPrgFunc[3]; //0xF6
uint16_t wStSound; //0xFC
uint16_t nStSoundClass; //0x0FE
uint16_t wDoSound; //0x100
uint16_t wDoSoundA; //0x102
uint16_t wDoSoundB; //0x104
uint16_t wCastOverlay; //0x106
uint16_t wTgtOverlay; //0x108
uint16_t wTgtSound; //0x10A
uint16_t wPrgOverlay; //0x10C
uint16_t wPrgSound; //0x10E
uint16_t wCltOverlayA; //0x110
uint16_t wCltOverlayB; //0x112
int32_t dwCltCalc[3]; //0x114
uint8_t nItemTarget; //0x120 D2C_SkillsTxtItemTarget
uint8_t pad0x121; //0x121
uint16_t wItemCastSound; //0x122
uint16_t wItemCastOverlay; //0x124
uint16_t pad0x126; //0x126
uint32_t dwPerDelay; //0x128
uint16_t wMaxLvl; //0x12C
uint16_t wResultFlags; //0x12E
uint32_t dwHitFlags; //0x130
uint32_t dwHitClass; //0x134
uint32_t dwCalc[4]; //0x138
int32_t dwParam[8]; //0x148
uint8_t nWeapSel; //0x168
uint8_t pad0x169; //0x169
uint16_t wItemEffect; //0x16A
uint16_t wItemCltEffect; //0x16C
uint16_t pad0x16E; //0x16E
uint32_t dwSkPoints; //0x170
uint16_t wReqLevel; //0x174
uint16_t wReqStr; //0x176
uint16_t wReqDex; //0x178
uint16_t wReqInt; //0x17A
uint16_t wReqVit; //0x17C
int16_t nReqSkill[3]; //0x17E
int16_t wStartMana; //0x184
uint16_t wMinMana; //0x186
uint8_t nManaShift; //0x188
uint8_t pad0x189; //0x189
int16_t wMana; //0x18A
int16_t wLevelMana; //0x18C
uint8_t nAttackRank; //0x18E
uint8_t nLineOfSight; //0x18F D2C_SkillsTxtLineOfSight
uint32_t dwDelay; //0x190
uint16_t wSkillDesc; //0x194
uint16_t pad0x196; //0x196
uint32_t dwToHit; //0x198
uint32_t dwLevToHit; //0x19C
uint32_t dwToHitCalc; //0x1A0
uint8_t nToHitShift; //0x1A4
uint8_t nSrcDam; //0x1A5
uint16_t pad0x1A6; //0x1A6
uint32_t dwMinDam; //0x1A8
uint32_t dwMaxDam; //0x1AC
uint32_t dwMinLvlDam[5]; //0x1B0
uint32_t dwMaxLvlDam[5]; //0x1C4
uint32_t dwDmgSymPerCalc; //0x1D8
uint8_t nEType; //0x1DC
uint8_t pad0x1DD[3]; //0x1DD
uint32_t dwEMin; //0x1E0
uint32_t dwEMax; //0x1E4
uint32_t dwEMinLev[5]; //0x1E8
uint32_t dwEMaxLev[5]; //0x1FC
uint32_t dwEDmgSymPerCalc; //0x210
uint32_t dwELen; //0x214
uint32_t dwELevLen[3]; //0x218
uint32_t dwELenSymPerCalc; //0x224
uint8_t nRestrict; //0x228
uint8_t pad0x229; //0x229
int16_t nState[3]; //0x22A
uint8_t nAiType; //0x230
uint8_t pad0x231; //0x231
int16_t wAiBonus; //0x232
int32_t nCostMult; //0x234
int32_t nCostAdd; //0x238
};
#pragma pack()
struct D2SummonArgStrc
{
uint32_t dwFlags; //0x00
diablo2::structures::unit* pOwner; //0x04
int32_t nHcIdx; //0x08
D2C_AiSpecialState nAiSpecialState; //0x0C
int32_t nMonMode; //0x10
D2CoordStrc pPosition; //0x14
int32_t nPetType; //0x1C
int32_t nPetMax; //0x20
};
}
class d2_game {
@ -52,8 +252,52 @@ namespace diablo2 {
static structures::unit* __fastcall D2GAME_CreateItemEx_6FC4ED80(structures::game* pGame, structures::D2ItemDropStrc* pItemDrop, int32_t a3);
//D2Game.0x6FC4A660
static int32_t __fastcall D2GAME_Transmogrify_6FC4A660(structures::game* pGame, structures::unit* pPlayer, structures::unit* pItem);
static int32_t __fastcall diablo2::d2_game::D2GAME_Transmogrify_6FC4A660(structures::game* pGame, structures::unit* pPlayer, structures::unit* pItem);
static diablo2::structures::unit* __fastcall diablo2::d2_game::QUESTS_CreateItem(diablo2::structures::game* pGame, diablo2::structures::unit* pPlayer, uint32_t dwCode, int32_t nLevel, uint8_t nQuality, int32_t bDroppable);
// Add wrapper for D2Game.0x6FC603D0
// D2MonPropTxt* __fastcall MONSTER_GetMonPropTxtRecord(int32_t nId)
static diablo2::structures::D2MonPropTxt* __fastcall diablo2::d2_game::MONSTER_GetMonPropTxtRecord(int32_t nId);
// add wrapper for //D2Game.0x6FCBC900
// D2UnitStrc* __stdcall SUNIT_GetTargetUnit(D2GameStrc* pGame, D2UnitStrc* pUnit)
static diablo2::structures::unit* __stdcall diablo2::d2_game::SUNIT_GetTargetUnit(structures::game* pGame, structures::unit* pUnit);
//D2Game.0x6FCF5B90
//D2SkillsTxt* __fastcall SKILLS_GetSkillsTxtRecord(int32_t nSkillId)
static diablo2::structures::D2SkillsTxt* __fastcall diablo2::d2_game::SKILLS_GetSkillsTxtRecord(int32_t nSkillId);
//D2Game.0x6FD15580
//int32_t __fastcall D2GAME_GetSummonIdFromSkill_6FD15580(D2UnitStrc* pUnit, int32_t bFromMonster, int32_t nSkillId, int32_t nSkillLevel, int32_t* pSpawnMode, int32_t* pX, int32_t* pY)
static int32_t __fastcall diablo2::d2_game::D2GAME_GetSummonIdFromSkill_6FD15580(structures::unit* pUnit, int32_t bFromMonster, int32_t nSkillId, int32_t nSkillLevel, int32_t* pSpawnMode, int32_t* pX, int32_t* pY);
//D2Game.0x6FD14430
//D2UnitStrc* __fastcall D2GAME_SummonPet_6FD14430(D2GameStrc* pGame, D2SummonArgStrc* pSummonArg)
static diablo2::structures::unit* __fastcall diablo2::d2_game::D2GAME_SummonPet_6FD14430(structures::game* pGame, structures::D2SummonArgStrc* pSummonArg);
//D2Game.0x6FD0CB10
//int32_t __fastcall D2GAME_SKILLS_SetSummonBaseStats_6FD0CB10(D2GameStrc* pGame, D2UnitStrc* pUnit, D2UnitStrc* pPet, int32_t nPetLevelArg, int32_t nSkillLevel)
static int32_t __fastcall diablo2::d2_game::D2GAME_SKILLS_SetSummonBaseStats_6FD0CB10(structures::game* pGame, structures::unit* pUnit, structures::unit* pPet, int32_t nPetLevelArg, int32_t nSkillLevel);
//D2Game.0x6FD0C530
//int32_t __fastcall D2GAME_SetSummonPassiveStats_6FD0C530(D2GameStrc* pGame, D2UnitStrc* pUnit, D2UnitStrc* pPet, int32_t nSkillId, int32_t nSkillLevel, int32_t nItemLevel)
static int32_t __fastcall diablo2::d2_game::D2GAME_SetSummonPassiveStats_6FD0C530(structures::game* pGame, structures::unit* pUnit, structures::unit* pPet, int32_t nSkillId, int32_t nSkillLevel, int32_t nItemLevel);
//D2Game.0x6FD0C2E0
//void __fastcall D2GAME_SetSummonResistance_6FD0C2E0(D2UnitStrc* pUnit, D2UnitStrc* pPet)
static void __fastcall diablo2::d2_game::D2GAME_SetSummonResistance_6FD0C2E0(structures::unit* pUnit, structures::unit* pPet);
//D2Game.0x6FC3E200
//void __fastcall sub_6FC3E200(D2ClientStrc* pClient, D2UnitStrc* pUnit)
static void __fastcall diablo2::d2_game::sub_6FC3E200(structures::net_client* pClient, structures::unit* pUnit);
//D2Game.0x6FC69F10
//D2UnitStrc* __fastcall D2GAME_SpawnMonster_6FC69F10(D2GameStrc* pGame, D2ActiveRoomStrc* pRoom, int32_t nX, int32_t nY, int32_t nMonsterId, int32_t nAnimMode, int32_t a7, int16_t nFlags)
static diablo2::structures::unit* __fastcall diablo2::d2_game::D2GAME_SpawnMonster_6FC69F10(structures::game* pGame, structures::room* pRoom, int32_t nX, int32_t nY, int32_t nMonsterId, int32_t nAnimMode, int32_t a7, int16_t nFlags);
};
}

View File

@ -311,6 +311,7 @@ public:
&& !diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_HELP)
&& !diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_MERC)
&& !diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_SCROLL)) {
// Draw stats
diablo2::d2_win::set_current_font(fontMap[statsFont]); // Set font to FONT16
diablo2::d2_win::draw_text(const_cast<wchar_t*>(statText.c_str()), stat.x1, stat.y1 + textOffset, stat.colorStat, 0);
@ -319,6 +320,10 @@ public:
diablo2::d2_win::draw_text(const_cast<wchar_t*>(statValueStr.c_str()), stat.x2, stat.y2 + textOffset, stat.colorStatValue, 0);
/*
auto runeword = diablo2::d2_common::get_runes_txt_record(169);

View File

@ -17,6 +17,9 @@
#include <diablo2/d2cmp.h>
#include <common/hooking.h>
#include <diablo2/structures/monster_data.h>
MODULE_INIT(damage_display)
struct damage_label {
@ -32,6 +35,9 @@ struct damage_label {
int32_t maxHp; // New field for maximum hit points
int32_t text_width;
wchar_t text[64];
bool isChampion;
bool isUnique;
bool isSuperUnique;
damage_label(uint32_t x, uint32_t y, uint32_t uw, uint32_t uh, int32_t damage, int32_t hp, int32_t maxHp)
: screen_space(false), color(diablo2::ui_color_t::UI_COLOR_WHITE), x(x), y(y),
@ -273,6 +279,10 @@ static void draw_damage_labels() {
diablo2::d2_win::draw_text(const_cast<wchar_t*>(dmgTextPtr), textX + diablo2::d2_win::get_text_pixel_width(const_cast<wchar_t*>(combinedTextPtr)) / 2, my + label->unit_height / 2, textColor, 0);
}
}
}
diablo2::d2_win::set_current_font(font);
@ -390,10 +400,45 @@ void d2_tweaks::client::modules::damage_display::handle_packet(common::packet_he
swprintf_s(label->text, L"%i", label->damage);
label->text_width = diablo2::d2_win::get_text_pixel_width(label->text);
/*
// Assuming info is already defined and contains the GUID
auto monster = diablo2::d2_client::get_unit_by_guid(info->guid, 0x01);
auto monsterData = monster->monster_data;
bool isChampion = monsterData->is_champion;
bool isSuperUnique = monsterData->is_super_unique;
bool isUnique = monsterData->is_unique;
if (info->currentHp == 0) {
//MessageBoxA(nullptr, "Monster is dead", "Monster is dead", MB_OK);
if (isChampion) {
//MessageBoxA(nullptr, "Monster is a Champion", "Monster is a Champion", MB_OK);
auto isChampionValue = diablo2::d2_common::get_stat(player, diablo2::UNIT_STAT_is_champion, 0);
diablo2::d2_common::set_stat(player, diablo2::UNIT_STAT_is_champion, isChampionValue + 1, 0);
}
else if (isUnique) {
//MessageBoxA(nullptr, "Monster is Unique", "Monster is Unique", MB_OK);
auto isUniqueValue = diablo2::d2_common::get_stat(player, diablo2::UNIT_STAT_is_unique, 0);
diablo2::d2_common::set_stat(player, diablo2::UNIT_STAT_is_unique, isUniqueValue + 1, 0);
}
else if (isSuperUnique) {
//MessageBoxA(nullptr, "Monster is Super Unique", "Monster is Super Unique", MB_OK);
auto isSuperUniqueValue = diablo2::d2_common::get_stat(player, diablo2::UNIT_STAT_is_super_unique, 0);
diablo2::d2_common::set_stat(player, diablo2::UNIT_STAT_is_super_unique, isSuperUniqueValue + 1, 0);
}
}
*/
if (add_label(label))
return;
g_label_pool.put(label); //prevent memory leak if there's no room for another label
}
void d2_tweaks::client::modules::damage_display::tick() {

View File

@ -1239,7 +1239,7 @@ void d2_tweaks::client::modules::loot_filter_settings_menu::extract_item(bool va
packet.val = -val;
diablo2::d2_client::send_to_server(&packet, sizeof packet);
D2PropertyStrc itemProperty = {};
diablo2::structures::D2PropertyStrc itemProperty = {};
itemProperty.nProperty = prop - 3; // Adjust the property ID
itemProperty.nLayer = 0;
itemProperty.nMin = -val;
@ -1269,7 +1269,7 @@ void d2_tweaks::client::modules::loot_filter_settings_menu::extract_rejuv_potion
void d2_tweaks::client::modules::loot_filter_settings_menu::extract_full_rejuv_potion(bool value) {
loot_filter_settings::get().m_show_full_rejuv_potion = value;
extract_item(value, 396, 5000, 'rvl ', diablo2::UNIT_STAT_gembag_Potions);
extract_item(value, 396, 3000, 'rvl ', diablo2::UNIT_STAT_gembag_Potions);
}
// stones

View File

@ -135,13 +135,13 @@ bool d2_tweaks::server::modules::autosort::sort(diablo2::structures::game* game,
occupied_cells += record->inv_height * record->inv_width;
}
spdlog::info("--------------------------------");
spdlog::info("Item Type: {0}", record->type);
spdlog::info("Item Type 2: {0}", record->type2);
spdlog::info("Occupied Cells: {0}", occupied_cells);
spdlog::info("x: {0}", backup.x);
spdlog::info("y: {0}", backup.y);
spdlog::info("is_charm: {0}\n\n", is_charm);
//spdlog::info("--------------------------------");
//spdlog::info("Item Type: {0}", record->type);
//spdlog::info("Item Type 2: {0}", record->type2);
//spdlog::info("Occupied Cells: {0}", occupied_cells);
//spdlog::info("x: {0}", backup.x);
//spdlog::info("y: {0}", backup.y);
//spdlog::info("is_charm: {0}\n\n", is_charm);
}
if (occupied_cells > inventoryHeight * inventoryWidth) {

View File

@ -64,6 +64,62 @@ static void send_damage_data(diablo2::structures::unit* defender,
auto currentHp = diablo2::d2_common::get_stat(defender, diablo2::UNIT_STAT_HITPOINTS, 0);
auto maxHp = diablo2::d2_common::get_stat(defender, diablo2::UNIT_STAT_MAXHP, 0);
/*
if (defender->type == diablo2::structures::unit_type_t::UNIT_TYPE_PLAYER) {
auto player = defender;
// spdlog player name
spdlog::info("Player name: {0}", player->player_data->name);
diablo2::d2_common::set_stat(player, diablo2::UNIT_STAT_is_champion, 100, 0);
// if defender is a monster, get the monster data
if (defender->type == diablo2::structures::unit_type_t::UNIT_TYPE_MONSTER) {
auto monsterData = defender->monster_data;
if (monsterData) {
bool isChampion = monsterData->is_champion;
bool isUnique = monsterData->is_unique;
bool isSuperUnique = monsterData->is_super_unique;
spdlog::info("Monster isChampion: {0}", isChampion);
spdlog::info("Monster isUnique: {0}", isUnique);
spdlog::info("Monster isSuperUnique: {0}", isSuperUnique);
// You can add these details to the packet if needed
packet.isChampion = isChampion;
packet.isUnique = isUnique;
packet.isSuperUnique = isSuperUnique;
// if currentHP is 0, if is_champion, then set_stat for player and increment the player stat diablo2::UNIT_STAT_is_champion by 1
if (currentHp == 0) {
if (isChampion) {
// get the player is_champion stat
auto isChampionValue = diablo2::d2_common::get_stat(player, diablo2::UNIT_STAT_is_champion, 0);
diablo2::d2_common::set_stat(player, diablo2::UNIT_STAT_is_champion, isChampionValue + 1, 0);
MessageBoxA(NULL, "Champion killed", "Champion killed", MB_OK);
spdlog::info("Champion killed");
}
// do the if condition for isUnique and isSuperUnique here
if (isUnique) {
// get the player is_unique stat
auto isUniqueValue = diablo2::d2_common::get_stat(player, diablo2::UNIT_STAT_is_unique, 0);
diablo2::d2_common::set_stat(player, diablo2::UNIT_STAT_is_unique, isUniqueValue + 1, 0);
MessageBoxA(NULL, "Unique killed", "Unique killed", MB_OK);
spdlog::info("Unique killed");
}
if (isSuperUnique) {
// get the player is_super_unique stat
auto isSuperUniqueValue = diablo2::d2_common::get_stat(player, diablo2::UNIT_STAT_is_super_unique, 0);
diablo2::d2_common::set_stat(player, diablo2::UNIT_STAT_is_super_unique, isSuperUniqueValue + 1, 0);
MessageBoxA(NULL, "SuperUnique killed", "SuperUnique killed", MB_OK);
spdlog::info("SuperUnique killed");
}
}
}
}
}
*/
packet.unit_type = static_cast<uint8_t>(defender->type);
packet.guid = defender->guid;
packet.damage_type = get_damage_type(dmg);
@ -71,9 +127,9 @@ static void send_damage_data(diablo2::structures::unit* defender,
packet.currentHp = currentHp / 256;
packet.maxHp = maxHp / 256;
spdlog::info("currentHp: {0}", packet.currentHp);
spdlog::info("maxHp: {0}", packet.maxHp);
spdlog::info("damage: {0}", packet.damage);
//spdlog::info("currentHp: {0}", packet.currentHp);
//spdlog::info("maxHp: {0}", packet.maxHp);
//spdlog::info("damage: {0}", packet.damage);
if (packet.damage_type == d2_tweaks::common::DAMAGE_TYPE_UNKNOWN)
return;

View File

@ -10,6 +10,7 @@
#include <diablo2/structures/net_client.h>
#include <diablo2/structures/item_data.h>
#include <diablo2/structures/player_data.h>
#include <diablo2/structures/path.h>
#include <spdlog/spdlog.h>
@ -58,6 +59,10 @@ bool d2_tweaks::server::modules::item_move::handle_packet(diablo2::structures::g
const auto item = instance.get_server_unit(game, itemMove->item_guid, diablo2::structures::unit_type_t::UNIT_TYPE_ITEM); //0x4 = item
// Get player room
diablo2::structures::room* room = diablo2::d2_common::get_room_from_unit(player);
const auto record = diablo2::d2_common::get_item_record(item->data_record_index);
const char* itemcode = itemMove->item_code;
@ -81,7 +86,7 @@ bool d2_tweaks::server::modules::item_move::handle_packet(diablo2::structures::g
std::string bag_guid = std::to_string(itemMove->bag_guid);
//MessageBox(NULL, bag_guid.c_str(), "Bag GUID", MB_OK | MB_ICONINFORMATION);
D2PropertyStrc itemProperty = {};
diablo2::structures::D2PropertyStrc itemProperty = {};
itemProperty.nProperty = itemMove->prop; // Adjust the property ID
itemProperty.nLayer = 0;
itemProperty.nMin = itemMove->val;
@ -98,7 +103,7 @@ bool d2_tweaks::server::modules::item_move::handle_packet(diablo2::structures::g
diablo2::d2_game::D2GAME_Transmogrify_6FC4A660(game, player, item);
}
else if (itemMove->updateBag == 1) {
D2PropertyStrc itemProperty = {};
diablo2::structures::D2PropertyStrc itemProperty = {};
itemProperty.nProperty = itemMove->prop;
itemProperty.nLayer = 0;
itemProperty.nMin = itemMove->val;

View File

@ -39,6 +39,7 @@
#include <unordered_map>
#include <vector>
#include <CommCtrl.h> // Include for edit control
#include <d2tweaks/client/modules/loot_filter/loot_filter_settings_toggle_menu.h>
// Define a static variable to keep track of the last time the stash window was toggled
static std::chrono::steady_clock::time_point lastToggleTime;
@ -150,7 +151,7 @@ const char* ITEMS_armor_and_weapons[] = {
"pa8", "pa9", "paa", "ne6", "ne7", "ne8", "ne9", "nea", "drb", "drc",
"drd", "dre", "drf", "bab", "bac", "bad", "bae", "baf", "pab", "pac",
"pad", "pae", "paf", "neb", "neg", "ned", "nee", "nef", "tor", "ooc",
"eaq", "ebq", "ib1", "ib3", "aqv", "cqv"
"eaq", "ebq", "ib3", "aqv", "cqv"
// demon keys/chests
"dkr1", "dkr2", "dkr3", "dkr4", "dkr5", "da1", "db1", "dc1"
@ -158,7 +159,10 @@ const char* ITEMS_armor_and_weapons[] = {
"afr", "afy", "afp", "af0", "afx", "afh", "afq", "afj", "aft", "afi",
"afe", "afg", "afk", "ae7", "afn", "ae8", "afl", "ae9", "afv", "afz",
"af3", "af1", "afm", "af5", "afc", "afo", "afw", "afs", "af2", "afd",
"afb", "af4", "afu"
"afb", "af4", "afu",
// rings/amulets
"rin", "amu", "jew"
};
const char* ITEMS_gems_and_runes[] = {
@ -529,7 +533,7 @@ void sendPacketAndUpdateProperty(int gemBagGuid, uint32_t iCode, int prop, int v
packet.target_page = 99;
diablo2::d2_client::send_to_server(&packet, sizeof packet);
D2PropertyStrc itemProperty = {};
diablo2::structures::D2PropertyStrc itemProperty = {};
itemProperty.nProperty = prop - 3; // Adjust the property ID
itemProperty.nLayer = 0;
itemProperty.nMin = val;
@ -770,6 +774,7 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
// Check if the current page is the stash or inventory, right click on gem/rune will
// add it to the cube and send it to page 99 which is non existent
// (hope it doesn't bloat save file size and actualy disappears from memory)
/*
if (currentPage == 0 || currentPage == 4) {
// Check if the stash or inventory window is open
if (diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_STASH) ||
@ -785,7 +790,7 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
// Check if the code of the hovered item matches the current gem type
if (strncmp(normCode, key, 3) == 0) {
// Create a D2PropertyStrc structure to represent the gem property
D2PropertyStrc itemProperty = {};
diablo2::structures::D2PropertyStrc itemProperty = {};
itemProperty.nProperty = value.rowID - 3; // Adjust the property ID
itemProperty.nLayer = 0;
itemProperty.nMin = value.chippedCount;
@ -856,7 +861,7 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
// Check if the code of the hovered item matches the current gem type
if (strncmp(normCode, key, 3) == 0) {
// Create a D2PropertyStrc structure to represent the gem property
D2PropertyStrc itemProperty = {};
diablo2::structures::D2PropertyStrc itemProperty = {};
itemProperty.nProperty = value.rowID - 3; // Adjust the property ID
itemProperty.nLayer = 0;
itemProperty.nMin = value.chippedCount;
@ -977,6 +982,11 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
}
}
}
*/
// For armor and weapon codes, right click will move the item to the stash or cube and transmute
if (isArmorOrWeaponCode(normCode)
@ -1036,6 +1046,62 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
// Clear the hovered item after processing
(*reinterpret_cast<diablo2::structures::unit**>(diablo2::d2_client::get_base() + 0x1158F4)) = nullptr;
}
if (strncmp(normCode, "ib1", 3) == 0) {
// we need to get instance of loot_filter_settings_menu class singleton
auto& toggle_menu = singleton<d2_tweaks::client::modules::loot_filter_settings_toggle_menu>::instance();
toggle_menu.m_show = !toggle_menu.m_show;
m_stats_enabled = !m_stats_enabled;
toggle_menu.m_filter_settings_menu->set_enabled(toggle_menu.m_show);
toggle_menu.m_filter_settings_menu->set_visible(toggle_menu.m_show);
}
if (strncmp(normCode, "r01", 3) == 0) {
auto localPlayer = diablo2::d2_client::get_local_player();
diablo2::structures::path* playerPath = localPlayer->path;
//diablo2::structures::room* pRoom = playerPath->pt_room;
//diablo2::structures::game* pGame = player->game;
//struct D2UnkMonCreateStrc
//{
// diablo2::structures::game* pGame; //0x00
// diablo2::structures::room* pRoom; //0x04
// DWORD pRoomCoordList; //0x08
// int32_t nMonsterId; //0x0C
// int32_t nAnimMode; //0x10
// int32_t nUnitGUID; //0x14
// int32_t nX; //0x18
// int32_t nY; //0x1C
// int32_t field_20; //0x20
// int16_t nFlags; //0x24
//};
//auto nX = playerPath->mapx + 50;
//auto nY = playerPath->mapy + 50;
////auto nMonsterId = 1272;
////int32_t nMode = 1;
////auto rubyGolem = diablo2::d2_game::D2GAME_SpawnMonster_6FC69F10(pGame, pRoom, nX, nY, nMonsterId, nMode, -1, 0);
//// Create a packet to move an item
//static d2_tweaks::common::item_move_cs packet;
//packet.item_guid = g_hoverItem->guid;
//packet.item_code = normCode;
//packet.target_page = 99;
//packet.summon = 1;
//packet.x = nX;
//packet.y = nY;
//diablo2::d2_client::send_to_server(&packet, sizeof packet);
//diablo2::d2_common::inv_remove_item(player->inventory, g_hoverItem);
//// Clear the hovered item after processing
//(*reinterpret_cast<diablo2::structures::unit**>(diablo2::d2_client::get_base() + 0x1158F4)) = nullptr;
}
}
block = instance.process_right_mouse(false);
@ -1200,7 +1266,7 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
}
if (strncmp(normCode, "rvl", 3) == 0) {
// Create the packet
sendPacketAndUpdateProperty(gemBagGuid, 'rvl ', 396, 5000, g_hoverItem->guid, gemBag);
sendPacketAndUpdateProperty(gemBagGuid, 'rvl ', 396, 3000, g_hoverItem->guid, gemBag);
diablo2::d2_common::inv_remove_item(player->inventory, g_hoverItem);
}
@ -1295,7 +1361,7 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
diablo2::d2_common::inv_remove_item(player->inventory, g_hoverItem);
}
char currentPage;
const char* key;
// Iterate through each gem type in the gemTypes map
for (const auto& gem : gemTypes) {
@ -1308,7 +1374,7 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
// Check if the code of the hovered item matches the current gem type
if (strncmp(normCode, key, 3) == 0) {
// Create a D2PropertyStrc structure to represent the gem property
D2PropertyStrc itemProperty = {};
diablo2::structures::D2PropertyStrc itemProperty = {};
itemProperty.nProperty = value.rowID - 3; // Adjust the property ID
itemProperty.nLayer = 0;
itemProperty.nMin = value.chippedCount;

View File

@ -244,8 +244,8 @@ void diablo2::d2_common::update_trade(structures::inventory* inventory, structur
// set_item_flags(item, dwFlag, bSet);
//}
void diablo2::d2_common::add_property(structures::unit* item, D2PropertyStrc* prop, int nUnused) {
static wrap_func_std_import<void(structures::unit* item, D2PropertyStrc* prop, int nUnused)> add_property(10868, get_base());
void diablo2::d2_common::add_property(structures::unit* item, diablo2::structures::D2PropertyStrc* prop, int nUnused) {
static wrap_func_std_import<void(structures::unit* item, diablo2::structures::D2PropertyStrc* prop, int nUnused)> add_property(10868, get_base());
add_property(item, prop, nUnused);
}
@ -289,3 +289,5 @@ diablo2::structures::items_line* diablo2::d2_common::get_items_txt_record(int nI
static wrap_func_std_import<diablo2::structures::items_line* (int)> get_items_txt_record(10600, get_base());
return get_items_txt_record(nItemId);
}

View File

@ -3,6 +3,12 @@
#include <diablo2/structures/npc_record.h>
#include <common/ptr_wrapper.h>
DWORD D2GAME_BASE = 0x6FC30000;
DWORD D2GAME_GetOffset(DWORD offset) {
return offset - D2GAME_BASE;
}
char* diablo2::d2_game::get_base() {
static auto base = reinterpret_cast<char*>(GetModuleHandle("d2game.dll"));
return base;
@ -158,3 +164,105 @@ diablo2::structures::unit* __fastcall diablo2::d2_game::QUESTS_CreateItem(diablo
static wrap_func_fast< diablo2::structures::unit* (diablo2::structures::game*, diablo2::structures::unit*, uint32_t, int32_t, uint8_t, int32_t)>QUESTS_CreateItem(0x65DF0, get_base());
return QUESTS_CreateItem(pGame, pPlayer, dwCode, nLevel, nQuality, bDroppable);
}
// Add wrapper for D2Game.0x6FC603D0
// D2MonPropTxt* __fastcall MONSTER_GetMonPropTxtRecord(int32_t nId)
diablo2::structures::D2MonPropTxt* __fastcall diablo2::d2_game::MONSTER_GetMonPropTxtRecord(int32_t nId) {
static wrap_func_fast<diablo2::structures::D2MonPropTxt* (int32_t)>MONSTER_GetMonPropTxtRecord(0x303D0, get_base());
return MONSTER_GetMonPropTxtRecord(nId);
}
// add wrapper for //D2Game.0x6FCBC900
// D2UnitStrc* __stdcall SUNIT_GetTargetUnit(D2GameStrc* pGame, D2UnitStrc* pUnit)
diablo2::structures::unit* __stdcall diablo2::d2_game::SUNIT_GetTargetUnit(structures::game* pGame, structures::unit* pUnit) {
static wrap_func_std<diablo2::structures::unit* (diablo2::structures::game*, diablo2::structures::unit*)>SUNIT_GetTargetUnit(0x8C900, get_base());
return SUNIT_GetTargetUnit(pGame, pUnit);
}
//D2Game.0x6FCF5B90
//D2SkillsTxt* __fastcall SKILLS_GetSkillsTxtRecord(int32_t nSkillId)
diablo2::structures::D2SkillsTxt* __fastcall diablo2::d2_game::SKILLS_GetSkillsTxtRecord(int32_t nSkillId) {
static wrap_func_fast<diablo2::structures::D2SkillsTxt* (int32_t)>SKILLS_GetSkillsTxtRecord(0xC5B90, get_base());
return SKILLS_GetSkillsTxtRecord(nSkillId);
}
//D2Game.0x6FD15580
// int32_t __fastcall D2GAME_GetSummonIdFromSkill_6FD15580(D2UnitStrc* pUnit, int32_t bFromMonster, int32_t nSkillId, int32_t nSkillLevel, int32_t* pSpawnMode, int32_t* pX, int32_t* pY)
int32_t __fastcall diablo2::d2_game::D2GAME_GetSummonIdFromSkill_6FD15580(diablo2::structures::unit* pUnit, int32_t bFromMonster, int32_t nSkillId, int32_t nSkillLevel, int32_t* pSpawnMode, int32_t* pX, int32_t* pY) {
static wrap_func_fast<int32_t(diablo2::structures::unit*, int32_t, int32_t, int32_t, int32_t*, int32_t*, int32_t*)>D2GAME_GetSummonIdFromSkill_6FD15580(0xE5580, get_base());
return D2GAME_GetSummonIdFromSkill_6FD15580(pUnit, bFromMonster, nSkillId, nSkillLevel, pSpawnMode, pX, pY);
}
//D2Game.0x6FD14430
//D2UnitStrc* __fastcall D2GAME_SummonPet_6FD14430(D2GameStrc* pGame, D2SummonArgStrc* pSummonArg)
diablo2::structures::unit* __fastcall diablo2::d2_game::D2GAME_SummonPet_6FD14430(diablo2::structures::game* pGame, diablo2::structures::D2SummonArgStrc* pSummonArg) {
static wrap_func_fast<diablo2::structures::unit* (diablo2::structures::game*, diablo2::structures::D2SummonArgStrc*)>D2GAME_SummonPet_6FD14430(0xE4430, get_base());
return D2GAME_SummonPet_6FD14430(pGame, pSummonArg);
}
//D2Game.0x6FD0CB10
//int32_t __fastcall D2GAME_SKILLS_SetSummonBaseStats_6FD0CB10(D2GameStrc* pGame, D2UnitStrc* pUnit, D2UnitStrc* pPet, int32_t nPetLevelArg, int32_t nSkillLevel)
int32_t __fastcall diablo2::d2_game::D2GAME_SKILLS_SetSummonBaseStats_6FD0CB10(diablo2::structures::game* pGame, diablo2::structures::unit* pUnit, diablo2::structures::unit* pPet, int32_t nPetLevelArg, int32_t nSkillLevel) {
static wrap_func_fast<int32_t(diablo2::structures::game*, diablo2::structures::unit*, diablo2::structures::unit*, int32_t, int32_t)>D2GAME_SKILLS_SetSummonBaseStats_6FD0CB10(D2GAME_GetOffset(0x6FD0CB10), get_base());
return D2GAME_SKILLS_SetSummonBaseStats_6FD0CB10(pGame, pUnit, pPet, nPetLevelArg, nSkillLevel);
}
//D2Game.0x6FD0C530
//int32_t __fastcall D2GAME_SetSummonPassiveStats_6FD0C530(D2GameStrc* pGame, D2UnitStrc* pUnit, D2UnitStrc* pPet, int32_t nSkillId, int32_t nSkillLevel, int32_t nItemLevel)
// use D2GAME_GetOffset(0x6FD0C530)
int32_t __fastcall diablo2::d2_game::D2GAME_SetSummonPassiveStats_6FD0C530(diablo2::structures::game* pGame, diablo2::structures::unit* pUnit, diablo2::structures::unit* pPet, int32_t nSkillId, int32_t nSkillLevel, int32_t nItemLevel) {
static wrap_func_fast<int32_t(diablo2::structures::game*, diablo2::structures::unit*, diablo2::structures::unit*, int32_t, int32_t, int32_t)>D2GAME_SetSummonPassiveStats_6FD0C530(D2GAME_GetOffset(0x6FD0C530), get_base());
return D2GAME_SetSummonPassiveStats_6FD0C530(pGame, pUnit, pPet, nSkillId, nSkillLevel, nItemLevel);
}
//D2Game.0x6FD0C2E0
//void __fastcall D2GAME_SetSummonResistance_6FD0C2E0(D2UnitStrc* pUnit, D2UnitStrc* pPet)
void __fastcall diablo2::d2_game::D2GAME_SetSummonResistance_6FD0C2E0(diablo2::structures::unit* pUnit, diablo2::structures::unit* pPet) {
static wrap_func_fast<void(diablo2::structures::unit*, diablo2::structures::unit*)>D2GAME_SetSummonResistance_6FD0C2E0(D2GAME_GetOffset(0x6FD0C2E0), get_base());
D2GAME_SetSummonResistance_6FD0C2E0(pUnit, pPet);
}
//D2Game.0x6FC3E200
//void __fastcall sub_6FC3E200(D2ClientStrc* pClient, D2UnitStrc* pUnit)
void __fastcall diablo2::d2_game::sub_6FC3E200(diablo2::structures::net_client* pClient , diablo2::structures::unit* pUnit) {
static wrap_func_fast<void(diablo2::structures::net_client*, diablo2::structures::unit*)>sub_6FC3E200(D2GAME_GetOffset(0x6FC3E200), get_base());
sub_6FC3E200(pClient, pUnit);
}
//D2Game.0x6FC69F10
//D2UnitStrc* __fastcall D2GAME_SpawnMonster_6FC69F10(D2GameStrc* pGame, D2ActiveRoomStrc* pRoom, int32_t nX, int32_t nY, int32_t nMonsterId, int32_t nAnimMode, int32_t a7, int16_t nFlags)
diablo2::structures::unit* __fastcall diablo2::d2_game::D2GAME_SpawnMonster_6FC69F10(diablo2::structures::game* pGame, diablo2::structures::room* pRoom, int32_t nX, int32_t nY, int32_t nMonsterId, int32_t nAnimMode, int32_t a7, int16_t nFlags) {
static wrap_func_fast<diablo2::structures::unit* (diablo2::structures::game*, diablo2::structures::room*, int32_t, int32_t, int32_t, int32_t, int32_t, int16_t)>D2GAME_SpawnMonster_6FC69F10(D2GAME_GetOffset(0x6FC69F10), get_base());
return diablo2::d2_game::D2GAME_SpawnMonster_6FC69F10(pGame, pRoom, nX, nY, nMonsterId, nAnimMode, a7, nFlags);
}