220 lines
7.2 KiB
Go
Executable File
220 lines
7.2 KiB
Go
Executable File
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
|
||
}
|