|
|
|
|
@ -1814,11 +1814,11 @@ func (e *Engine) handleEnemyDeath(cs *model.CombatState, now time.Time) {
|
|
|
|
|
// Rewards (XP, gold, loot, level-ups) are handled by the onEnemyDeath callback
|
|
|
|
|
// via processVictoryRewards -- the single source of truth.
|
|
|
|
|
var victoryDrops []model.LootDrop
|
|
|
|
|
if e.onEnemyDeath != nil && hero != nil {
|
|
|
|
|
if e.onEnemyDeath != nil {
|
|
|
|
|
victoryDrops = e.onEnemyDeath(hero, enemy, now)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if hero != nil {
|
|
|
|
|
|
|
|
|
|
dctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
|
|
|
e.applyOfflineDigest(dctx, cs.HeroID, hero, now, storage.OfflineDigestDelta{
|
|
|
|
|
MonstersKilled: 1,
|
|
|
|
|
@ -1828,7 +1828,7 @@ func (e *Engine) handleEnemyDeath(cs *model.CombatState, now time.Time) {
|
|
|
|
|
LootAppend: NonGoldLootForDigest(victoryDrops),
|
|
|
|
|
})
|
|
|
|
|
cancel()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
e.emitEvent(model.CombatEvent{
|
|
|
|
|
Type: "combat_end",
|
|
|
|
|
@ -1856,7 +1856,7 @@ func (e *Engine) handleEnemyDeath(cs *model.CombatState, now time.Time) {
|
|
|
|
|
|
|
|
|
|
// Persist progression (XP, gold, level/stats after level-up, inventory, world state)
|
|
|
|
|
// so a disconnect or crash does not roll back combat rewards.
|
|
|
|
|
if e.heroStore != nil && hero != nil {
|
|
|
|
|
if e.heroStore != nil {
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
|
err := e.heroStore.Save(ctx, hero)
|
|
|
|
|
cancel()
|
|
|
|
|
|