refactor: #60 重构 game/task 包,支持更灵活的任务配置方式

This commit is contained in:
kercylan98 2023-11-09 12:08:27 +08:00
parent 2079e9595e
commit 98c1f39ce6
8 changed files with 452 additions and 279 deletions

142
game/task/condition.go Normal file
View File

@ -0,0 +1,142 @@
package task
import "time"
// Cond 创建任务条件
func Cond(k, v any) Condition {
return map[any]any{k: v}
}
// Condition 任务条件
type Condition map[any]any
// Cond 创建任务条件
func (slf Condition) Cond(k, v any) Condition {
slf[k] = v
return slf
}
// GetString 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetString(key any) string {
v, _ := slf[key].(string)
return v
}
// GetInt 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetInt(key any) int {
v, _ := slf[key].(int)
return v
}
// GetInt8 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetInt8(key any) int8 {
v, _ := slf[key].(int8)
return v
}
// GetInt16 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetInt16(key any) int16 {
v, _ := slf[key].(int16)
return v
}
// GetInt32 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetInt32(key any) int32 {
v, _ := slf[key].(int32)
return v
}
// GetInt64 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetInt64(key any) int64 {
v, _ := slf[key].(int64)
return v
}
// GetUint 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetUint(key any) uint {
v, _ := slf[key].(uint)
return v
}
// GetUint8 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetUint8(key any) uint8 {
v, _ := slf[key].(uint8)
return v
}
// GetUint16 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetUint16(key any) uint16 {
v, _ := slf[key].(uint16)
return v
}
// GetUint32 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetUint32(key any) uint32 {
v, _ := slf[key].(uint32)
return v
}
// GetUint64 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetUint64(key any) uint64 {
v, _ := slf[key].(uint64)
return v
}
// GetFloat32 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetFloat32(key any) float32 {
v, _ := slf[key].(float32)
return v
}
// GetFloat64 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetFloat64(key any) float64 {
v, _ := slf[key].(float64)
return v
}
// GetBool 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetBool(key any) bool {
v, _ := slf[key].(bool)
return v
}
// GetTime 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetTime(key any) time.Time {
v, _ := slf[key].(time.Time)
return v
}
// GetDuration 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetDuration(key any) time.Duration {
v, _ := slf[key].(time.Duration)
return v
}
// GetByte 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetByte(key any) byte {
v, _ := slf[key].(byte)
return v
}
// GetBytes 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetBytes(key any) []byte {
v, _ := slf[key].([]byte)
return v
}
// GetRune 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetRune(key any) rune {
v, _ := slf[key].(rune)
return v
}
// GetRunes 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetRunes(key any) []rune {
v, _ := slf[key].([]rune)
return v
}
// GetAny 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
func (slf Condition) GetAny(key any) any {
return slf[key]
}

View File

@ -1,14 +0,0 @@
package task
import "errors"
var (
// ErrTaskNotFinish 任务未完成
ErrTaskNotFinish = errors.New("task not finish")
// ErrTaskRewardReceived 任务奖励已领取
ErrTaskRewardReceived = errors.New("task reward received")
// ErrTaskNotStart 任务未开始
ErrTaskNotStart = errors.New("task not start")
// ErrTaskFail 任务失败
ErrTaskFail = errors.New("task fail")
)

View File

