Skip to content

Commit

Permalink
Implemented the Deal with the Devil statistic.
Browse files Browse the repository at this point in the history
Bumped version number to 1.1
  • Loading branch information
networkMe committed Sep 23, 2015
1 parent 3a73448 commit 79ad316
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/LoaderGUI.ui
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
<number>1</number>
</property>
<property name="text">
<string>&lt;a href=&quot;https://github.com/networkMe/missinghud2/releases&quot;&gt;v1.0.0&lt;/a&gt;</string>
<string>&lt;a href=&quot;https://github.com/networkMe/missinghud2/releases&quot;&gt;v1.1.0&lt;/a&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
Expand Down
6 changes: 3 additions & 3 deletions src/dll/HUDOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void HUDOverlay::DrawHUD(HDC hdc)
HUDStat luck_stat(MHUDSTAT::kStat_Luck);
luck_stat.Draw(base_hud_stats_menu, mem_reader->GetPlayerStatf(RebirthPlayerStat::kLuck));

//base_hud_stats_menu.y -= 0.1f;
//HUDStat dwd_stat(MHUDSTAT::kStat_DealWithDevil);
//dwd_stat.Draw(base_hud_stats_menu, mem_reader->GetPlayerStati(RebirthPlayerStat::kDealWithDevil));
base_hud_stats_menu.y -= 0.1f;
HUDStat dwd_stat(MHUDSTAT::kStat_DealWithDevil);
dwd_stat.Draw(base_hud_stats_menu, mem_reader->GetPlayerStatf(RebirthPlayerStat::kDealWithDevil), true);
}
100 changes: 99 additions & 1 deletion src/dll/RebirthMemReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ bool RebirthMemReader::IsRunActive()

float RebirthMemReader::GetPlayerStatf(RebirthPlayerStat player_stat)
{
if (player_stat == RebirthPlayerStat::kDealWithDevil)
{
return GetDealWithDevilChance();
}

DWORD player_class = GetPlayerMemAddr();
if (player_class == 0)
return 0.0f;
Expand All @@ -81,6 +86,91 @@ int RebirthMemReader::GetPlayerStati(RebirthPlayerStat player_stat)
return stat_val;
}

float RebirthMemReader::GetDealWithDevilChance()
{
DWORD player_manager_inst = GetPlayerManagerMemAddr();
if (player_manager_inst == 0)
return 0.0f;

int current_floor = *((int*)player_manager_inst);
if (current_floor == 7 || current_floor > 8) // In-eligible for natural DWD on these floors (even with Goat Head)
return 0.0f;

DWORD player = GetPlayerMemAddr();
if (*((DWORD*)(player + PASSIVE_ITEM_GOATHEAD)) == 1) // Goat Head is a guaranteed DWD (100%)
return 1.0f;

float dwd_chance = 0.01f; // Default 1% chance

if (*((DWORD*)(player + PASSIVE_ITEM_PENTAGRAM)) == 1) // Pentagram adds 20% chance
dwd_chance += 0.20f;

if (*((DWORD*)(player + PASSIVE_ITEM_BLACKCANDLE)) == 1) // Black Candle adds 30% chance
dwd_chance += 0.30f;

DWORD player_active_item = *((DWORD*)(player + ITEM_ACTIVE_SLOT));
if (player_active_item == ACTIVE_ITEM_BOOKOFREVELATIONS) // Holding Book of Revelations adds 35% chance
dwd_chance += 0.35f;
else if (player_active_item == ACTIVE_ITEM_BOOKOFBELIAL) // Holding Book of Belial adds 2500% chance
dwd_chance += 25.00f;

BYTE floor_flag = *((BYTE*)(player_manager_inst + PLAYER_MANAGER_FLOOR_FLAGS));
if (floor_flag & 1) // Killing a normal beggar adds 35% chance
dwd_chance += 0.35f;

DWORD floor_flags = *((DWORD*)(player_manager_inst + PLAYER_MANAGER_FLOOR_FLAGS));
if (((floor_flags >> 2) & 1) <= 0) // Not taking red heart damage on the entire floor adds 99% chance
dwd_chance += 0.99f;
if (((floor_flags >> 6) & 1) > 0) // Blowing up a dead shopkeeper adds 10% chance
dwd_chance += 0.10f;

// Not taking damage from the floor's boss room adds 35% chance to DWD chance
DWORD current_room = GetCurrentRoom();
DWORD boss_room = *((DWORD*)(player_manager_inst + PLAYER_MANAGER_BOSS_ROOM_CODE));
if (current_room == boss_room)
{
DWORD boss_fight = *((DWORD*)(player_manager_inst + PLAYER_MANAGER_FLOOR_BOSS_FIGHT));
BYTE boss_dmg_flag = *((BYTE*)(boss_fight + BOSS_FIGHT_TOOK_RED_DMG));
if (boss_dmg_flag == 1)
boss_fight_took_dmg_ = true;
}
else
{
if (current_floor > current_floor_)
{
// This method brings a bug where if a player restarts on the first floor
// after taking damage to the boss, they will not get back the +35% boss fight chance until
// they go down to Basement/Cellar II.
// Complicated to rectify and only minor.
boss_fight_took_dmg_ = false;
current_floor_ = current_floor;
}
}

if (!boss_fight_took_dmg_) // Not taking damage from the boss fight adds 35% chance
dwd_chance += 0.35f;


DWORD devil_deal_prev_floor = *((DWORD*)(player_manager_inst + PLAYER_MANAGER_DEVILDEAL_PREV_FLOOR));
if (devil_deal_prev_floor > 0 && devil_deal_prev_floor != current_floor)
{
int devil_deal_num_floors_ago = current_floor_ - (int)devil_deal_prev_floor;
if (devil_deal_num_floors_ago < 2)
{
dwd_chance *= 0.25f; // Player has seen a Deal with Devil door less than 2 floors ago, reduce overall chance by 75%
}
else if (devil_deal_num_floors_ago == 2)
{
dwd_chance *= 0.5f; // Player has seen a Deal with Devil door 2 floors ago, reduce overall chance by 50%
}
}

if (dwd_chance > 1.00f)
dwd_chance = 1.00f;

return dwd_chance;
}

