|
|
|
|
@ -1957,13 +1957,14 @@ void GroupUnity(int i)
|
|
|
|
|
assert((DWORD)i < MAXMONSTERS); |
|
|
|
|
auto &monster = Monsters[i]; |
|
|
|
|
|
|
|
|
|
auto &leader = Monsters[monster.leader]; |
|
|
|
|
if (monster.leaderflag != MonsterRelation::Individual) { |
|
|
|
|
bool clear = IsLineNotSolid(monster.position.tile, leader.position.future); |
|
|
|
|
if (clear || monster.leaderflag != MonsterRelation::Minion) { |
|
|
|
|
if (clear |
|
|
|
|
&& monster.leaderflag == MonsterRelation::Leader |
|
|
|
|
&& monster.position.tile.WalkingDistance(leader.position.future) < 4) { |
|
|
|
|
if (monster.leaderflag == MonsterRelation::Individual) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (monster.leader != 0) { |
|
|
|
|
auto &leader = Monsters[monster.leader]; |
|
|
|
|
if (IsLineNotSolid(monster.position.tile, leader.position.future)) { |
|
|
|
|
if (monster.leaderflag == MonsterRelation::Leader && monster.position.tile.WalkingDistance(leader.position.future) < 4) { |
|
|
|
|
leader.packsize++; |
|
|
|
|
monster.leaderflag = MonsterRelation::Minion; |
|
|
|
|
} |
|
|
|
|
@ -1971,35 +1972,34 @@ void GroupUnity(int i)
|
|
|
|
|
leader.packsize--; |
|
|
|
|
monster.leaderflag = MonsterRelation::Leader; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (monster.leaderflag == MonsterRelation::Minion) { |
|
|
|
|
if (monster._msquelch > leader._msquelch) { |
|
|
|
|
leader.position.last = monster.position.tile; |
|
|
|
|
leader._msquelch = monster._msquelch - 1; |
|
|
|
|
} |
|
|
|
|
if (leader._mAi == AI_GARG) { |
|
|
|
|
if ((leader._mFlags & MFLAG_ALLOW_SPECIAL) != 0) { |
|
|
|
|
leader._mFlags &= ~MFLAG_ALLOW_SPECIAL; |
|
|
|
|
leader._mmode = MM_SATTACK; |
|
|
|
|
if (monster.leaderflag == MonsterRelation::Minion) { |
|
|
|
|
if (monster._msquelch > leader._msquelch) { |
|
|
|
|
leader.position.last = monster.position.tile; |
|
|
|
|
leader._msquelch = monster._msquelch - 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else if (monster._uniqtype != MonsterRelation::Individual) { |
|
|
|
|
if ((UniqMonst[monster._uniqtype - 1].mUnqAttr & 2) != 0) { |
|
|
|
|
for (int j = 0; j < ActiveMonsterCount; j++) { |
|
|
|
|
auto &minion = Monsters[ActiveMonsters[j]]; |
|
|
|
|
if (minion.leaderflag == MonsterRelation::Minion && minion.leader == i) { |
|
|
|
|
if (monster._msquelch > minion._msquelch) { |
|
|
|
|
minion.position.last = monster.position.tile; |
|
|
|
|
minion._msquelch = monster._msquelch - 1; |
|
|
|
|
} |
|
|
|
|
if (minion._mAi == AI_GARG) { |
|
|
|
|
if ((minion._mFlags & MFLAG_ALLOW_SPECIAL) != 0) { |
|
|
|
|
minion._mFlags &= ~MFLAG_ALLOW_SPECIAL; |
|
|
|
|
minion._mmode = MM_SATTACK; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (monster._mAi == AI_GARG && (monster._mFlags & MFLAG_ALLOW_SPECIAL) != 0) { |
|
|
|
|
if (monster.leaderflag == MonsterRelation::Minion || monster.packsize > 0) { |
|
|
|
|
monster._mFlags &= ~MFLAG_ALLOW_SPECIAL; |
|
|
|
|
monster._mmode = MM_SATTACK; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (monster.leaderflag == MonsterRelation::Leader && monster._uniqtype != 0) { |
|
|
|
|
if ((UniqMonst[monster._uniqtype - 1].mUnqAttr & 2) == 0) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
for (int j = 0; j < ActiveMonsterCount; j++) { |
|
|
|
|
auto &minion = Monsters[ActiveMonsters[j]]; |
|
|
|
|
if (minion.leaderflag != MonsterRelation::Minion || minion.leader != i) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if (monster._msquelch > minion._msquelch) { |
|
|
|
|
minion.position.last = monster.position.tile; |
|
|
|
|
minion._msquelch = monster._msquelch - 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -4386,38 +4386,35 @@ void GolumAi(int i)
|
|
|
|
|
if ((golem._mFlags & MFLAG_TARGETS_MONSTER) == 0) |
|
|
|
|
UpdateEnemy(golem); |
|
|
|
|
|
|
|
|
|
bool haveEnemy = (golem._mFlags & MFLAG_NO_ENEMY) == 0; |
|
|
|
|
|
|
|
|
|
if (golem._mmode == MM_ATTACK) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto &enemy = Monsters[golem._menemy]; |
|
|
|
|
|
|
|
|
|
int mex = golem.position.tile.x - enemy.position.future.x; |
|
|
|
|
int mey = golem.position.tile.y - enemy.position.future.y; |
|
|
|
|
Direction md = GetDirection(golem.position.tile, enemy.position.tile); |
|
|
|
|
golem._mdir = md; |
|
|
|
|
if (abs(mex) < 2 && abs(mey) < 2 && haveEnemy) { |
|
|
|
|
golem.enemyPosition = enemy.position.tile; |
|
|
|
|
if (enemy._msquelch == 0) { |
|
|
|
|
enemy._msquelch = UINT8_MAX; |
|
|
|
|
enemy.position.last = golem.position.tile; |
|
|
|
|
for (int j = 0; j < 5; j++) { |
|
|
|
|
for (int k = 0; k < 5; k++) { |
|
|
|
|
int menemy = dMonster[golem.position.tile.x + k - 2][golem.position.tile.y + j - 2]; // BUGFIX: Check if indexes are between 0 and 112
|
|
|
|
|
if (menemy > 0) |
|
|
|
|
Monsters[menemy - 1]._msquelch = UINT8_MAX; // BUGFIX: should be `Monsters[_menemy-1]`, not Monsters[_menemy]. (fixed)
|
|
|
|
|
if ((golem._mFlags & MFLAG_NO_ENEMY) == 0) { |
|
|
|
|
auto &enemy = Monsters[golem._menemy]; |
|
|
|
|
int mex = golem.position.tile.x - enemy.position.future.x; |
|
|
|
|
int mey = golem.position.tile.y - enemy.position.future.y; |
|
|
|
|
golem._mdir = GetDirection(golem.position.tile, enemy.position.tile); |
|
|
|
|
if (abs(mex) < 2 && abs(mey) < 2) { |
|
|
|
|
golem.enemyPosition = enemy.position.tile; |
|
|
|
|
if (enemy._msquelch == 0) { |
|
|
|
|
enemy._msquelch = UINT8_MAX; |
|
|
|
|
enemy.position.last = golem.position.tile; |
|
|
|
|
for (int j = 0; j < 5; j++) { |
|
|
|
|
for (int k = 0; k < 5; k++) { |
|
|
|
|
int enemyId = dMonster[golem.position.tile.x + k - 2][golem.position.tile.y + j - 2]; // BUGFIX: Check if indexes are between 0 and 112
|
|
|
|
|
if (enemyId > 0) |
|
|
|
|
Monsters[enemyId - 1]._msquelch = UINT8_MAX; // BUGFIX: should be `Monsters[_menemy-1]`, not Monsters[_menemy]. (fixed)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
StartAttack(golem); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
StartAttack(golem); |
|
|
|
|
return; |
|
|
|
|
if (AiPlanPath(i)) |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (haveEnemy && AiPlanPath(i)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
golem._pathcount++; |
|
|
|
|
if (golem._pathcount > 8) |
|
|
|
|
golem._pathcount = 5; |
|
|
|
|
@ -4426,7 +4423,7 @@ void GolumAi(int i)
|
|
|
|
|
if (ok) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
md = left[md]; |
|
|
|
|
Direction md = left[golem._mdir]; |
|
|
|
|
for (int j = 0; j < 8 && !ok; j++) { |
|
|
|
|
md = right[md]; |
|
|
|
|
ok = DirOK(i, md); |
|
|
|
|
@ -4628,12 +4625,10 @@ bool DirOK(int i, Direction mdir)
|
|
|
|
|
if (y < 0 || y >= MAXDUNY || x < 0 || x >= MAXDUNX) |
|
|
|
|
continue; |
|
|
|
|
int mi = dMonster[x][y]; |
|
|
|
|
if (mi < 0) |
|
|
|
|
mi = -mi; |
|
|
|
|
if (mi != 0) |
|
|
|
|
mi--; |
|
|
|
|
// BUGFIX: should only run pack member check if mi was non-zero prior to executing the body of the above if-statement.
|
|
|
|
|
auto &minion = Monsters[mi]; |
|
|
|
|
if (mi == 0) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
auto &minion = Monsters[(mi < 0) ? -(mi + 1) : (mi - 1)]; |
|
|
|
|
if (minion.leaderflag == MonsterRelation::Minion |
|
|
|
|
&& minion.leader == i |
|
|
|
|
&& minion.position.future == Point { x, y }) { |
|
|
|
|
|