@ -1,35 +1,77 @@
package task package task
import (
"reflect"
)
type ( type (
RefreshTaskCountEvent func(taskType int, increase int64) RefreshTaskCounterEventHandler[Trigger any] func(taskType string, trigger Trigger, count int64) // 刷新任务计数器事件处理函数
RefreshTaskChildCountEvent func(taskType int, key any, increase int64) RefreshTaskConditionEventHandler[Trigger any] func(taskType string, trigger Trigger, condition Condition) // 刷新任务条件事件处理函数
) )
var ( var (
refreshTaskCountEventHandles = make(map[int]RefreshTaskCountEvent) refreshTaskCounterEventHandlers = make(map[string][]struct {
refreshTaskChildCountEventHandles = make(map[int]RefreshTaskChildCountEvent) t reflect.Type
h func(taskType string, trigger any, count int64)
})
refreshTaskConditionEventHandlers = make(map[string][]struct {
t reflect.Type
h func(taskType string, trigger any, condition Condition)
})
) )
// RegRefreshTaskCount 注册任务计数刷新事件 // RegisterRefreshTaskCounterEvent 注册特定任务类型的刷新任务计数器事件处理函数
func RegRefreshTaskCount(taskType int, handler RefreshTaskCountEvent) { func RegisterRefreshTaskCounterEvent[Trigger any](taskType string, handler RefreshTaskCounterEventHandler[Trigger]) {
refreshTaskCountEventHandles[taskType] = handler if refreshTaskCounterEventHandlers == nil {
refreshTaskCounterEventHandlers = make(map[string][]struct {
t reflect.Type
h func(taskType string, trigger any, count int64)
})
}
refreshTaskCounterEventHandlers[taskType] = append(refreshTaskCounterEventHandlers[taskType], struct {
t reflect.Type
h func(taskType string, trigger any, count int64)
}{reflect.TypeOf(handler).In(1), func(taskType string, trigger any, count int64) {
handler(taskType, trigger.(Trigger), count)
}})
} }
// OnRefreshTaskCount 触发任务计数刷新事件 // OnRefreshTaskCounterEvent 触发特定任务类型的刷新任务计数器事件
func OnRefreshTaskCount(taskType int, increase int64) { func OnRefreshTaskCounterEvent(taskType string, trigger any, count int64) {
if handler, ok := refreshTaskCountEventHandles[taskType]; ok { if handlers, exist := refreshTaskCounterEventHandlers[taskType]; exist {
handler(taskType, increase) for _, handler := range handlers {
if !reflect.TypeOf(trigger).AssignableTo(handler.t) {
continue
}
handler.h(taskType, trigger, count)
}
} }
} }
// RegRefreshTaskChildCount 注册任务子计数刷新事件 // RegisterRefreshTaskConditionEvent 注册特定任务类型的刷新任务条件事件处理函数
func RegRefreshTaskChildCount(taskType int, handler RefreshTaskChildCountEvent) { func RegisterRefreshTaskConditionEvent[Trigger any](taskType string, handler RefreshTaskConditionEventHandler[Trigger]) {
refreshTaskChildCountEventHandles[taskType] = handler if refreshTaskConditionEventHandlers == nil {
refreshTaskConditionEventHandlers = make(map[string][]struct {
t reflect.Type
h func(taskType string, trigger any, condition Condition)
})
}
refreshTaskConditionEventHandlers[taskType] = append(refreshTaskConditionEventHandlers[taskType], struct {
t reflect.Type
h func(taskType string, trigger any, condition Condition)
}{reflect.TypeOf(handler).In(1), func(taskType string, trigger any, condition Condition) {
handler(taskType, trigger.(Trigger), condition)
}})
} }
// OnRefreshTaskChildCount 触发任务子计数刷新事件 // OnRefreshTaskConditionEvent 触发特定任务类型的刷新任务条件事件
func OnRefreshTaskChildCount(taskType int, key any, increase int64) { func OnRefreshTaskConditionEvent(taskType string, trigger any, condition Condition) {
if handler, ok := refreshTaskChildCountEventHandles[taskType]; ok { if handlers, exist := refreshTaskConditionEventHandlers[taskType]; exist {
handler(taskType, key, increase) for _, handler := range handlers {
if !reflect.TypeOf(trigger).AssignableTo(handler.t) {
continue
}
handler.h(taskType, trigger, condition)
}
} }
} }

View File

