Browse Source

Introduce FindGolemForPlayer and use goalVar3 to track golem <-> player relation

pull/7952/head
obligaron 1 year ago committed by Stephen C. Wills
parent
commit
fee7f4749f
  1. 29
      Source/missiles.cpp
  2. 26
      Source/monster.cpp
  3. 5
      Source/monster.h
  4. 14
      Source/player.cpp

29
Source/missiles.cpp

@ -2342,22 +2342,25 @@ void AddGolem(Missile &missile, AddMissileParameter &parameter)
int playerId = missile._misource;
Player &player = Players[playerId];
Monster &golem = Monsters[playerId];
Monster *golem = FindGolemForPlayer(player);
if (golem.position.tile != GolemHoldingCell && &player == MyPlayer)
KillMyGolem();
// Is Golem alive?
if (golem != nullptr) {
if (&player == MyPlayer)
KillGolem(*golem);
return;
}
if (golem.position.tile == GolemHoldingCell) {
std::optional<Point> spawnPosition = FindClosestValidPosition(
[start = missile.position.start](Point target) {
return !IsTileOccupied(target) && LineClearMissile(start, target);
},
parameter.dst, 0, 5);
std::optional<Point> spawnPosition = FindClosestValidPosition(
[start = missile.position.start](Point target) {
return !IsTileOccupied(target) && LineClearMissile(start, target);
},
parameter.dst, 0, 5);
if (spawnPosition) {
SpawnGolem(player, golem, *spawnPosition, missile);
}
}
if (!spawnPosition)
return;
SpawnGolem(player, *golem, *spawnPosition, missile);
}
void AddApocalypseBoom(Missile &missile, AddMissileParameter &parameter)

26
Source/monster.cpp

@ -1068,7 +1068,7 @@ void MonsterAttackMonster(Monster &attacker, Monster &target, int hper, int mind
ApplyMonsterDamage(DamageType::Physical, target, dam);
if (attacker.isPlayerMinion()) {
size_t playerId = attacker.getId();
size_t playerId = static_cast<size_t>(attacker.goalVar3);
const Player &player = Players[playerId];
target.tag(player);
}
@ -3833,9 +3833,8 @@ void StartMonsterDeath(Monster &monster, const Player &player, bool sendmsg)
MonsterDeath(monster, md, sendmsg);
}
void KillMyGolem()
void KillGolem(Monster &golem)
{
Monster &golem = Monsters[MyPlayerId];
delta_kill_monster(golem, golem.position.tile, *MyPlayer);
NetSendCmdLocParam1(false, CMD_MONSTDEATH, golem.position.tile, static_cast<uint16_t>(golem.getId()));
M_StartKill(golem, *MyPlayer);
@ -4001,7 +4000,7 @@ void GolumAi(Monster &golem)
if (golem.pathCount > 8)
golem.pathCount = 5;
if (RandomWalk(golem, Players[golem.getId()]._pdir))
if (RandomWalk(golem, Players[golem.goalVar3]._pdir))
return;
Direction md = Left(golem.direction);
@ -4516,6 +4515,24 @@ Monster *FindUniqueMonster(UniqueMonsterType monsterType)
return nullptr;
}
Monster *FindGolemForPlayer(const Player &player)
{
for (size_t i = 0; i < ActiveMonsterCount; i++) {
int monsterId = ActiveMonsters[i];
Monster &monster = Monsters[monsterId];
if (monster.type().type != MT_GOLEM)
continue;
if (monster.position.tile == GolemHoldingCell)
continue;
if (monster.goalVar3 != player.getId())
continue;
if (monster.hitPoints == 0)
continue;
return &monster;
}
return nullptr;
}
bool IsTileAvailable(const Monster &monster, Point position)
{
if (!IsTileAvailable(position))
@ -4654,6 +4671,7 @@ void SpawnGolem(Player &player, Monster &golem, Point position, Missile &missile
golem.minDamage = 2 * (missile._mispllvl + 4);
golem.maxDamage = 2 * (missile._mispllvl + 8);
golem.flags |= MFLAG_GOLEM;
golem.goalVar3 = player.getId();
StartSpecialStand(golem, Direction::South);
UpdateEnemy(golem);
if (&player == MyPlayer) {

5
Source/monster.h

@ -237,7 +237,7 @@ struct Monster { // note: missing field _mAFNum
/**
* @brief Controls monster's behaviour regarding special actions.
* Used only by @p ScavengerAi and @p MegaAi.
* Used only by @p ScavengerAi, @p MegaAi and @p GolemAi.
*/
int8_t goalVar3;
@ -529,7 +529,7 @@ void M_StartHit(Monster &monster, int dam);
void M_StartHit(Monster &monster, const Player &player, int dam);
void StartMonsterDeath(Monster &monster, const Player &player, bool sendmsg);
void MonsterDeath(Monster &monster, Direction md, bool sendmsg);
void KillMyGolem();
void KillGolem(Monster &golem);
void M_StartKill(Monster &monster, const Player &player);
void M_SyncStartKill(Monster &monster, Point position, const Player &player);
void M_UpdateRelations(const Monster &monster);
@ -553,6 +553,7 @@ void MissToMonst(Missile &missile, Point position);
Monster *FindMonsterAtPosition(Point position, bool ignoreMovingMonsters = false);
Monster *FindUniqueMonster(UniqueMonsterType monsterType);
Monster *FindGolemForPlayer(const Player &player);
/**
* @brief Check that the given tile is available to the monster

14
Source/player.cpp

@ -2812,14 +2812,14 @@ void SyncPlrKill(Player &player, DeathReason deathReason)
void RemovePlrMissiles(const Player &player)
{
if (leveltype != DTYPE_TOWN && &player == MyPlayer) {
Monster &golem = Monsters[MyPlayerId];
if (golem.position.tile.x != 1 || golem.position.tile.y != 0) {
KillMyGolem();
AddCorpse(golem.position.tile, golem.type().corpseId, golem.direction);
int mx = golem.position.tile.x;
int my = golem.position.tile.y;
Monster *golem = FindGolemForPlayer(player);
if (golem != nullptr) {
KillGolem(*golem);
AddCorpse(golem->position.tile, golem->type().corpseId, golem->direction);
int mx = golem->position.tile.x;
int my = golem->position.tile.y;
dMonster[mx][my] = 0;
golem.isInvalid = true;
golem->isInvalid = true;
DeleteMonsterList();
}
}

Loading…
Cancel
Save