Skip to content

Commit

Permalink
Fixed invisible monsters
Browse files Browse the repository at this point in the history
They occur when a freshly spawned monster starts a walk before it has been added to be observed by the player object.
In this case, ObserverToWorldViewAdapter.LocateableRemovedAsync leaves early, because the NewBucket is not null and the player is observing this bucket already.
Therefore, we can only start to walk, when the monster was safely added to the observing players before.
  • Loading branch information
sven-n committed Jun 21, 2024
1 parent 72cb006 commit e67c385
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/GameLogic/MapInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ private void RegisterForConfigChanges(GameMap createdMap, MonsterSpawnArea spawn
await createdMap.RemoveAsync(o).ConfigureAwait(false);
o.Initialize();
await createdMap.AddAsync(o).ConfigureAwait(false);
o.OnSpawn();

if (this._spawnedMonsters.TryGetValue(area, out var previousSpawnCount))
{
Expand Down Expand Up @@ -275,6 +276,7 @@ public async ValueTask InitializeNpcsOnWaveStartAsync(GameMap createdMap, IEvent
npc.SpawnIndex = spawnIndex;
npc.Initialize();
await createdMap.AddAsync(npc).ConfigureAwait(false);
npc.OnSpawn();
if (spawnArea.SpawnTrigger is SpawnTrigger.Automatic or SpawnTrigger.Wandering)
{
this.RegisterForConfigChanges(createdMap, spawnArea, npc);
Expand Down
1 change: 1 addition & 0 deletions src/GameLogic/NPC/AttackableNpcBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ private async ValueTask RespawnAsync()

this.Initialize();
await this.CurrentMap.RespawnAsync(this).ConfigureAwait(false);
this.OnSpawn();
}
catch (Exception ex)
{
Expand Down
17 changes: 15 additions & 2 deletions src/GameLogic/NPC/Monster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public sealed class Monster : AttackableNpcBase, IAttackable, IAttacker, ISuppor

private bool _isCalculatingPath;

private bool _isReadyToWalk;

/// <summary>
/// Initializes a new instance of the <see cref="Monster" /> class.
/// </summary>
Expand Down Expand Up @@ -77,7 +79,6 @@ public Monster(MonsterSpawnArea spawnInfo, MonsterDefinition stats, GameMap map,
/// </summary>
public Player? SummonedBy => (this._intelligence as SummonedMonsterIntelligence)?.Owner;

/// <inheritdoc/>
public Point WalkTarget => this._walker.CurrentTarget;

/// <inheritdoc/>
Expand All @@ -104,13 +105,20 @@ public async ValueTask AttackAsync(IAttackable target)
}
}

/// <inheritdoc />
public override void OnSpawn()
{
base.OnSpawn();
this._isReadyToWalk = true;
}

/// <summary>
/// Walks to the target coordinates.
/// </summary>
/// <param name="target">The target object.</param>
public async ValueTask<bool> WalkToAsync(Point target)
{
if (this._isCalculatingPath || this.IsWalking)
if (this._isCalculatingPath || this.IsWalking || !this._isReadyToWalk)
{
return false;
}
Expand Down Expand Up @@ -215,6 +223,11 @@ public ValueTask MoveAsync(Point target)
/// </summary>
internal async ValueTask RandomMoveAsync()
{
if (!this._isReadyToWalk)
{
return;
}

byte randx = (byte)GameLogic.Rand.NextInt(Math.Max(0, this.Position.X - 1), Math.Min(0xFF, this.Position.X + 2));
byte randy = (byte)GameLogic.Rand.NextInt(Math.Max(0, this.Position.Y - 1), Math.Min(0xFF, this.Position.Y + 2));
if (this.CurrentMap.Terrain.AIgrid[randx, randy] == 1)
Expand Down
8 changes: 8 additions & 0 deletions src/GameLogic/NPC/NonPlayerCharacter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ public virtual void Initialize()
this.Rotation = GetSpawnDirection(this.SpawnArea.Direction);
}

/// <summary>
/// Called when this instance spawned on the map.
/// </summary>
public virtual void OnSpawn()
{
// can be overwritten
}

/// <inheritdoc/>
public async ValueTask AddObserverAsync(IWorldObserver observer)
{
Expand Down
2 changes: 2 additions & 0 deletions src/GameLogic/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,7 @@ public async ValueTask ClientReadyAfterMapChangeAsync()
if (this.Summon?.Item1 is { IsAlive: true } summon)
{
await this.CurrentMap.AddAsync(summon).ConfigureAwait(false);
summon.OnSpawn();
}
}

Expand Down Expand Up @@ -1321,6 +1322,7 @@ public async ValueTask CreateSummonedMonsterAsync(MonsterDefinition definition)
this.Summon = (monster, intelligence);
monster.Initialize();
await gameMap.AddAsync(monster).ConfigureAwait(false);
monster.OnSpawn();
}

/// <summary>
Expand Down

0 comments on commit e67c385

Please sign in to comment.