@ -1,85 +1,82 @@
package task package task
import ( import (
"github.com/kercylan98/minotaur/utils/offset"
"time" "time"
) )
// Option 任务选项
type Option func(task *Task) type Option func(task *Task)
// WithChildCount 通过初始化子计数的方式创建任务 // WithType 设置任务类型
func WithChildCount(key any, childCount int64) Option { func WithType(taskType string) Option {
return func(task *Task) { return func(task *Task) {
if task.childCount == nil { task.Type = taskType
task.childCount = make(map[any]int64) }
}
// WithCondition 设置任务完成条件,当满足条件时,任务状态为完成
// - 任务条件值需要变更时可通过 Task.AssignConditionValueAndRefresh 方法变更
// - 当多次设置该选项时,后面的设置会覆盖之前的设置
func WithCondition(condition Condition) Option {
return func(task *Task) {
if condition == nil {
return
} }
if task.childCondition == nil { if task.Cond == nil {
task.childCondition = make(map[any]int64) task.Cond = condition
return
} }
task.childCount[key] = childCount for k, v := range condition {
} task.Cond[k] = v
}
// WithChild 通过指定子计数的方式创建任务
// - 只有当子计数与主计数均达到条件时,任务才会完成
// - 通常用于多条件的任务
func WithChild(key any, childCondition int64) Option {
return func(task *Task) {
if task.childCount == nil {
task.childCount = make(map[any]int64)
}
if task.childCondition == nil {
task.childCondition = make(map[any]int64)
}
task.childCondition[key] = childCondition
}
}
// WithDisableNotStartGetReward 禁止未开始的任务领取奖励
func WithDisableNotStartGetReward() Option {
return func(task *Task) {
task.disableNotStartGetReward = true
}
}
// WithCount 通过初始化计数的方式创建任务
func WithCount(count int64) Option {
return func(task *Task) {
task.SetCount(count)
}
}
// WithStartTime 通过指定开始时间的方式创建任务
// - 只有当时间在开始时间之后,任务才会开始计数
func WithStartTime(startTime time.Time) Option {
return func(task *Task) {
task.start = startTime
}
}
// WithOffsetTime 通过指定偏移时间的方式创建任务
func WithOffsetTime(offset *offset.Time) Option {
return func(task *Task) {
task.offset = offset
}
}
// WithLimitedTime 通过限时的方式创建任务
func WithLimitedTime(limitTime time.Duration) Option {
return func(task *Task) {
task.limitTime = limitTime
}
}
// WithFront 通过指定任务前置任务的方式创建任务
// - 当前置任务未完成时,当前任务不会开始计数
func WithFront(fronts ...*Task) Option {
return func(task *Task) {
if task.fronts == nil {
task.fronts = make(map[int64]*Task)
}
for _, front := range fronts {
task.fronts[front.GetID()] = front
} }
} }
} }
// WithCounter 设置任务计数器,当计数器达到要求时,任务状态为完成
// - 一些场景下,任务计数器可能会溢出,此时可通过 WithOverflowCounter 设置可溢出的任务计数器
// - 当多次设置该选项时,后面的设置会覆盖之前的设置
// - 如果需要初始化计数器的值,可通过 initCount 参数设置
func WithCounter(counter int64, initCount ...int64) Option {
return func(task *Task) {
task.Counter = counter
if len(initCount) > 0 {
task.CurrCount = initCount[0]
if task.CurrCount < 0 {
task.CurrCount = 0
} else if task.CurrCount > task.Counter {
task.CurrCount = task.Counter
}
}
}
}
// WithOverflowCounter 设置可溢出的任务计数器,当计数器达到要求时,任务状态为完成
// - 当多次设置该选项时,后面的设置会覆盖之前的设置
// - 如果需要初始化计数器的值,可通过 initCount 参数设置
func WithOverflowCounter(counter int64, initCount ...int64) Option {
return func(task *Task) {
task.Counter = counter
task.CurrOverflow = true
if len(initCount) > 0 {
task.CurrCount = initCount[0]
if task.CurrCount < 0 {
task.CurrCount = 0
}
}
}
}
// WithDeadline 设置任务截止时间,超过截至时间并且任务未完成时,任务状态为失败
func WithDeadline(deadline time.Time) Option {
return func(task *Task) {
task.Deadline = deadline
}
}
// WithLimitedDuration 设置任务限时,超过限时时间并且任务未完成时,任务状态为失败
func WithLimitedDuration(start time.Time, duration time.Duration) Option {
return func(task *Task) {
task.StartTime = start
task.LimitedDuration = duration
}
}

