package items import ( "fmt" "math/rand" "wuziqi-server/core" ) // --- Medkit --- type MedkitStrategy struct{} func (s *MedkitStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { if user.Character == "elephant" { ctx.Logger.Info("Elephant refused medkit") ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "ability", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "medkit", Message: "🐘 大象无法使用该道具!", }) return false } user.Poisoned = false user.PoisonSteps = 0 ctx.Logic.HealPlayer(user, 1) ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "medkit", Value: 1, Message: "💊 使用医疗包,回复1血并解除中毒!", }) return true } // --- BombTimer --- type BombTimerStrategy struct{} func (s *BombTimerStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { user.TimeBombTurns = 3 ctx.Logger.Info("Player %s has a time bomb! Explodes in 3 turns", user.UserID) ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "bomb_timer", Value: 3, Message: "⏰ 定时炸弹启动,3回合后爆炸!", }) return true } // --- Poison --- type PoisonStrategy struct{} func (s *PoisonStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { target := ctx.Logic.GetRandomAliveTarget(state, user.UserID) if target != nil { if target.Character == "sloth" { ctx.Logger.Info("Sloth resisted poison") ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, TargetID: target.UserID, TargetName: target.Username, ItemID: "poison", Message: "🦥 树懒免疫了毒药!", }) } else { target.Poisoned = true target.PoisonSteps = 0 ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, TargetID: target.UserID, TargetName: target.Username, ItemID: "poison", Message: fmt.Sprintf("☠️ %s 中毒了!", target.Username), }) } } return true } // --- Shield --- type ShieldStrategy struct{} func (s *ShieldStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { user.Shield = true ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "shield", Message: "🛡️ 获得护盾,可抵挡一次伤害!", }) return true } // --- Skip --- type SkipStrategy struct{} func (s *SkipStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { user.SkipTurn = true user.Shield = true ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "skip", Message: "⏭️ 好人卡:跳过回合并获得护盾!", }) return true } // --- Magnifier --- type MagnifierStrategy struct{} func (s *MagnifierStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { for i := 0; i < 100; i++ { idx := rand.Intn(len(state.Grid)) if !state.Grid[idx].Revealed { cellType := state.Grid[idx].Type if state.Grid[idx].Type == "item" { cellType = state.Grid[idx].ItemID } user.RevealedCells[idx] = cellType coords := state.FormatCoordinates(idx) contentDesc := core.TranslateCellType(cellType) msg := fmt.Sprintf("🔍 放大镜:透视了 %s,内容是 [%s]!", coords, contentDesc) ctx.Logger.Info("Magnifier: Player %s can now see cell %d (%s) at %s", user.UserID, idx, cellType, coords) ctx.Logic.SendPrivateEvent(user.UserID, core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "magnifier", Message: msg, CellIndex: idx, CellType: cellType, }) break } } return true } // --- Knife --- type KnifeStrategy struct{} func (s *KnifeStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { dmg := 1 isAOE := false // 检查场上是否有存活的老虎(任何玩家是老虎都会触发增强) for _, p := range state.Players { if p.Character == "tiger" && p.HP > 0 { dmg = 2 isAOE = true break } } if isAOE { ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "knife", Value: dmg, Message: fmt.Sprintf("🐯🔪 老虎在场!飞刀变为全体攻击,对所有敌人造成%d点伤害!", dmg), }) for _, p := range state.Players { if p.UserID != user.UserID && p.HP > 0 { ctx.Logic.ApplyDamage(state, p, dmg, true) } } } else { target := ctx.Logic.GetRandomAliveTarget(state, user.UserID) if target != nil { ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, TargetID: target.UserID, TargetName: target.Username, ItemID: "knife", Value: dmg, Message: fmt.Sprintf("🔪 飞刀命中 %s,造成%d点伤害!", target.Username, dmg), }) ctx.Logic.ApplyDamage(state, target, dmg, true) } } return true } // --- Revive --- type ReviveStrategy struct{} func (s *ReviveStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { if user.Character == "elephant" { ctx.Logger.Info("Elephant refused revive") ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "ability", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "revive", Message: "🐘 大象无法使用该道具!", }) return false } user.Revive = true ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "revive", Message: "💖 获得复活甲,可免疫一次死亡!", }) return true } // --- Lightning --- type LightningStrategy struct{} func (s *LightningStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "lightning", Value: 1, Message: "⚡ 闪电对所有玩家造成1点伤害!", }) for _, p := range state.Players { ctx.Logic.ApplyDamage(state, p, 1, true) } return true } // --- Chest --- type ChestStrategy struct{} func (s *ChestStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { user.ChestCount++ ctx.Logger.Info("Player %s found a chest! Total chests: %d", user.UserID, user.ChestCount) ctx.Logic.BroadcastEvent(core.GameEvent{ Type: "item", PlayerID: user.UserID, PlayerName: user.Username, ItemID: "chest", Value: user.ChestCount, Message: "📦 发现宝箱!游戏结束后可获得奖励!", }) return true } // --- Curse --- type CurseStrategy struct{} func (s *CurseStrategy) Use(state *core.GameState, user *core.Player, ctx ItemContext) bool { user.Curse = true // 逻辑上诅咒只是设置标志。原始代码中没有广播? // 嗯,原始代码确实只是设置了标志。 // 我们可以选择添加广播,或者让客户端查看状态图标。 // 如果需要清晰度,我们可以添加广播,但原始代码在 resolveItem 的 switch 诅咒分支中并没有专门的广播... // 等等,检查原始代码。 // case "curse": player.Curse = true。就这样。 // 我将保持最小化。 return true }