mirror of
https://gitlab.com/hashborgir/plugy.git
synced 2024-10-05 17:16:03 +00:00
520 lines
17 KiB
C++
520 lines
17 KiB
C++
/*=================================================================
|
|
File created by Yohann NICOLAS.
|
|
Add support 1.13d by L'Autour.
|
|
Add support 1.14d by haxifix.
|
|
|
|
Uber Quest Management.
|
|
|
|
=================================================================*/
|
|
|
|
#include <math.h>
|
|
#include "uberQuest.h"
|
|
#include "common.h"
|
|
|
|
#define OBJECT_PERMANENT_PORTAL 0x3C
|
|
#define LEVEL_ACT5TOWN 109
|
|
#define LEVEL_ACT5_PANDEMONIUM1 133
|
|
#define LEVEL_ACT5_PANDEMONIUM2 134
|
|
#define LEVEL_ACT5_PANDEMONIUM3 135
|
|
#define LEVEL_ACT5_PANDEMONIUM_FINAL 136
|
|
|
|
#define UBER_IZUAL_ID 706
|
|
#define UBER_ANDARIEL_ID 707
|
|
#define UBER_DURIEL_ID 708
|
|
#define UBER_MEPHISTO_ID 704
|
|
#define UBER_DIABLO_ID 705
|
|
#define UBER_BAAL_ID 709
|
|
|
|
#define UBER_MEPHISTO_SQUELETON 725
|
|
#define UBER_MEPHISTO_ARCHER 726
|
|
#define UBER_MEPHISTO_FIRE 727
|
|
#define UBER_MEPHISTO_LIGHTNING 728
|
|
#define UBER_MEPHISTO_COLD 729
|
|
#define UBER_MEPHISTO_POISON 730
|
|
#define UBER_BAAL_DARK_LORD 731
|
|
#define UBER_BAAL_SPECTER 732
|
|
#define UBER_DIABLO_PIT_LORD 711
|
|
|
|
|
|
bool active_UberQuest = false;
|
|
DWORD UberMephistoX = 25130;
|
|
DWORD UberMephistoY = 5143;
|
|
DWORD UberDiabloX = 25139;
|
|
DWORD UberDiabloY = 5139;
|
|
DWORD UberBaalX = 25139;
|
|
DWORD UberBaalY = 5135;
|
|
|
|
bool active_UberMinions = true;
|
|
DWORD UberMephistoNbMinions = 6;
|
|
DWORD UberMephistoMinions[] = {UBER_MEPHISTO_SQUELETON, UBER_MEPHISTO_ARCHER, UBER_MEPHISTO_FIRE, UBER_MEPHISTO_LIGHTNING, UBER_MEPHISTO_COLD, UBER_MEPHISTO_POISON};
|
|
int UberMephistoSpawnPercent = 80;
|
|
DWORD UberMephistoSpawnRadius = 30;
|
|
DWORD UberBaalNbMinions = 2;
|
|
DWORD UberBaalMinions[] = {UBER_BAAL_DARK_LORD, UBER_BAAL_SPECTER};
|
|
int UberBaalSpawnPercent = 30;
|
|
DWORD UberBaalSpawnRadius = 30;
|
|
DWORD UberDiabloNbMinions = 1;
|
|
DWORD UberDiabloMinions[] = {UBER_DIABLO_PIT_LORD};
|
|
int UberDiabloSpawnPercent = 30;
|
|
DWORD UberDiabloSpawnRadius = 30;
|
|
|
|
bool active_UberDiabloRushTweekAI = false;
|
|
bool active_UberBaalTeleportTweekAI = false;
|
|
bool active_UberBaalChillingArmorTweekAI = false;
|
|
int uberBaalChillingArmorTimer = 6000;
|
|
|
|
int uberBaalChillingArmorLastFrame = 0;
|
|
|
|
static struct
|
|
{
|
|
union{
|
|
DWORD all;
|
|
struct{
|
|
DWORD portal1Opened:1;
|
|
DWORD portal2Opened:1;
|
|
DWORD portal3Opened:1;
|
|
DWORD portal4Opened:1;
|
|
DWORD uber1Spawned:1;
|
|
DWORD uber2Spawned:1;
|
|
DWORD uber3Spawned:1;
|
|
DWORD uber4Spawned:1;
|
|
DWORD uber5Spawned:1;
|
|
DWORD uber6Spawned:1;
|
|
};
|
|
};
|
|
int count1;
|
|
int count2;
|
|
int count3;
|
|
} questState;
|
|
|
|
|
|
int GetNbMonsters(Level* level, Position position, int radius);
|
|
int GetNbMonsters(Level* level);
|
|
|
|
bool IsInRoom(Room* ptRoom, DWORD x, DWORD y)
|
|
{
|
|
DWORD startX = version_D2Game > V112 ? ptRoom->startX : *((DWORD*)ptRoom + 6);
|
|
DWORD startY = version_D2Game > V112 ? ptRoom->startY : *((DWORD*)ptRoom + 7);
|
|
DWORD sizeX = version_D2Game > V112 ? ptRoom->sizeX : *((DWORD*)ptRoom + 8);
|
|
DWORD sizeY = version_D2Game > V112 ? ptRoom->sizeY : *((DWORD*)ptRoom + 9);
|
|
return x >= startX && x <= startX + sizeX &&
|
|
y >= startY && y <= startY + sizeY;
|
|
}
|
|
|
|
double Distance(Position p1, Position p2)
|
|
{
|
|
return sqrt((double)(p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
|
|
}
|
|
|
|
void resetQuestState()
|
|
{
|
|
ZeroMemory(&questState,sizeof(questState));
|
|
questState.count1 = 10 + RANDOM(10);
|
|
questState.count2 = 20 + RANDOM(40);
|
|
questState.count3 = 10 + RANDOM(20);
|
|
uberBaalChillingArmorLastFrame = 0;
|
|
log_msg("Uber Quest State : %d %d %d\n",questState.count1, questState.count2, questState.count3);
|
|
}
|
|
|
|
DWORD openPortalOnLevel(Game* ptGame, Unit* ptChar, DWORD levelID)
|
|
{
|
|
log_msg("Open portal to level %d\n", levelID);
|
|
Room* ptRoom = D2GetRoom(ptChar);
|
|
if ( D2GetLevelID(ptRoom) != LEVEL_ACT5TOWN ) return 0;
|
|
|
|
//Get position in the room
|
|
Position pos;
|
|
D2GetPosition(ptChar, &pos);
|
|
log_msg("ptChar pos : %d %d\n", pos.x, pos.y);
|
|
|
|
if (!D2GetDropRoom(ptRoom, &pos, &pos, 3, 0x3E01, 0xC01, 0)) return 0;
|
|
ptRoom = D2TestPositionInRoom(ptRoom, pos.x, pos.y);
|
|
if (!ptRoom) return 0;
|
|
|
|
// Create Portal
|
|
Unit* ptPortal = D2CreateUnit(UNIT_OBJECT, OBJECT_PERMANENT_PORTAL, pos.x, pos.y, ptGame, ptRoom, 1, 1, 0);
|
|
ptPortal->ptObjectData->levelID = (BYTE)levelID;
|
|
D2Common10572(ptPortal, 1);
|
|
D2LinkPortal(ptGame, ptPortal, levelID, LEVEL_ACT5TOWN);
|
|
D2SetObjectFlags(ptPortal, D2GetObjectFlags(ptPortal) | 3);
|
|
D2Common11084(ptRoom, 0);
|
|
D2Common11084(D2GetRoom(ptPortal), 0);
|
|
|
|
return 1;
|
|
}
|
|
|
|
DWORD FASTCALL openPandPortal(Game* ptGame, Unit* ptChar)
|
|
{
|
|
log_msg("openPandPortal\n");
|
|
|
|
if (ptGame->difficultyLevel != D2DM_HELL)
|
|
return 0;
|
|
|
|
int available[3];
|
|
int nbAvailable=0;
|
|
if (!questState.portal1Opened) available[nbAvailable++]=LEVEL_ACT5_PANDEMONIUM1;
|
|
if (!questState.portal2Opened) available[nbAvailable++]=LEVEL_ACT5_PANDEMONIUM2;
|
|
if (!questState.portal3Opened) available[nbAvailable++]=LEVEL_ACT5_PANDEMONIUM3;
|
|
int selectedTargetLevel;
|
|
if (nbAvailable)
|
|
selectedTargetLevel = available[RANDOM(nbAvailable)];
|
|
else selectedTargetLevel = LEVEL_ACT5_PANDEMONIUM1 + RANDOM(3);
|
|
|
|
int ret = openPortalOnLevel(ptGame, ptChar, selectedTargetLevel);
|
|
|
|
if (ret)
|
|
{
|
|
if (selectedTargetLevel == LEVEL_ACT5_PANDEMONIUM1) questState.portal1Opened = 1;
|
|
else if (selectedTargetLevel == LEVEL_ACT5_PANDEMONIUM2) questState.portal2Opened = 1;
|
|
else if (selectedTargetLevel == LEVEL_ACT5_PANDEMONIUM3) questState.portal3Opened = 1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
DWORD FASTCALL openPandFinalPortal(Game* ptGame, Unit* ptChar)
|
|
{
|
|
log_msg("openPandFinalPortal\n");
|
|
|
|
if (ptGame->difficultyLevel != D2DM_HELL)
|
|
return 0;
|
|
|
|
return openPortalOnLevel(ptGame, ptChar, LEVEL_ACT5_PANDEMONIUM_FINAL);
|
|
}
|
|
|
|
void STDCALL spawnUber(Game* ptGame, Room* ptRoom)
|
|
{
|
|
log_msg("Uber Quest State : %d %d %d\n",questState.count1, questState.count2, questState.count3);
|
|
log_msg("Uber Quest questState spawn : %d %d %d %d %d %d\n",questState.uber1Spawned, questState.uber2Spawned, questState.uber3Spawned, questState.uber4Spawned, questState.uber5Spawned, questState.uber6Spawned);
|
|
switch(D2GetLevelID(ptRoom))
|
|
{
|
|
case LEVEL_ACT5_PANDEMONIUM1:
|
|
if (!questState.uber1Spawned)
|
|
{
|
|
if (questState.count1) questState.count1--;
|
|
else {
|
|
if (D2SpawnSuperUnique(ptGame, ptRoom, 0, 0, 0, -1, UBER_ANDARIEL_ID, 0))
|
|
questState.uber1Spawned = 1;
|
|
}
|
|
}
|
|
break;
|
|
case LEVEL_ACT5_PANDEMONIUM2:
|
|
if (!questState.uber2Spawned)
|
|
{
|
|
if (questState.count2) questState.count2--;
|
|
else {
|
|
if (D2SpawnSuperUnique(ptGame, ptRoom, 0, 0, 0, -1, UBER_DURIEL_ID, 0))
|
|
questState.uber2Spawned = 1;
|
|
}
|
|
}
|
|
break;
|
|
case LEVEL_ACT5_PANDEMONIUM3:
|
|
if (!questState.uber3Spawned)
|
|
{
|
|
if (questState.count3) questState.count3--;
|
|
else {
|
|
if (D2SpawnSuperUnique(ptGame, ptRoom, 0, 0, 0, -1, UBER_IZUAL_ID, 0))
|
|
questState.uber3Spawned = 1;
|
|
}
|
|
}
|
|
break;
|
|
case LEVEL_ACT5_PANDEMONIUM_FINAL:
|
|
if (!questState.uber4Spawned)
|
|
{
|
|
log_msg("Spawn Mephisto ptRoom: startX:%d - startY:%d / x:%d y:%d\n", ptRoom->startX, ptRoom->startY, ptRoom->sizeX, ptRoom->sizeY);
|
|
if (IsInRoom(ptRoom, UberMephistoX, UberMephistoY))
|
|
{
|
|
log_msg("Spawn Mephisto ptRoom: startX:%d - startY:%d / x:%d y:%d\n", ptRoom->startX, ptRoom->startY, ptRoom->sizeX, ptRoom->sizeY);
|
|
if (D2SpawnSuperUnique(ptGame, ptRoom, 0, UberMephistoX, UberMephistoY, -1, UBER_MEPHISTO_ID, 0))
|
|
questState.uber4Spawned = 1;
|
|
}
|
|
}
|
|
if (!questState.uber5Spawned)
|
|
{
|
|
if (IsInRoom(ptRoom, UberDiabloX, UberDiabloY))
|
|
{
|
|
log_msg("Spawn Diablo ptRoom: startX:%d - startY:%d / x:%d y:%d\n", ptRoom->startX, ptRoom->startY, ptRoom->sizeX, ptRoom->sizeY);
|
|
if (D2SpawnSuperUnique(ptGame, ptRoom, 0, UberDiabloX, UberDiabloY, -1, UBER_DIABLO_ID, 0))
|
|
questState.uber4Spawned = 1;
|
|
}
|
|
}
|
|
if (!questState.uber6Spawned)
|
|
{
|
|
if (IsInRoom(ptRoom, UberBaalX, UberBaalY))
|
|
{
|
|
log_msg("Spawn Baal ptRoom: startX:%d - startY:%d / x:%d y:%d\n", ptRoom->startX, ptRoom->startY, ptRoom->sizeX, ptRoom->sizeY);
|
|
if (D2SpawnSuperUnique(ptGame, ptRoom, 0, UberBaalX, UberBaalY, -1, UBER_BAAL_ID, 0))
|
|
questState.uber4Spawned = 1;
|
|
}
|
|
}
|
|
}
|
|
D2Game235C0(ptGame, ptRoom);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
int GetNbMonsters(Level* level)
|
|
{
|
|
int nbMonsters = 0;
|
|
for (RoomEx* roomEx = level->ptFirstRoomEx; roomEx; roomEx = roomEx->ptNextRoomEx)
|
|
{
|
|
if (roomEx->ptRoom)
|
|
{
|
|
for (Unit* unit = roomEx->ptRoom->ptFirstUnit; unit; unit = unit->ptNextUnitInRoom)
|
|
{
|
|
if (unit->nUnitType == UNIT_MONSTER && unit->mode != UNIT_MODE_KICK && unit->nTxtFileNo != 711)
|
|
{
|
|
//log_msg("GetNbMonsters ++ / type:%d - id:%d - mode:%d\n", unit->nUnitType, unit->nTxtFileNo, unit->mode);
|
|
nbMonsters++;
|
|
}
|
|
//else log_msg("GetNbMonsters no / type:%d - id:%d - mode:%d\n", unit->nUnitType, unit->nTxtFileNo, unit->mode);
|
|
}
|
|
}
|
|
}
|
|
return nbMonsters;
|
|
}
|
|
|
|
int GetNbMonsters(Level* level, Position position, int radius)
|
|
{
|
|
int nbMonsters = 0;
|
|
for (RoomEx* roomEx = level->ptFirstRoomEx; roomEx; roomEx = roomEx->ptNextRoomEx)
|
|
{
|
|
if (roomEx->ptRoom)
|
|
{
|
|
for (Unit* unit = roomEx->ptRoom->ptFirstUnit; unit; unit = unit->ptNextUnitInRoom)
|
|
{
|
|
if (unit->nUnitType == UNIT_MONSTER && unit->mode != UNIT_MODE_KICK && unit->nTxtFileNo != 711)
|
|
{
|
|
Position p;
|
|
D2GetPosition(unit, &p);
|
|
if (Distance(position, p) <= radius)
|
|
nbMonsters++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return nbMonsters;
|
|
}
|
|
|
|
bool CastSummonMonster(Game* ptGame, Unit* ptMonster, DWORD x, DWORD y, DWORD* minions, int minionsSize, int mode)
|
|
{
|
|
DWORD minionId = minions[RANDOM(minionsSize)];
|
|
log_msg("CastSummonMonster: id:%d x:%d y:%d mode:%d\n", minionId, x, y, mode);
|
|
|
|
Room* ptRoom = D2GetRoom(ptMonster);
|
|
|
|
// Check nb of monsters
|
|
Level* ptLevel = ptRoom->ptRoomEx->ptLevel;
|
|
int monstersInLevel = GetNbMonsters(ptLevel);
|
|
Position position;
|
|
D2GetPosition(ptMonster, &position);
|
|
int monstersNearby = GetNbMonsters(ptLevel, position, 25);
|
|
|
|
log_msg("CastSummonMonster nbMonsters: %d - %d\n", monstersNearby, monstersInLevel);
|
|
if (monstersNearby > 16 || monstersInLevel > 100)
|
|
return false;
|
|
|
|
// Spawn Monster
|
|
log_msg("CastSummonMonster D2SpawnMonster(%d, %d, %08X, %08X, %d, %d, %d, %d)\n", minionId, mode, ptGame, ptRoom, x, y, 1, 0);
|
|
Unit* monster = D2SpawnMonster(minionId, mode, ptGame, ptRoom, x, y, 1, 0);
|
|
log_msg("CastSummonMonster D2SpawnMonster end\n");
|
|
if (monster)
|
|
return true;
|
|
|
|
// Try in near rooms
|
|
log_msg("CastSummonMonster Try in near rooms: %d - %d\n", ptRoom->startX, ptRoom->startY);
|
|
for(int i = 0; i < ptRoom->nbNearRooms; i++)
|
|
{
|
|
Room* ptRoom2 = ptRoom->ptNearRooms[i];
|
|
if (IsInRoom(ptRoom2, x, y))
|
|
{
|
|
log_msg("CastSummonMonster D2SpawnMonster(%d, %d, %08X, %08X, %d, %d, %d, %d)\n", minionId, mode, ptGame, ptRoom2, x, y, 1, 0);
|
|
monster = D2SpawnMonster(minionId, mode, ptGame, ptRoom2, x, y, 1, 0);
|
|
log_msg("CastSummonMonster D2SpawnMonster end\n");
|
|
if (monster)
|
|
return true;
|
|
}
|
|
}
|
|
log_msg("CastSummonMonster end: %d - %d\n", ptRoom->startX, ptRoom->startY);
|
|
return false;
|
|
}
|
|
|
|
void RandInCircle(Position* position, DWORD radius)
|
|
{
|
|
double theta = RANDOMF() * 6.283185;
|
|
double r = sqrt(RANDOMF()) * radius;
|
|
position->x += (DWORD)(r * cos(theta));
|
|
position->y += (DWORD)(r * sin(theta));
|
|
}
|
|
|
|
void FASTCALL uberMephAI(Game* ptGame, Unit* ptMonster, AIParam* ptAIArgs)
|
|
{
|
|
log_msg("UberMephAI called.\n");
|
|
|
|
// Spawn Minions
|
|
if (active_UberMinions && RANDOM(100) < UberMephistoSpawnPercent && ptAIArgs->distanceToTarget < UberMephistoSpawnRadius)
|
|
{
|
|
Position pos;
|
|
D2GetPosition(ptAIArgs->target, &pos);
|
|
CastSummonMonster(ptGame, ptMonster, pos.x, pos.y, UberMephistoMinions, UberMephistoNbMinions, 8);
|
|
}
|
|
|
|
log_msg("Uber Mephisto AI activated.\n");
|
|
D2MephAI(ptGame, ptMonster, ptAIArgs);
|
|
}
|
|
|
|
void FASTCALL uberDiabloAI(Game* ptGame, Unit* ptMonster, AIParam* ptAIArgs)
|
|
{
|
|
log_msg("UberDiabloAI called.\n");
|
|
|
|
// Spawn Minions
|
|
if (active_UberMinions && RANDOM(100) < UberDiabloSpawnPercent && ptAIArgs->distanceToTarget < UberDiabloSpawnRadius)
|
|
{
|
|
Position pos;
|
|
D2GetPosition(ptAIArgs->target, &pos);
|
|
RandInCircle(&pos, 3);
|
|
CastSummonMonster(ptGame, ptMonster, pos.x, pos.y, UberDiabloMinions, UberDiabloNbMinions, 1);
|
|
}
|
|
|
|
// Tweek Diablo AI Rush
|
|
if (active_UberDiabloRushTweekAI && RANDOM(100) < (int)ptAIArgs->distanceToTarget - 10)
|
|
{
|
|
if (RANDOM(3) > 0)//67% to Rush
|
|
{
|
|
log_msg("Uber Diablo Run activated.\n");
|
|
int diabloRunSkillId = 4;
|
|
D2MonsterUseSkill(ptGame, ptMonster, ptAIArgs->ptMonStatsBIN->skillArg[diabloRunSkillId], ptAIArgs->ptMonStatsBIN->skill[diabloRunSkillId], ptAIArgs->target, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
log_msg("Uber Diablo Move activated.\n");
|
|
Position pos;
|
|
D2GetPosition(ptAIArgs->target, &pos);
|
|
D2MonsterMove(ptGame, ptMonster, NULL, 2, pos.x, pos.y, 1, 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
log_msg("Uber Diablo AI activated.\n");
|
|
D2DiabloAI(ptGame, ptMonster, ptAIArgs);
|
|
}
|
|
|
|
void FASTCALL uberBaalAI(Game* ptGame, Unit* ptMonster, AIParam* ptAIArgs)
|
|
{
|
|
log_msg("UberBaalAI called.\n");
|
|
|
|
if (active_UberMinions && RANDOM(100) < UberBaalSpawnPercent && ptAIArgs->distanceToTarget < UberBaalSpawnRadius)
|
|
{
|
|
Position pos;
|
|
D2GetPosition(ptAIArgs->target, &pos);
|
|
RandInCircle(&pos, 3);
|
|
CastSummonMonster(ptGame, ptMonster, pos.x, pos.y, UberBaalMinions, UberBaalNbMinions, 1);
|
|
}
|
|
|
|
// Tweek Baal AI Chilling Armor
|
|
if (active_UberBaalChillingArmorTweekAI)
|
|
{
|
|
if (uberBaalChillingArmorLastFrame == 0 || ((int)ptGame->gameFrame - uberBaalChillingArmorLastFrame > uberBaalChillingArmorTimer))
|
|
{
|
|
log_msg("Uber Baal Chilling Armor activated.\n");
|
|
uberBaalChillingArmorLastFrame = ptGame->gameFrame;
|
|
const int baalChillingArmorSkillId = 7;
|
|
D2MonsterUseSkill(ptGame, ptMonster, ptAIArgs->ptMonStatsBIN->skillArg[baalChillingArmorSkillId], ptAIArgs->ptMonStatsBIN->skill[baalChillingArmorSkillId], NULL, 0, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Tweek Baal AI Teleport
|
|
if (active_UberBaalTeleportTweekAI && RANDOM(100) < (int)ptAIArgs->distanceToTarget - 10)
|
|
{
|
|
if (RANDOM(3) > 0)//67% to teleport
|
|
{
|
|
log_msg("Uber Baal Teleport activated.\n");
|
|
const int baalTeleportSkillId = 4;
|
|
Position pos;
|
|
D2GetPosition(ptAIArgs->target, &pos);
|
|
D2MonsterUseSkill(ptGame, ptMonster, ptAIArgs->ptMonStatsBIN->skillArg[baalTeleportSkillId], ptAIArgs->ptMonStatsBIN->skill[baalTeleportSkillId], NULL/*ptAIArgs->target*/, pos.x, pos.y);
|
|
}
|
|
else
|
|
{
|
|
log_msg("Uber Baal Move activated.\n");
|
|
Position pos;
|
|
D2GetPosition(ptAIArgs->target, &pos);
|
|
D2MonsterMove(ptGame, ptMonster, NULL, 2, pos.x, pos.y, 1, 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
log_msg("Uber Baal AI activated.\n");
|
|
D2BaalAI(ptGame, ptMonster, ptAIArgs);
|
|
}
|
|
|
|
FCT_ASM ( caller_spawnUber )
|
|
PUSH EDX
|
|
PUSH ECX
|
|
CALL spawnUber
|
|
RETN
|
|
}}
|
|
|
|
void Install_UberQuest()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
if ( version_D2Game <= V110 )
|
|
return;
|
|
|
|
log_msg("Patch D2Game for active Uber Quest. (UberQuest)\n");
|
|
|
|
DWORD oldProtection;
|
|
|
|
// open Red Portal
|
|
VirtualProtect((LPVOID)R8(D2Game,0,0,0,FA480,FA7B8, FA228, FA5F0, FA2C4, 2E11D0), 8, PAGE_EXECUTE_READWRITE, &oldProtection);
|
|
mem_seek R8(D2Game, 0000, 0000, 0000, FA480, FA7B8, FA228, FA5F0, FA2C4, 2E11D0);
|
|
MEMT_DWORD( D2OpenPandPortal , openPandPortal);
|
|
MEMT_DWORD( D2OpenPandFinalPortal , openPandFinalPortal);
|
|
//0201E357 |. FFD0 |CALL EAX
|
|
//01FA77E7 |. FFD0 |CALL EAX
|
|
//6FCF3CC7 |. FFD0 |CALL EAX
|
|
//6FC92437 |. FFD0 |CALL EAX
|
|
//6FCB7127 |. FFD0 |CALL EAX
|
|
//00565D45 . FFD0 CALL EAX
|
|
VirtualProtect((LPVOID)R8(D2Game,0,0,0,FA480,FA7B8, FA228, FA5F0, FA2C4, 2E11D0), 8, oldProtection, &oldProtection);
|
|
|
|
|
|
// manage uberIA (fct table at 0209E7E8)
|
|
VirtualProtect((LPVOID)(R8(D2Game,0,0,0,10E7E8,10ECD0,10EF58,10E788, 10ED00, 33CA18) + 145*0x10), 0x30, PAGE_EXECUTE_READWRITE, &oldProtection);
|
|
mem_seek R8(D2Game, 0000, 0000, 0000, 10F100, 10F5E8, 10F870, 10F0A0, 10F618, 33D330);
|
|
MEMT_DWORD( D2UberBaalAI , uberBaalAI);
|
|
mem_seek R8(D2Game, 0000, 0000, 0000, 10F110, 10F5F8, 10F880, 10F0B0, 10F628, 33D340);
|
|
MEMT_DWORD( D2UberMephAI , uberMephAI);
|
|
mem_seek R8(D2Game, 0000, 0000, 0000, 10F120, 10F608, 10F890, 10F0C0, 10F638, 33D350);
|
|
MEMT_DWORD( D2UberDiabloAI , uberDiabloAI);
|
|
VirtualProtect((LPVOID)(R8(D2Game,0,0,0,10E7E8,10ECD0,10EF58,10E788, 10ED00, 33CA18) + 145*0x10), 0x30, oldProtection, &oldProtection);
|
|
//0202ADA7 |> B8 E8E70902 MOV EAX,D2Game.0209E7E8
|
|
//01FD2BE7 |> B8 D0EC0702 MOV EAX,D2Game.0207ECD0
|
|
//6FC3B597 |> B8 58EFD26F MOV EAX,D2Game.6FD2EF58
|
|
//6FCBD157 |> B8 88E7D26F MOV EAX,D2Game.6FD2E788
|
|
//6FC5C617 |> B8 00EDD26F MOV EAX,D2Game.6FD2ED00
|
|
//005B163D |. B8 18CA7300 MOV EAX,Game.0073CA18
|
|
|
|
// spawn Uber
|
|
// mem_seek R7(D2Game, 0000, 0000, 0000, 98DAD, 0000, 0000, 0000);
|
|
// MEMJ_REF4( D2WarpPlayer , spawnUber);
|
|
//02028DAC |. E8 491CF7FF CALL <JMP.&D2Common.#10872>
|
|
|
|
mem_seek R8(D2Game, 0000, 0000, 0000, E26E2, E6B52, A850B, 2CCAB, BE9AB, 12D1DC);
|
|
MEMC_REF4( V2Game235C0 , version_D2Game >= V114d ? (DWORD)caller_spawnUber : (DWORD)spawnUber);
|
|
//020726E1 |. E8 2A46FFFF ||CALL D2Game.02066D10
|
|
//02056B51 |. E8 6ACAF3FF ||CALL D2Game.01F935C0
|
|
//6FCC850A |. E8 014FF6FF ||CALL D2Game.6FC2D410
|
|
//6FC4CCAA |. E8 3134FFFF ||CALL D2Game.6FC400E0
|
|
//6FCDE9AA |. E8 D1AFF9FF ||CALL D2Game.6FC79980
|
|
//0052D1DB |. E8 60590100 ||CALL Game.00542B40
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/*================================= END OF FILE =================================*/ |