View File

@ -1,10 +0,0 @@
package task
const (
StateAccept State = iota + 1 // 已接受
StateFinish // 已完成
StateReward // 已领取
StateFail // 已失败
)
type State uint16

23
game/task/status.go Normal file
View File

@ -0,0 +1,23 @@
package task
const (
StatusAccept Status = iota + 1 // 已接受
StatusFailed // 已失败
StatusComplete // 已完成
StatusReward // 已领取奖励
)
var (
statusFormat = map[Status]string{
StatusAccept: "Accept",
StatusComplete: "Complete",
StatusReward: "Reward",
StatusFailed: "Failed",
}
)
type Status byte
func (slf Status) String() string {
return statusFormat[slf]
}

View File

@ -1,207 +1,152 @@
package task package task
import ( import (
"github.com/kercylan98/minotaur/utils/hash"
"github.com/kercylan98/minotaur/utils/offset"
"time" "time"
) )
// NewTask 创建任务 // NewTask 生成任务
func NewTask(id int64, taskType int, condition int64, options ...Option) *Task { func NewTask(options ...Option) *Task {
task := &Task{ task := new(Task)
id: id,
taskType: taskType,
condition: condition,
state: StateAccept,
}
for _, option := range options { for _, option := range options {
option(task) option(task)
} }
if task.start.IsZero() { return task.refreshTaskStatus()
if task.offset != nil {
task.start = task.offset.Now()
} else {
task.start = time.Now()
}
}
for key := range task.childCount {
if !hash.Exist(task.childCondition, key) {
delete(task.childCount, key)
}
}
if task.count == task.condition {
task.state = StateFinish
}
return task
} }
// Task 通用任务数据结构 // Task 是对任务信息进行描述和处理的结构体
type Task struct { type Task struct {
id int64 // 任务ID Type string `json:"type,omitempty"` // 任务类型
taskType int // 任务类型 Status Status `json:"status,omitempty"` // 任务状态
count int64 // 任务主计数 Cond Condition `json:"cond,omitempty"` // 任务条件
condition int64 // 任务完成需要的计数条件 CondValue map[any]any `json:"cond_value,omitempty"` // 任务条件值
childCount map[any]int64 // 任务子计数 Counter int64 `json:"counter,omitempty"` // 任务要求计数器
childCondition map[any]int64 // 任务子计数条件 CurrCount int64 `json:"curr_count,omitempty"` // 任务当前计数
state State // 任务状态 CurrOverflow bool `json:"curr_overflow,omitempty"` // 任务当前计数是否允许溢出
start time.Time // 任务开始时间 Deadline time.Time `json:"deadline,omitempty"` // 任务截止时间
limitTime time.Duration // 任务限时 StartTime time.Time `json:"start_time,omitempty"` // 任务开始时间
fronts map[int64]*Task // 任务前置任务 LimitedDuration time.Duration `json:"limited_duration,omitempty"` // 任务限时
disableNotStartGetReward bool // 禁止未开始的任务领取奖励
offset *offset.Time // 任务偏移时间
} }
// GetID 获取任务ID // IsComplete 判断任务是否已完成
func (slf *Task) GetID() int64 { func (slf *Task) IsComplete() bool {
return slf.id return slf.Status == StatusComplete
} }
// GetType 获取任务类型 // IsFailed 判断任务是否已失败
func (slf *Task) GetType() int { func (slf *Task) IsFailed() bool {
return slf.taskType return slf.Status == StatusFailed
} }
// Reset 重置任务 // IsReward 判断任务是否已领取奖励
func (slf *Task) Reset() { func (slf *Task) IsReward() bool {
slf.count = 0 return slf.Status == StatusReward
slf.state = StateAccept }
for key := range slf.childCount {
delete(slf.childCount, key) // ReceiveReward 领取任务奖励,当任务状态为已完成时,才能领取奖励,此时返回 true并且任务状态变更为已领取奖励
} func (slf *Task) ReceiveReward() bool {
} if slf.Status != StatusComplete {
return false
// GetFronts 获取前置任务
func (slf *Task) GetFronts() map[int64]*Task {
return slf.fronts
}
// GetFrontsWithState 获取特定状态的前置任务
func (slf *Task) GetFrontsWithState(state State) map[int64]*Task {
fronts := make(map[int64]*Task)
for id, front := range slf.fronts {
if front.GetState() == state {
fronts[id] = front
}
}
return fronts
}
// FrontsIsFinish 判断前置任务是否完成
func (slf *Task) FrontsIsFinish() bool {
for _, front := range slf.fronts {
state := front.GetState()
if state == StateAccept || state == StateFail {
return false
}
} }
slf.Status = StatusReward
return true return true
} }
// GetReward 获取任务奖励 // IncrementCounter 增加计数器的值,当 incr 为负数时,计数器的值不会发生变化
// - 当任务状态为 StateFinish 时,调用 rewardHandle 函数 // - 如果需要溢出计数器,可通过 WithOverflowCounter 设置可溢出的任务计数器
// - 当任务状态不为 StateFinish 或奖励函数发生错误时,返回错误 func (slf *Task) IncrementCounter(incr int64) *Task {
func (slf *Task) GetReward(rewardHandle func() error) error { if incr < 0 {
if !slf.IsStart() { return slf
return ErrTaskNotStart
} }
switch slf.GetState() { slf.CurrCount += incr
case StateAccept: if !slf.CurrOverflow && slf.CurrCount > slf.Counter {
return ErrTaskNotFinish slf.CurrCount = slf.Counter
case StateReward:
return ErrTaskRewardReceived
case StateFail:
return ErrTaskFail
} }
if err := rewardHandle(); err != nil { return slf.refreshTaskStatus()
return err
}
slf.state = StateReward
return nil
} }
// GetState 获取任务状态 // DecrementCounter 减少计数器的值,当 decr 为负数时,计数器的值不会发生变化
func (slf *Task) GetState() State { func (slf *Task) DecrementCounter(decr int64) *Task {
return slf.state if decr < 0 {
} return slf
// IsStart 判断任务是否开始
func (slf *Task) IsStart() bool {
var current time.Time
if slf.offset != nil {
current = slf.offset.Now()
} else {
current = time.Now()
} }
if current.Before(slf.start) { slf.CurrCount -= decr
return false if slf.CurrCount < 0 {
} else if slf.limitTime > 0 && current.Sub(slf.start) >= slf.limitTime { slf.CurrCount = 0
return false
} }
return true return slf.refreshTaskStatus()
} }
// SetCount 设置计数 // AssignConditionValueAndRefresh 分配条件值并刷新任务状态
func (slf *Task) SetCount(count int64) { func (slf *Task) AssignConditionValueAndRefresh(key, value any) *Task {
if !slf.IsStart() || !slf.FrontsIsFinish() { if slf.Cond == nil {
return return slf
} }
slf.count = count if _, exist := slf.Cond[key]; !exist {
if slf.count >= slf.condition { return slf
slf.count = slf.condition
} else if slf.count < 0 {
slf.count = 0
} }
slf.refreshState() if slf.CondValue == nil {
} slf.CondValue = make(map[any]any)
// AddCount 增加计数
func (slf *Task) AddCount(count int64) {
slf.SetCount(slf.count + count)
}
// GetCount 获取计数
func (slf *Task) GetCount() int64 {
return slf.count
}
// GetCondition 获取计数条件
func (slf *Task) GetCondition() int64 {
return slf.condition
}
// SetChildCount 设置子计数
func (slf *Task) SetChildCount(key any, count int64) {
if !slf.IsStart() || !slf.FrontsIsFinish() || !hash.Exist(slf.childCondition, key) {
return
} }
if condition := slf.childCondition[key]; count > condition { slf.CondValue[key] = value
count = condition return slf.refreshTaskStatus()
} else if count < 0 {
count = 0
}
slf.childCount[key] = count
slf.refreshState()
OnRefreshTaskCount(slf.taskType, count)
} }
// AddChildCount 增加子计数 // AssignConditionValueAndRefreshByCondition 分配条件值并刷新任务状态
func (slf *Task) AddChildCount(key any, count int64) { func (slf *Task) AssignConditionValueAndRefreshByCondition(condition Condition) *Task {
slf.SetChildCount(key, slf.childCount[key]+count) if slf.Cond == nil {
OnRefreshTaskChildCount(slf.taskType, key, count) return slf
}
if slf.CondValue == nil {
slf.CondValue = make(map[any]any)
}
for k, v := range condition {
if _, exist := slf.Cond[k]; !exist {
continue
}
slf.CondValue[k] = v
}
return slf.refreshTaskStatus()
} }
// refreshState 刷新任务状态 // ResetStatus 重置任务状态
func (slf *Task) refreshState() { // - 该函数会将任务状态重置为已接受状态后,再刷新任务状态
slf.state = StateFinish // - 当任务条件变更,例如任务计数要求为 10已经完成的情况下将任务计数要求变更为 5 或 20此时任务状态由于是已完成或已领取状态不会自动刷新需要调用该函数刷新任务状态
if slf.count != slf.condition { func (slf *Task) ResetStatus() *Task {
slf.state = StateAccept slf.Status = StatusAccept
return return slf.refreshTaskStatus()
}
// refreshTaskStatus 刷新任务状态
func (slf *Task) refreshTaskStatus() *Task {
curr := time.Now()
if (!slf.StartTime.IsZero() && curr.Before(slf.StartTime)) || (!slf.Deadline.IsZero() && curr.After(slf.Deadline)) || slf.Status >= StatusComplete {
return slf
} }
for key, condition := range slf.childCondition { slf.Status = StatusComplete
if slf.childCount[key] != condition {
slf.state = StateAccept if slf.Counter > 0 && slf.CurrCount < slf.Counter {
return slf.Status = StatusAccept
return slf
}
if slf.Cond != nil {
for k, v := range slf.Cond {
if v != slf.CondValue[k] {
slf.Status = StatusAccept
return slf
}
} }
} }
if !slf.Deadline.IsZero() && slf.Status == StatusAccept {
if slf.Deadline.After(curr) {
slf.Status = StatusFailed
return slf
}
}
if slf.LimitedDuration > 0 && slf.Status == StatusAccept {
if curr.Sub(slf.StartTime) > slf.LimitedDuration {
slf.Status = StatusFailed
return slf
}
}
return slf
} }

