aboutsummaryrefslogtreecommitdiff
path: root/internal/game/combat_mob.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/combat_mob.go')
-rw-r--r--internal/game/combat_mob.go16
1 files changed, 13 insertions, 3 deletions
diff --git a/internal/game/combat_mob.go b/internal/game/combat_mob.go
index 21aaf4c..b16e4e1 100644
--- a/internal/game/combat_mob.go
+++ b/internal/game/combat_mob.go
@@ -330,10 +330,16 @@ func (g *Game) awardKillDrops(sess *net.Session, p *player.Player, mob *world.Mo
// scheduleMobRespawn removes trigger-spawned mobs or schedules a normal respawn.
func (g *Game) scheduleMobRespawn(mob *world.MobInstance) {
- instanceID := mob.InstanceID
+ if mob == nil {
+ return
+ }
if mob.SpawnedByTrigger {
g.SubscribeTicks(10, func() bool {
- g.MobStore.RemoveInstance(instanceID)
+ // Read the ID at fire time: a room-ID migration may have rewritten
+ // it while the timer was pending.
+ if id := mob.InstanceID; id != "" {
+ g.MobStore.RemoveInstance(id)
+ }
return false
})
return
@@ -343,7 +349,11 @@ func (g *Game) scheduleMobRespawn(mob *world.MobInstance) {
respawnTicks = engine.ToTicks(30)
}
g.SubscribeTicks(respawnTicks, func() bool {
- g.respawnMob(instanceID)
+ // Re-read the current ID at fire time instead of capturing the string:
+ // RekeyRooms rewrites an instance's key when its home room is rekeyed,
+ // so a captured ID would miss, the mob would stay at HP 0 forever, and
+ // SeedMobs would skip the (now-correct) key as already present.
+ g.respawnMob(mob.InstanceID)
return false
})
}