DWORD RebirthMemReader::GetPlayerManagerMemAddr()
{
DWORD player_manager_inst = *((DWORD*)(player_manager_inst_p_addr_));
Expand Down Expand Up @@ -115,6 +205,14 @@ DWORD RebirthMemReader::GetPlayerMemAddr()
return *((DWORD*)player_p);
}

DWORD RebirthMemReader::GetCurrentRoom()
{
DWORD player_manager_inst = GetPlayerManagerMemAddr();
DWORD room_code = *((DWORD*)(player_manager_inst + PLAYER_MANAGER_ROOM_CODE));
DWORD room_num = *((DWORD*)(player_manager_inst + (room_code * 4) + 0x5AC4));
return room_num;
}

void RebirthMemReader::GetRebirthModuleInfo()
{
// Get the base address of the Rebirth module
Expand Down Expand Up @@ -179,4 +277,4 @@ std::vector<unsigned char> RebirthMemReader::SearchMemForVal(MemSig mem_sig)
}

return val_bytes;
}
}
25 changes: 24 additions & 1 deletion src/dll/RebirthMemReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@

#define ISAAC_MODULE_NAME "isaac-ng.exe"

#define ITEM_ACTIVE_SLOT 0xCC8
#define ACTIVE_ITEM_BOOKOFREVELATIONS 0x4E
#define ACTIVE_ITEM_BOOKOFBELIAL 0x22

#define PASSIVE_ITEM_PENTAGRAM 0xE38
#define PASSIVE_ITEM_GOATHEAD 0x10C8
#define PASSIVE_ITEM_BLACKCANDLE 0x117C

#define PLAYER_MANAGER_FLOOR_FLAGS 0x5DC0
#define PLAYER_MANAGER_FLOOR_BOSS_FIGHT 0x5D98
#define PLAYER_MANAGER_ROOM_CODE 0x5D9C
#define PLAYER_MANAGER_BOSS_ROOM_CODE 0x5DA4
#define PLAYER_MANAGER_DEVILDEAL_PREV_FLOOR 0x10D7E8

#define BOSS_FIGHT_TOOK_RED_DMG 0xE8C

// These values are the offsets of the specific statistic from the core Player memory address
enum RebirthPlayerStat {
kSpeed = 0xCB4,
Expand All @@ -32,7 +48,7 @@ enum RebirthPlayerStat {
kShotSpeed = 0xBE4,
kDamage = 0xBF0,
kLuck = 0xCB8,
kDealWithDevil = 0x10C8 // This is for a Goathead guranteed DWD, actual DWD chance is much more complicated
kDealWithDevil = 0xFFFFFFFF // An advanced function is required for this statistic
};

class RebirthMemReader
Expand All @@ -58,6 +74,10 @@ class RebirthMemReader
DWORD GetPlayerListMemAddr();
DWORD GetPlayerMemAddr();

float GetDealWithDevilChance();

DWORD GetCurrentRoom();

private:
static RebirthMemReader* mem_reader_;

Expand All @@ -66,6 +86,9 @@ class RebirthMemReader

DWORD player_manager_inst_p_addr_ = 0;
DWORD player_manager_player_list_offset_ = 0;

int current_floor_ = 0;
bool boss_fight_took_dmg_ = false;
};


Expand Down

0 comments on commit 79ad316

Please sign in to comment.