48
game/task/task_test.go Normal file
View File

@ -0,0 +1,48 @@
package task
import (
"fmt"
"testing"
)
type Player struct {
tasks map[string][]*Task
}
type Monster struct {
}
func TestCond(t *testing.T) {
task := NewTask(WithType("T"), WithCounter(5), WithCondition(Cond("N", 5).Cond("M", 10)))
task.AssignConditionValueAndRefresh("N", 5)
task.AssignConditionValueAndRefresh("M", 10)
RegisterRefreshTaskCounterEvent[*Player](task.Type, func(taskType string, trigger *Player, count int64) {
fmt.Println("Player", count)
for _, t := range trigger.tasks[taskType] {
fmt.Println(t.CurrCount, t.IncrementCounter(count).Status)
}
})
RegisterRefreshTaskConditionEvent[*Player](task.Type, func(taskType string, trigger *Player, condition Condition) {
fmt.Println("Player", condition)
for _, t := range trigger.tasks[taskType] {
fmt.Println(t.CurrCount, t.AssignConditionValueAndRefresh("N", 5).Status)
}
})
RegisterRefreshTaskCounterEvent[*Monster](task.Type, func(taskType string, trigger *Monster, count int64) {
fmt.Println("Monster", count)
})
player := &Player{
tasks: map[string][]*Task{
task.Type: []*Task{task},
},
}
OnRefreshTaskCounterEvent(task.Type, player, 1)
OnRefreshTaskCounterEvent(task.Type, player, 2)
OnRefreshTaskCounterEvent(task.Type, player, 3)
OnRefreshTaskCounterEvent(task.Type, new(Monster), 3)
}