package player import ( "blazing/modules/blazing/model" ) type Done struct { *Player //对玩家进行操作 // *bus.Topic[*model.MilestoneEX] } func NewDone(P *Player) Done { return Done{ Player: P, /// Topic: bus.NewTopic[*model.MilestoneEX](), } } // 注册地图BOSS完成事件 // MAPID 地图ID // BOSSID 地图BOSSID // 注册胜利次数 // 监听器返回奖励是否发送完成,完成就done // func (d *Done) SPT(mapid, bossid, count uint32, fn func() bool) *bus.Listener[*model.MilestoneEX] { // return d.Topic.Sub(func(v *model.MilestoneEX) { // //然后每次触发使用前缀匹配,只要前缀满足就触发 // if v.DoneType == model.MilestoneMode.BOSS && IsPrefixBasicSlice(v.Args, []uint32{mapid, bossid}) && v.Count == count { // _, ok := lo.Find(v.Args, func(v1 uint32) bool { //寻找是否触发过 // //大于触发值就触发,然后1的返回false,因为没有奖励,这样就可以一直触发 // return v1 >= count //大于等于就触发 // }) // if !ok { //说明没有触发过 // if fn() { // v.Results = append(v.Results, count) //把本次的记录添加 // } // } // } // }) // } // 分发事件 ,指定事件+1 并触发是否完成 func (d *Player) Exec(Donetype model.EnumMilestone, id []uint32, fn func(*model.MilestoneEX) uint32) { d.Service.Done.Exec(Donetype, id, func(t *model.MilestoneEX) bool { //这里给予即时奖励,并将用户计数+1 t.Count++ //然后有需要自动发送奖励地方,发送完奖励给置真 if fn != nil { t1 := fn(t) if t1 != 0 { t.Results = append(t.Results, t1) //把本次的记录添加 } } // d.Topic.Pub(t) //异步发送,然后给事件+1 // d.Topic.PubAsyncCallBack(s, func() { //如果没执行完,说明奖励没发完,直接掉线 // d.Service.Done.Exec(s) //给计数器加1 // }) //提交触发里程碑奖励 return true }) //给计数器加1 } // IsPrefixBasicSlice 判断切片 B 是否是切片 A 的前缀 // 泛型约束支持 int | string | bool | uint32 类型的切片 // 规则: // 1. 若 B 长度 > A 长度 → 直接返回 false // 2. 若 B 为空切片 → 返回 true(空切片是任何切片的前缀) // 3. 遍历 B 的每个元素,与 A 对应位置元素逐一比对,全部相等则返回 true func IsPrefixBasicSlice[T int | string | bool | uint32](a, b []T) bool { // 前置判断:B 更长则不可能是 A 的前缀 if len(b) > len(a) { return false } // 遍历 B 的所有元素,比对 A 前 len(b) 个元素 for i := range b { if a[i] != b[i] { return false } } // 所有校验通过 return true }