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