Browse Source

Convert monster_goal in to a scoped enum

pull/4960/head
Anders Jenbo 4 years ago
parent
commit
38113c0ad8
  1. 4
      Source/loadsave.cpp
  2. 230
      Source/monster.cpp
  3. 20
      Source/monster.h
  4. 2
      Source/objects.cpp

4
Source/loadsave.cpp

@ -575,7 +575,7 @@ void LoadMonster(LoadHelper *file, Monster &monster)
{
monster.levelType = file->NextLE<int32_t>();
monster.mode = static_cast<MonsterMode>(file->NextLE<int32_t>());
monster.goal = static_cast<monster_goal>(file->NextLE<uint8_t>());
monster.goal = static_cast<MonsterGoal>(file->NextLE<uint8_t>());
file->Skip(3); // Alignment
monster.goalVar1 = file->NextLE<int32_t>();
monster.goalVar2 = file->NextLE<int32_t>();
@ -1325,7 +1325,7 @@ void SaveMonster(SaveHelper *file, Monster &monster)
{
file->WriteLE<int32_t>(monster.levelType);
file->WriteLE<int32_t>(static_cast<int>(monster.mode));
file->WriteLE<uint8_t>(monster.goal);
file->WriteLE<uint8_t>(static_cast<uint8_t>(monster.goal));
file->Skip(3); // Alignment
file->WriteLE<int32_t>(monster.goalVar1);
file->WriteLE<int32_t>(monster.goalVar2);

230
Source/monster.cpp

@ -220,7 +220,7 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
monster.hitPoints = monster.maxHitPoints;
monster.ai = monster.data().mAi;
monster.intelligence = monster.data().mInt;
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.goalVar1 = 0;
monster.goalVar2 = 0;
monster.goalVar3 = 0;
@ -525,7 +525,7 @@ void ClrAllMonsters()
for (auto &monster : Monsters) {
ClearMVars(monster);
monster.name = "Invalid Monster";
monster.goal = MGOAL_NONE;
monster.goal = MonsterGoal::None;
monster.mode = MonsterMode::Stand;
monster.var1 = 0;
monster.var2 = 0;
@ -1056,7 +1056,7 @@ void HitMonster(Monster &monster, int dam)
if (monster.type().type == MT_BLINK) {
Teleport(monster);
} else if (IsAnyOf(monster.type().type, MT_NSCAV, MT_BSCAV, MT_WSCAV, MT_YSCAV, MT_GRAVEDIG)) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.goalVar1 = 0;
monster.goalVar2 = 0;
}
@ -1105,7 +1105,7 @@ void MonsterDeath(Monster &monster, int pnum, Direction md, bool sendmsg)
NewMonsterAnim(monster, MonsterGraphic::Death, md, gGameLogicStep < GameLogicStep::ProcessMonsters ? AnimationDistributionFlags::ProcessAnimationPending : AnimationDistributionFlags::None);
monster.mode = MonsterMode::Death;
}
monster.goal = MGOAL_NONE;
monster.goal = MonsterGoal::None;
monster.var1 = 0;
monster.position.offset = { 0, 0 };
monster.position.tile = monster.position.old;
@ -1577,7 +1577,7 @@ void MonsterHeal(Monster &monster)
void MonsterTalk(Monster &monster)
{
M_StartStand(monster, monster.direction);
monster.goal = MGOAL_TALKING;
monster.goal = MonsterGoal::Talking;
if (effect_is_playing(Speeches[monster.talkMsg].sfxnr))
return;
InitQTextMsg(monster.talkMsg);
@ -1629,7 +1629,7 @@ void MonsterTalk(Monster &monster)
Quests[Q_WARLORD]._qvar1 = 2;
if (monster.uniqType - 1 == UMT_LAZARUS && gbIsMultiplayer) {
Quests[Q_BETRAYER]._qvar1 = 6;
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.activeForTicks = UINT8_MAX;
monster.talkMsg = TEXT_NONE;
}
@ -1959,7 +1959,7 @@ bool AiPlanPath(int monsterId)
return false;
if (monster.mode != MonsterMode::Stand)
return false;
if (monster.goal != MGOAL_NORMAL && monster.goal != MGOAL_MOVE && monster.goal != MGOAL_ATTACK2)
if (IsNoneOf(monster.goal, MonsterGoal::Normal, MonsterGoal::Move, MonsterGoal::Attack))
return false;
if (monster.position.tile.x == 1 && monster.position.tile.y == 0)
return false;
@ -2003,23 +2003,23 @@ void AiAvoidance(int monsterId)
MonstCheckDoors(monster);
int v = GenerateRnd(100);
if ((abs(mx) >= 2 || abs(my) >= 2) && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goal == MGOAL_MOVE || ((abs(mx) >= 4 || abs(my) >= 4) && FlipCoin(4))) {
if (monster.goal != MGOAL_MOVE) {
if (monster.goal == MonsterGoal::Move || ((abs(mx) >= 4 || abs(my) >= 4) && FlipCoin(4))) {
if (monster.goal != MonsterGoal::Move) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
}
monster.goal = MGOAL_MOVE;
monster.goal = MonsterGoal::Move;
int dist = std::max(abs(mx), abs(my));
if ((monster.goalVar1++ >= 2 * dist && DirOK(monsterId, md)) || dTransVal[monster.position.tile.x][monster.position.tile.y] != dTransVal[fx][fy]) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
} else if (!RoundWalk(monsterId, md, &monster.goalVar2)) {
AiDelay(monster, GenerateRnd(10) + 10);
}
}
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (monster.goal == MGOAL_NORMAL) {
if (monster.goal == MonsterGoal::Normal) {
if (abs(mx) >= 2 || abs(my) >= 2) {
if ((monster.var2 > 20 && v < 2 * monster.intelligence + 28)
|| (IsAnyOf(static_cast<MonsterMode>(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways)
@ -2143,14 +2143,14 @@ void AiRangedAvoidance(int monsterId)
int v = GenerateRnd(10000);
int dist = std::max(abs(mx), abs(my));
if (dist >= 2 && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goal == MGOAL_MOVE || (dist >= 3 && FlipCoin(4 << lessmissiles))) {
if (monster.goal != MGOAL_MOVE) {
if (monster.goal == MonsterGoal::Move || (dist >= 3 && FlipCoin(4 << lessmissiles))) {
if (monster.goal != MonsterGoal::Move) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
}
monster.goal = MGOAL_MOVE;
monster.goal = MonsterGoal::Move;
if (monster.goalVar1++ >= 2 * dist && DirOK(monsterId, md)) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
} else if (v < (500 * (monster.intelligence + 1) >> lessmissiles)
&& (LineClearMissile(monster.position.tile, { fx, fy }))) {
StartRangedSpecialAttack(monster, missileType, dam);
@ -2159,9 +2159,9 @@ void AiRangedAvoidance(int monsterId)
}
}
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (monster.goal == MGOAL_NORMAL) {
if (monster.goal == MonsterGoal::Normal) {
if (((dist >= 3 && v < ((500 * (monster.intelligence + 2)) >> lessmissiles))
|| v < ((500 * (monster.intelligence + 1)) >> lessmissiles))
&& LineClearMissile(monster.position.tile, { fx, fy })) {
@ -2342,16 +2342,16 @@ void ScavengerAi(int monsterId)
if (monster.mode != MonsterMode::Stand)
return;
if (monster.hitPoints < (monster.maxHitPoints / 2) && monster.goal != MGOAL_HEALING) {
if (monster.hitPoints < (monster.maxHitPoints / 2) && monster.goal != MonsterGoal::Healing) {
if (monster.leaderRelation != LeaderRelation::None) {
if (monster.leaderRelation == LeaderRelation::Leashed)
Monsters[monster.leader].packSize--;
monster.leaderRelation = LeaderRelation::None;
}
monster.goal = MGOAL_HEALING;
monster.goal = MonsterGoal::Healing;
monster.goalVar3 = 10;
}
if (monster.goal == MGOAL_HEALING && monster.goalVar3 != 0) {
if (monster.goal == MonsterGoal::Healing && monster.goalVar3 != 0) {
monster.goalVar3--;
if (dCorpse[monster.position.tile.x][monster.position.tile.y] != 0) {
StartEating(monster);
@ -2371,7 +2371,7 @@ void ScavengerAi(int monsterId)
if (!gbIsHellfire)
targetHealth = (monster.maxHitPoints / 2) + (monster.maxHitPoints / 4);
if (monster.hitPoints >= targetHealth) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.goalVar1 = 0;
monster.goalVar2 = 0;
}
@ -2415,22 +2415,22 @@ void RhinoAi(int monsterId)
int v = GenerateRnd(100);
int dist = std::max(abs(mx), abs(my));
if (dist >= 2) {
if (monster.goal == MGOAL_MOVE || (dist >= 5 && !FlipCoin(4))) {
if (monster.goal != MGOAL_MOVE) {
if (monster.goal == MonsterGoal::Move || (dist >= 5 && !FlipCoin(4))) {
if (monster.goal != MonsterGoal::Move) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
}
monster.goal = MGOAL_MOVE;
monster.goal = MonsterGoal::Move;
if (monster.goalVar1++ >= 2 * dist || dTransVal[monster.position.tile.x][monster.position.tile.y] != dTransVal[fx][fy]) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
} else if (!RoundWalk(monsterId, md, &monster.goalVar2)) {
AiDelay(monster, GenerateRnd(10) + 10);
}
}
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (monster.goal == MGOAL_NORMAL) {
if (monster.goal == MonsterGoal::Normal) {
if (dist >= 5
&& v < 2 * monster.intelligence + 43
&& LineClear([&monster](Point position) { return IsTileAvailable(monster, position); }, monster.position.tile, { fx, fy })) {
@ -2466,19 +2466,19 @@ void FallenAi(int monsterId)
assert(monsterId >= 0 && monsterId < MaxMonsters);
auto &monster = Monsters[monsterId];
if (monster.goal == MGOAL_ATTACK2) {
if (monster.goal == MonsterGoal::Attack) {
if (monster.goalVar1 != 0)
monster.goalVar1--;
else
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (monster.mode != MonsterMode::Stand || monster.activeForTicks == 0) {
return;
}
if (monster.goal == MGOAL_RETREAT) {
if (monster.goal == MonsterGoal::Retreat) {
if (monster.goalVar1-- == 0) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
M_StartStand(monster, Opposite(static_cast<Direction>(monster.goalVar2)));
}
}
@ -2509,15 +2509,15 @@ void FallenAi(int monsterId)
if (otherMonster.ai != AI_FALLEN)
continue;
otherMonster.goal = MGOAL_ATTACK2;
otherMonster.goal = MonsterGoal::Attack;
otherMonster.goalVar1 = 30 * monster.intelligence + 105;
}
}
}
} else if (monster.goal == MGOAL_RETREAT) {
} else if (monster.goal == MonsterGoal::Retreat) {
monster.direction = static_cast<Direction>(monster.goalVar2);
RandomWalk(monsterId, monster.direction);
} else if (monster.goal == MGOAL_ATTACK2) {
} else if (monster.goal == MonsterGoal::Attack) {
int xpos = monster.position.tile.x - monster.enemyPosition.x;
int ypos = monster.position.tile.y - monster.enemyPosition.y;
if (abs(xpos) < 2 && abs(ypos) < 2)
@ -2547,22 +2547,22 @@ void LeoricAi(int monsterId)
int v = GenerateRnd(100);
int dist = std::max(abs(mx), abs(my));
if (dist >= 2 && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goal == MGOAL_MOVE || ((abs(mx) >= 3 || abs(my) >= 3) && FlipCoin(4))) {
if (monster.goal != MGOAL_MOVE) {
if (monster.goal == MonsterGoal::Move || ((abs(mx) >= 3 || abs(my) >= 3) && FlipCoin(4))) {
if (monster.goal != MonsterGoal::Move) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
}
monster.goal = MGOAL_MOVE;
monster.goal = MonsterGoal::Move;
if ((monster.goalVar1++ >= 2 * dist && DirOK(monsterId, md)) || dTransVal[monster.position.tile.x][monster.position.tile.y] != dTransVal[fx][fy]) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
} else if (!RoundWalk(monsterId, md, &monster.goalVar2)) {
AiDelay(monster, GenerateRnd(10) + 10);
}
}
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (monster.goal == MGOAL_NORMAL) {
if (monster.goal == MonsterGoal::Normal) {
if (!gbIsMultiplayer
&& ((dist >= 3 && v < 4 * monster.intelligence + 35) || v < 6)
&& LineClearMissile(monster.position.tile, { fx, fy })) {
@ -2604,13 +2604,13 @@ void BatAi(int monsterId)
Direction md = GetDirection(monster.position.tile, monster.position.last);
monster.direction = md;
int v = GenerateRnd(100);
if (monster.goal == MGOAL_RETREAT) {
if (monster.goal == MonsterGoal::Retreat) {
if (monster.goalVar1 == 0) {
RandomWalk(monsterId, Opposite(md));
monster.goalVar1++;
} else {
RandomWalk(monsterId, PickRandomlyAmong({ Right(md), Left(md) }));
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
return;
}
@ -2634,7 +2634,7 @@ void BatAi(int monsterId)
}
} else if (v < 4 * monster.intelligence + 8) {
StartAttack(monster);
monster.goal = MGOAL_RETREAT;
monster.goal = MonsterGoal::Retreat;
monster.goalVar1 = 0;
if (monster.type().type == MT_FAMILIAR) {
AddMissile(monster.enemyPosition, { monster.enemyPosition.x + 1, 0 }, Direction::South, MIS_LIGHTNING, TARGET_PLAYERS, monsterId, GenerateRnd(10) + 1, 0);
@ -2668,13 +2668,13 @@ void GargoyleAi(int monsterId)
if (monster.hitPoints < (monster.maxHitPoints / 2))
if ((monster.flags & MFLAG_NOHEAL) == 0)
monster.goal = MGOAL_RETREAT;
if (monster.goal == MGOAL_RETREAT) {
monster.goal = MonsterGoal::Retreat;
if (monster.goal == MonsterGoal::Retreat) {
if (abs(dx) >= monster.intelligence + 2 || abs(dy) >= monster.intelligence + 2) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
StartHeal(monster);
} else if (!RandomWalk(monsterId, Opposite(md))) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
}
AiAvoidance(monsterId);
@ -2723,14 +2723,14 @@ void SneakAi(int monsterId)
int dist = 5 - monster.intelligence;
if (static_cast<MonsterMode>(monster.var1) == MonsterMode::HitRecovery) {
monster.goal = MGOAL_RETREAT;
monster.goal = MonsterGoal::Retreat;
monster.goalVar1 = 0;
} else if (abs(mx) >= dist + 3 || abs(my) >= dist + 3 || monster.goalVar1 > 8) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.goalVar1 = 0;
}
Direction md = GetMonsterDirection(monster);
if (monster.goal == MGOAL_RETREAT && (monster.flags & MFLAG_NO_ENEMY) == 0) {
if (monster.goal == MonsterGoal::Retreat && (monster.flags & MFLAG_NO_ENEMY) == 0) {
if ((monster.flags & MFLAG_TARGETS_MONSTER) != 0)
md = GetDirection(monster.position.tile, Monsters[monster.enemy].position.tile);
else
@ -2748,7 +2748,7 @@ void SneakAi(int monsterId)
if ((abs(mx) >= dist + 1 || abs(my) >= dist + 1) && (monster.flags & MFLAG_HIDDEN) == 0) {
StartFadeout(monster, md, true);
} else {
if (monster.goal == MGOAL_RETREAT
if (monster.goal == MonsterGoal::Retreat
|| ((abs(mx) >= 2 || abs(my) >= 2) && ((monster.var2 > 20 && v < 4 * monster.intelligence + 14) || (IsAnyOf(static_cast<MonsterMode>(monster.var1), MonsterMode::MoveNorthwards, MonsterMode::MoveSouthwards, MonsterMode::MoveSideways) && monster.var2 == 0 && v < 4 * monster.intelligence + 64)))) {
monster.goalVar1++;
RandomWalk(monsterId, md);
@ -2777,8 +2777,8 @@ void GharbadAi(int monsterId)
if (monster.talkMsg >= TEXT_GARBUD1
&& monster.talkMsg <= TEXT_GARBUD3
&& !IsTileVisible(monster.position.tile)
&& monster.goal == MGOAL_TALKING) {
monster.goal = MGOAL_INQUIRING;
&& monster.goal == MonsterGoal::Talking) {
monster.goal = MonsterGoal::Inquiring;
switch (monster.talkMsg) {
case TEXT_GARBUD1:
monster.talkMsg = TEXT_GARBUD2;
@ -2796,15 +2796,15 @@ void GharbadAi(int monsterId)
if (IsTileVisible(monster.position.tile)) {
if (monster.talkMsg == TEXT_GARBUD4) {
if (!effect_is_playing(USFX_GARBUD4) && monster.goal == MGOAL_TALKING) {
monster.goal = MGOAL_NORMAL;
if (!effect_is_playing(USFX_GARBUD4) && monster.goal == MonsterGoal::Talking) {
monster.goal = MonsterGoal::Normal;
monster.activeForTicks = UINT8_MAX;
monster.talkMsg = TEXT_NONE;
}
}
}
if (monster.goal == MGOAL_NORMAL || monster.goal == MGOAL_MOVE)
if (IsAnyOf(monster.goal, MonsterGoal::Normal, MonsterGoal::Move))
AiAvoidance(monsterId);
monster.checkStandAnimationIsLoaded(md);
@ -2821,29 +2821,29 @@ void SnotSpilAi(int monsterId)
Direction md = GetMonsterDirection(monster);
if (monster.talkMsg == TEXT_BANNER10 && !IsTileVisible(monster.position.tile) && monster.goal == MGOAL_TALKING) {
if (monster.talkMsg == TEXT_BANNER10 && !IsTileVisible(monster.position.tile) && monster.goal == MonsterGoal::Talking) {
monster.talkMsg = TEXT_BANNER11;
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
}
if (monster.talkMsg == TEXT_BANNER11 && Quests[Q_LTBANNER]._qvar1 == 3) {
monster.talkMsg = TEXT_NONE;
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (IsTileVisible(monster.position.tile)) {
if (monster.talkMsg == TEXT_BANNER12) {
if (!effect_is_playing(USFX_SNOT3) && monster.goal == MGOAL_TALKING) {
if (!effect_is_playing(USFX_SNOT3) && monster.goal == MonsterGoal::Talking) {
ObjChangeMap(SetPiece.position.x, SetPiece.position.y, SetPiece.position.x + SetPiece.size.width + 1, SetPiece.position.y + SetPiece.size.height + 1);
Quests[Q_LTBANNER]._qvar1 = 3;
RedoPlayerVision();
monster.activeForTicks = UINT8_MAX;
monster.talkMsg = TEXT_NONE;
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
}
if (Quests[Q_LTBANNER]._qvar1 == 3) {
if (monster.goal == MGOAL_NORMAL || monster.goal == MGOAL_ATTACK2)
if (IsAnyOf(monster.goal, MonsterGoal::Normal, MonsterGoal::Attack))
FallenAi(monsterId);
}
}
@ -2927,33 +2927,33 @@ void CounselorAi(int monsterId)
if (monster.activeForTicks < UINT8_MAX)
MonstCheckDoors(monster);
int v = GenerateRnd(100);
if (monster.goal == MGOAL_RETREAT) {
if (monster.goal == MonsterGoal::Retreat) {
if (monster.goalVar1++ <= 3)
RandomWalk(monsterId, Opposite(md));
else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
StartFadein(monster, md, true);
}
} else if (monster.goal == MGOAL_MOVE) {
} else if (monster.goal == MonsterGoal::Move) {
int dist = std::max(abs(mx), abs(my));
if (dist >= 2 && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goalVar1++ < 2 * dist || !DirOK(monsterId, md)) {
RoundWalk(monsterId, md, &monster.goalVar2);
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
StartFadein(monster, md, true);
}
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
StartFadein(monster, md, true);
}
} else if (monster.goal == MGOAL_NORMAL) {
} else if (monster.goal == MonsterGoal::Normal) {
if (abs(mx) >= 2 || abs(my) >= 2) {
if (v < 5 * (monster.intelligence + 10) && LineClearMissile(monster.position.tile, { fx, fy })) {
constexpr missile_id MissileTypes[4] = { MIS_FIREBOLT, MIS_CBOLT, MIS_LIGHTCTRL, MIS_FIREBALL };
StartRangedAttack(monster, MissileTypes[monster.intelligence], monster.minDamage + GenerateRnd(monster.maxDamage - monster.minDamage + 1));
} else if (GenerateRnd(100) < 30) {
monster.goal = MGOAL_MOVE;
monster.goal = MonsterGoal::Move;
monster.goalVar1 = 0;
StartFadeout(monster, md, false);
} else
@ -2961,7 +2961,7 @@ void CounselorAi(int monsterId)
} else {
monster.direction = md;
if (monster.hitPoints < (monster.maxHitPoints / 2)) {
monster.goal = MGOAL_RETREAT;
monster.goal = MonsterGoal::Retreat;
monster.goalVar1 = 0;
StartFadeout(monster, md, false);
} else if (static_cast<MonsterMode>(monster.var1) == MonsterMode::Delay
@ -2988,22 +2988,22 @@ void ZharAi(int monsterId)
}
Direction md = GetMonsterDirection(monster);
if (monster.talkMsg == TEXT_ZHAR1 && !IsTileVisible(monster.position.tile) && monster.goal == MGOAL_TALKING) {
if (monster.talkMsg == TEXT_ZHAR1 && !IsTileVisible(monster.position.tile) && monster.goal == MonsterGoal::Talking) {
monster.talkMsg = TEXT_ZHAR2;
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
}
if (IsTileVisible(monster.position.tile)) {
if (monster.talkMsg == TEXT_ZHAR2) {
if (!effect_is_playing(USFX_ZHAR2) && monster.goal == MGOAL_TALKING) {
if (!effect_is_playing(USFX_ZHAR2) && monster.goal == MonsterGoal::Talking) {
monster.activeForTicks = UINT8_MAX;
monster.talkMsg = TEXT_NONE;
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
}
}
if (monster.goal == MGOAL_NORMAL || monster.goal == MGOAL_RETREAT || monster.goal == MGOAL_MOVE)
if (IsAnyOf(monster.goal, MonsterGoal::Normal, MonsterGoal::Retreat, MonsterGoal::Move))
CounselorAi(monsterId);
monster.checkStandAnimationIsLoaded(md);
@ -3035,23 +3035,23 @@ void MegaAi(int monsterId)
int v = GenerateRnd(100);
int dist = std::max(abs(mx), abs(my));
if (dist >= 2 && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goal == MGOAL_MOVE || dist >= 3) {
if (monster.goal != MGOAL_MOVE) {
if (monster.goal == MonsterGoal::Move || dist >= 3) {
if (monster.goal != MonsterGoal::Move) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
}
monster.goal = MGOAL_MOVE;
monster.goal = MonsterGoal::Move;
monster.goalVar3 = 4;
if (monster.goalVar1++ < 2 * dist || !DirOK(monsterId, md)) {
if (v < 5 * (monster.intelligence + 16))
RoundWalk(monsterId, md, &monster.goalVar2);
} else
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (monster.goal == MGOAL_NORMAL) {
if (monster.goal == MonsterGoal::Normal) {
if (((dist >= 3 && v < 5 * (monster.intelligence + 2)) || v < 5 * (monster.intelligence + 1) || monster.goalVar3 == 4) && LineClearMissile(monster.position.tile, { fx, fy })) {
StartRangedSpecialAttack(monster, MIS_FLAMEC, 0);
} else if (dist >= 2) {
@ -3091,28 +3091,28 @@ void LazarusAi(int monsterId)
if (IsTileVisible(monster.position.tile)) {
if (!gbIsMultiplayer) {
Player &myPlayer = *MyPlayer;
if (monster.talkMsg == TEXT_VILE13 && monster.goal == MGOAL_INQUIRING && myPlayer.position.tile == Point { 35, 46 }) {
if (monster.talkMsg == TEXT_VILE13 && monster.goal == MonsterGoal::Inquiring && myPlayer.position.tile == Point { 35, 46 }) {
PlayInGameMovie("gendata\\fprst3.smk");
monster.mode = MonsterMode::Talk;
Quests[Q_BETRAYER]._qvar1 = 5;
}
if (monster.talkMsg == TEXT_VILE13 && !effect_is_playing(USFX_LAZ1) && monster.goal == MGOAL_TALKING) {
if (monster.talkMsg == TEXT_VILE13 && !effect_is_playing(USFX_LAZ1) && monster.goal == MonsterGoal::Talking) {
ObjChangeMap(1, 18, 20, 24);
RedoPlayerVision();
Quests[Q_BETRAYER]._qvar1 = 6;
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.activeForTicks = UINT8_MAX;
monster.talkMsg = TEXT_NONE;
}
}
if (gbIsMultiplayer && monster.talkMsg == TEXT_VILE13 && monster.goal == MGOAL_INQUIRING && Quests[Q_BETRAYER]._qvar1 <= 3) {
if (gbIsMultiplayer && monster.talkMsg == TEXT_VILE13 && monster.goal == MonsterGoal::Inquiring && Quests[Q_BETRAYER]._qvar1 <= 3) {
monster.mode = MonsterMode::Talk;
}
}
if (monster.goal == MGOAL_NORMAL || monster.goal == MGOAL_RETREAT || monster.goal == MGOAL_MOVE) {
if (IsAnyOf(monster.goal, MonsterGoal::Normal, MonsterGoal::Retreat, MonsterGoal::Move)) {
if (!gbIsMultiplayer && Quests[Q_BETRAYER]._qvar1 == 4 && monster.talkMsg == TEXT_NONE) { // Fix save games affected by teleport bug
ObjChangeMapResync(1, 18, 20, 24);
RedoPlayerVision();
@ -3138,15 +3138,15 @@ void LazarusMinionAi(int monsterId)
if (IsTileVisible(monster.position.tile)) {
if (!gbIsMultiplayer) {
if (Quests[Q_BETRAYER]._qvar1 <= 5) {
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
} else {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.talkMsg = TEXT_NONE;
}
} else
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
if (monster.goal == MGOAL_NORMAL)
if (monster.goal == MonsterGoal::Normal)
AiRanged(monsterId);
monster.checkStandAnimationIsLoaded(md);
@ -3163,14 +3163,14 @@ void LachdananAi(int monsterId)
Direction md = GetMonsterDirection(monster);
if (monster.talkMsg == TEXT_VEIL9 && !IsTileVisible(monster.position.tile) && monster.goal == MGOAL_TALKING) {
if (monster.talkMsg == TEXT_VEIL9 && !IsTileVisible(monster.position.tile) && monster.goal == MonsterGoal::Talking) {
monster.talkMsg = TEXT_VEIL10;
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
}
if (IsTileVisible(monster.position.tile)) {
if (monster.talkMsg == TEXT_VEIL11) {
if (!effect_is_playing(USFX_LACH3) && monster.goal == MGOAL_TALKING) {
if (!effect_is_playing(USFX_LACH3) && monster.goal == MonsterGoal::Talking) {
monster.talkMsg = TEXT_NONE;
Quests[Q_VEIL]._qactive = QUEST_DONE;
StartMonsterDeath(monster, -1, true);
@ -3192,16 +3192,16 @@ void WarlordAi(int monsterId)
Direction md = GetMonsterDirection(monster);
if (IsTileVisible(monster.position.tile)) {
if (monster.talkMsg == TEXT_WARLRD9 && monster.goal == MGOAL_INQUIRING)
if (monster.talkMsg == TEXT_WARLRD9 && monster.goal == MonsterGoal::Inquiring)
monster.mode = MonsterMode::Talk;
if (monster.talkMsg == TEXT_WARLRD9 && !effect_is_playing(USFX_WARLRD1) && monster.goal == MGOAL_TALKING) {
if (monster.talkMsg == TEXT_WARLRD9 && !effect_is_playing(USFX_WARLRD1) && monster.goal == MonsterGoal::Talking) {
monster.activeForTicks = UINT8_MAX;
monster.talkMsg = TEXT_NONE;
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
}
}
if (monster.goal == MGOAL_NORMAL)
if (monster.goal == MonsterGoal::Normal)
SkeletonAi(monsterId);
monster.checkStandAnimationIsLoaded(md);
@ -3229,22 +3229,22 @@ void HorkDemonAi(int monsterId)
int v = GenerateRnd(100);
if (abs(mx) < 2 && abs(my) < 2) {
monster.goal = MGOAL_NORMAL;
} else if (monster.goal == 4 || ((abs(mx) >= 5 || abs(my) >= 5) && !FlipCoin(4))) {
if (monster.goal != 4) {
monster.goal = MonsterGoal::Normal;
} else if (monster.goal == MonsterGoal::Move || ((abs(mx) >= 5 || abs(my) >= 5) && !FlipCoin(4))) {
if (monster.goal != MonsterGoal::Move) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
}
monster.goal = MGOAL_MOVE;
monster.goal = MonsterGoal::Move;
int dist = std::max(abs(mx), abs(my));
if (monster.goalVar1++ >= 2 * dist || dTransVal[monster.position.tile.x][monster.position.tile.y] != dTransVal[fx][fy]) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
} else if (!RoundWalk(monsterId, md, &monster.goalVar2)) {
AiDelay(monster, GenerateRnd(10) + 10);
}
}
if (monster.goal == 1) {
if (monster.goal == MonsterGoal::Normal) {
if ((abs(mx) >= 3 || abs(my) >= 3) && v < 2 * monster.intelligence + 43) {
Point position = monster.position.tile + monster.direction;
if (IsTileAvailable(monster, position) && ActiveMonsterCount < MaxMonsters) {
@ -3458,12 +3458,12 @@ void PrepareUniqueMonst(Monster &monster, int uniqindex, int miniontype, int bos
if (monster.ai == AI_LAZHELP)
monster.talkMsg = TEXT_NONE;
if (monster.ai == AI_LAZARUS && Quests[Q_BETRAYER]._qvar1 > 3) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
} else if (monster.talkMsg != TEXT_NONE) {
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
}
} else if (monster.talkMsg != TEXT_NONE) {
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
}
if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
@ -3931,7 +3931,7 @@ void M_StartHit(Monster &monster, int dam)
Teleport(monster);
} else if (IsAnyOf(monster.type().type, MT_NSCAV, MT_BSCAV, MT_WSCAV, MT_YSCAV)
|| monster.type().type == MT_GRAVEDIG) {
monster.goal = MGOAL_NORMAL;
monster.goal = MonsterGoal::Normal;
monster.goalVar1 = 0;
monster.goalVar2 = 0;
}
@ -4475,7 +4475,7 @@ void M_FallenFear(Point position)
continue;
int runDistance = std::max((8 - monster.data().mLevel), 2);
monster.goal = MGOAL_RETREAT;
monster.goal = MonsterGoal::Retreat;
monster.goalVar1 = runDistance;
monster.goalVar2 = static_cast<int>(GetDirection(position, monster.position.tile));
}
@ -4771,13 +4771,13 @@ void TalktoMonster(Monster &monster)
if (RemoveInventoryItemById(player, IDI_BANNER)) {
Quests[Q_LTBANNER]._qactive = QUEST_DONE;
monster.talkMsg = TEXT_BANNER12;
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
}
}
if (Quests[Q_VEIL].IsAvailable() && monster.talkMsg >= TEXT_VEIL9) {
if (RemoveInventoryItemById(player, IDI_GLDNELIX)) {
monster.talkMsg = TEXT_VEIL11;
monster.goal = MGOAL_INQUIRING;
monster.goal = MonsterGoal::Inquiring;
}
}
}
@ -4815,7 +4815,7 @@ void SpawnGolem(int id, Point position, Missile &missile)
bool CanTalkToMonst(const Monster &monster)
{
return IsAnyOf(monster.goal, MGOAL_INQUIRING, MGOAL_TALKING);
return IsAnyOf(monster.goal, MonsterGoal::Inquiring, MonsterGoal::Talking);
}
int encode_enemy(Monster &monster)
@ -4902,9 +4902,9 @@ bool Monster::isPossibleToHit() const
{
return !(hitPoints >> 6 <= 0
|| talkMsg != TEXT_NONE
|| (type().type == MT_ILLWEAV && goal == MGOAL_RETREAT)
|| (type().type == MT_ILLWEAV && goal == MonsterGoal::Retreat)
|| mode == MonsterMode::Charge
|| (IsAnyOf(type().type, MT_COUNSLR, MT_MAGISTR, MT_CABALIST, MT_ADVOCATE) && goal != MGOAL_NORMAL));
|| (IsAnyOf(type().type, MT_COUNSLR, MT_MAGISTR, MT_CABALIST, MT_ADVOCATE) && goal != MonsterGoal::Normal));
}
bool Monster::tryLiftGargoyle()

20
Source/monster.h

@ -95,15 +95,15 @@ enum class MonsterGraphic : uint8_t {
Special,
};
enum monster_goal : uint8_t {
MGOAL_NONE,
MGOAL_NORMAL,
MGOAL_RETREAT,
MGOAL_HEALING,
MGOAL_MOVE,
MGOAL_ATTACK2,
MGOAL_INQUIRING,
MGOAL_TALKING,
enum class MonsterGoal : uint8_t {
None,
Normal,
Retreat,
Healing,
Move,
Attack,
Inquiring,
Talking,
};
enum placeflag : uint8_t {
@ -173,7 +173,7 @@ struct Monster { // note: missing field _mAFNum
*/
AnimationInfo animInfo;
/** Specifies current goal of the monster */
monster_goal goal;
MonsterGoal goal;
/** Specifies monster's behaviour regarding moving and changing goals. */
int goalVar1;
/**

2
Source/objects.cpp

@ -3440,7 +3440,7 @@ void OperateBookCase(int i, bool sendmsg, bool sendLootMsg)
&& zhar.hitPoints > 0) {
zhar.talkMsg = TEXT_ZHAR2;
M_StartStand(zhar, zhar.direction); // BUGFIX: first parameter in call to M_StartStand should be MAX_PLRS, not 0. (fixed)
zhar.goal = MGOAL_ATTACK2;
zhar.goal = MonsterGoal::Attack;
zhar.mode = MonsterMode::Talk;
}
}

Loading…
Cancel
Save