新手任务

This commit is contained in:
hahwu 2025-08-25 11:42:09 +08:00
parent d8e361ccc2
commit 810067c37a
10 changed files with 2164 additions and 1474 deletions

View File

@ -0,0 +1,58 @@
package GuideTaskCfg
import (
"server/game/mod/item"
"server/gamedata"
)
const (
GUIDE_TASK_CONST = "GuideTaskConst"
GUIDE_TASK_TASK = "GuideTaskTask"
GUIDE_TASK_ACTIVE = "GuideTaskActive"
)
func init() {
gamedata.InitCfg(GUIDE_TASK_CONST)
gamedata.InitCfg(GUIDE_TASK_TASK)
gamedata.InitCfg(GUIDE_TASK_ACTIVE)
}
func GetTaskRewardById(Id int) []*item.Item {
data, err := gamedata.GetDataByIntKey(GUIDE_TASK_TASK, Id)
if err != nil {
return nil
}
return gamedata.GetItemList(data, "Items")
}
func GetTaskActive(Id int) int {
data, err := gamedata.GetDataByIntKey(GUIDE_TASK_TASK, Id)
if err != nil {
return 0
}
return gamedata.GetIntValue(data, "Active")
}
func GetActiveReward(Id int) ([]*item.Item, int) {
data, err := gamedata.GetDataByIntKey(GUIDE_TASK_ACTIVE, Id)
if err != nil {
return nil, 0
}
return gamedata.GetItemList(data, "Items"), gamedata.GetIntValue(data, "Active")
}
func GetUnlockLv() int {
data, err := gamedata.GetDataByKey(GUIDE_TASK_CONST, "UnlockLv")
if err != nil {
return 0
}
return gamedata.GetIntValue(data, "Value")
}
func GetDays() int {
data, err := gamedata.GetDataByKey(GUIDE_TASK_CONST, "Days")
if err != nil {
return 0
}
return gamedata.GetIntValue(data, "Value")
}

View File

@ -0,0 +1,51 @@
package GuideTaskCfg
import (
"fmt"
"testing"
)
func TestGuideTaskCfg_NoPanic(t *testing.T) {
ids := []int{-1, 0, 1, 999999}
for _, id := range ids {
t.Run(fmt.Sprintf("Id=%d", id), func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Fatalf("unexpected panic: %v", r)
}
}()
_ = GetTaskRewardById(id)
_ = GetTaskActive(id)
_, _ = GetActiveReward(id)
})
}
_ = GetUnlockLv()
_ = GetDays()
}
// 以下 Example 用于文档与编译校验(无固定输出校验)
func ExampleGetTaskRewardById() {
_ = GetTaskRewardById(1)
// Output:
}
func ExampleGetTaskActive() {
_ = GetTaskActive(1)
// Output:
}
func ExampleGetActiveReward() {
_, _ = GetActiveReward(1)
// Output:
}
func ExampleGetUnlockLv() {
_ = GetUnlockLv()
// Output:
}
func ExampleGetDays() {
_ = GetDays()
// Output:
}

View File

@ -6,6 +6,7 @@ import (
"server/game/mod/item"
MsgMod "server/game/mod/msg"
"server/game/mod/piggyBank"
"server/game/mod/quest"
"server/msg"
"server/pkg/github.com/name5566/leaf/log"
)
@ -16,6 +17,7 @@ func Charge(p *Player, ChargeId int) {
PiggyBankFire(p, ChargeId) // 猪猪银行
PlayroomFire(p, ChargeId) // 游乐场
ActivityFire(p, ChargeId) // 活动礼包
p.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_PURCHASE, A: []interface{}{}})
}
func SendCharge(p *Player, d *ChargeExtra) {

View File

@ -737,6 +737,9 @@ func (ad *GameLogic) RegisterNetWorkFunc() {
RegisterMsgProcessFunc("ReqGetDailyTaskReward", ReqGetDailyTaskReward) // 领取日常任务奖励
RegisterMsgProcessFunc("ReqGetDailyWeekReward", ReqGetDailyWeekReward) // 领取周活跃奖励
RegisterMsgProcessFunc("ReqDailyUnlock", ReqDailyUnlock) // 日常任务解锁
// 新手任务
RegisterMsgProcessFunc("ReqGetGuideTaskReward", ReqGetGuideTaskReward) // 领取日新手任务奖励
RegisterMsgProcessFunc("ReqGetGuideActiveReward", ReqGetGuideActiveReward) // 领取活跃奖励
// 引导奖励
RegisterMsgProcessFunc("ReqGuideReward", ReqGuideReward) // 领取引导奖励

View File

@ -467,6 +467,7 @@ func (p *PlayerBaseData) AddStar(player *Player, cnt int) error {
if NewStar < 0 {
return errors.New("星星不足")
}
player.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_STAR, A: []interface{}{cnt}})
BaseMod.Star = NewStar
player.UpdateUserInfo()
return nil
@ -516,7 +517,10 @@ func (p *PlayerBaseData) AddExp(player *Player, exp int, pexp int) (int, error)
if ChessMod.TriggerChessBagUnlock(int(BaseMod.Level)) {
player.PushClientRes(ChessMod.BackData())
}
GuideTaskMod := player.PlayMod.getGuideTaskMod()
if GuideTaskMod.Unlock(BaseMod.Level) {
player.PushClientRes(GuideTaskMod.BackData())
}
ChargeMod := player.PlayMod.getChargeMod()
ChargeMod.TriggerChargeUnlock(int(BaseMod.Level), ChessMod.GetEmitList())
player.PushClientRes(ChargeMod.BackData())

View File

@ -25,6 +25,7 @@ import (
"server/game/mod/friendTreasure.go"
guesscolor "server/game/mod/guessColor"
"server/game/mod/guide"
"server/game/mod/guideTask"
"server/game/mod/handbook"
"server/game/mod/invite"
"server/game/mod/item"
@ -82,6 +83,7 @@ type PlayerModList struct {
Activity activity.Activity // 活动
Compensation compensation.Compensation // 补偿
Catnip catnip.CatnipMod // 猫草大作战
GuideTask guideTask.GuideTaskMod // 引导任务
}
func (p *PlayerModData) LoadDataFromDB(dwUin interface{}) bool {
@ -180,6 +182,8 @@ func (p *PlayerModData) InitMod(player *Player) (bool, error) {
p.ModList.Collect.InitData()
p.ModList.Activity.InitData()
p.ModList.Catnip.InitData()
p.ModList.Compensation.InitData()
p.ModList.GuideTask.InitData()
return is_update, nil
}
@ -378,3 +382,6 @@ func (p *PlayerMod) getCompensationMod() *compensation.Compensation {
func (p *PlayerMod) getCatnipMod() *catnip.CatnipMod {
return &p.mod_list.Catnip
}
func (p *PlayerMod) getGuideTaskMod() *guideTask.GuideTaskMod {
return &p.mod_list.GuideTask
}

View File

@ -435,7 +435,7 @@ func ReqDecorate(player *Player, buf []byte) error {
})
return err
}
player.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_DECORATE, A: []interface{}{1}})
EnergyItem := DecorateMod.GetDecorateAddEnergy(1)
AddItem = item.Merge(AddItem, EnergyItem)
err = player.HandleItem(AddItem, msg.ITEM_POP_LABEL_DecorateAdd.String()) // 增加道具
@ -504,6 +504,7 @@ func ReqDecorateAll(player *Player, buf []byte) error {
})
return err
}
player.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_DECORATE, A: []interface{}{DecorateNum}})
EnergyItem := DecorateMod.GetDecorateAddEnergy(DecorateNum)
AddItem = item.Merge(AddItem, EnergyItem)
err = player.HandleItem(AddItem, msg.ITEM_POP_LABEL_DecorateAdd.String()) // 增加道具
@ -514,7 +515,6 @@ func ReqDecorateAll(player *Player, buf []byte) error {
})
return err
}
_, err = player.GetPlayerBaseMod().AddExp(player, 10*DecorateNum, PetExp)
if err != nil {
player.SendErrClienRes(&msg.ResDecorateAll{
@ -874,6 +874,7 @@ func ReqChessEx(player *Player, buf []byte) error {
})
return err
}
player.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_BUBBLE, A: []interface{}{}})
}
err := ChessMod.ExChess(int(req.OldChessId), int(req.NewChessId))
@ -1256,6 +1257,72 @@ func ReqDailyUnlock(player *Player, buf []byte) error {
return nil
}
func ReqGetGuideTaskReward(player *Player, buf []byte) error {
req := &msg.ReqGetGuideTaskReward{}
proto.Unmarshal(buf, req)
GuideTaskMod := player.PlayMod.getGuideTaskMod()
itemList, err := GuideTaskMod.GetTaskReward(int(req.Id))
if err != nil {
player.SendErrClienRes(&msg.ResGetGuideTaskReward{
Code: msg.RES_CODE_FAIL,
Msg: err.Error(),
})
return err
}
player.args["ResItemPopId"] = int(req.Id)
err = player.HandleItem(itemList, msg.ITEM_POP_LABEL_GuideTaskReward.String())
if err != nil {
player.SendErrClienRes(&msg.ResGetGuideTaskReward{
Code: msg.RES_CODE_FAIL,
Msg: err.Error(),
})
return err
}
player.TeLog("ReqGetGuideTaskReward", map[string]interface{}{
"task_id": int(req.Id),
"item_list": itemList,
})
player.PlayMod.save()
player.PushClientRes(GuideTaskMod.BackData())
player.PushClientRes(&msg.ResGetGuideTaskReward{
Code: msg.RES_CODE_SUCCESS,
})
return nil
}
func ReqGetGuideActiveReward(player *Player, buf []byte) error {
req := &msg.ReqGetGuideActiveReward{}
proto.Unmarshal(buf, req)
GuideTaskMod := player.PlayMod.getGuideTaskMod()
itemList, err := GuideTaskMod.GetActiveReward(int(req.Id))
if err != nil {
player.SendErrClienRes(&msg.ResGetGuideActiveReward{
Code: msg.RES_CODE_FAIL,
Msg: err.Error(),
})
return err
}
player.args["ResItemPopId"] = int(req.Id)
err = player.HandleItem(itemList, msg.ITEM_POP_LABEL_GuideActiveReward.String())
if err != nil {
player.SendErrClienRes(&msg.ResGetGuideActiveReward{
Code: msg.RES_CODE_FAIL,
Msg: err.Error(),
})
return err
}
player.TeLog("ReqGetGuideActiveReward", map[string]interface{}{
"active_id": int(req.Id),
"item_list": itemList,
})
player.PlayMod.save()
player.PushClientRes(GuideTaskMod.BackData())
player.PushClientRes(&msg.ResGetGuideActiveReward{
Code: msg.RES_CODE_SUCCESS,
})
return nil
}
// 头像框
func ReqSetAvatar(player *Player, buf []byte) error {
req := &msg.ReqSetAvatar{}

View File

@ -0,0 +1,127 @@
package guideTask
import (
"fmt"
"server/GoUtil"
GuideTaskCfg "server/conf/guideTask"
"server/game/mod/item"
"server/game/mod/quest"
"server/msg"
)
type GuideTaskMod struct {
Tasks map[int]*GuideTask
Active int
Reward []int // 任务奖励状态
UnlockTime int64 // 解锁时间
}
type GuideTask struct {
Items []*item.Item
Status int
Quest quest.QuestProgress
UnLock bool
}
func (gt *GuideTaskMod) InitData() {
if gt.Tasks == nil {
gt.Tasks = make(map[int]*GuideTask)
}
}
func (gt *GuideTaskMod) Login() {
// 登录时触发的引导任务
if task, ok := gt.Tasks[1]; ok && !task.UnLock {
task.UnLock = true
task.Status = 1 // 设置为已解锁状态
}
}
func (gt *GuideTaskMod) Unlock(lv int) bool {
UnLockLv := GuideTaskCfg.GetUnlockLv()
if lv >= UnLockLv && gt.UnlockTime == 0 {
gt.UnlockTime = GoUtil.Now()
return true
}
return false
}
func (gt *GuideTaskMod) CheckOpen() bool {
// 检查是否可以打开引导任务
if gt.UnlockTime == 0 {
return false
}
return GoUtil.Now()-gt.UnlockTime <= 96*3600 // 96小时内可以打开
}
func (gt *GuideTaskMod) Trigger(Tr *quest.Trigger) bool {
if !gt.CheckOpen() {
return false
}
update := false
for k, v := range gt.Tasks {
if v.Status != quest.QUEST_STATUS_UNFINISH {
continue
}
up := quest.TriggerQuestProgress(&v.Quest, Tr)
if up {
update = true
}
if v.Quest.Status {
v.Status = quest.QUEST_STATUS_FINISH
if _, ok := gt.Tasks[k+1]; ok {
task := gt.Tasks[k+1]
task.UnLock = true
gt.Tasks[k+1] = task
}
}
gt.Tasks[k] = v
}
return update
}
func (gt *GuideTaskMod) GetTaskReward(Id int) ([]*item.Item, error) {
if task, ok := gt.Tasks[Id]; ok {
if task.Status == quest.QUEST_STATUS_FINISH {
task.Status = quest.QUEST_STATUS_REWARD
Active := GuideTaskCfg.GetTaskActive(Id)
gt.Active += Active
return GuideTaskCfg.GetTaskRewardById(Id), nil
}
}
return nil, fmt.Errorf("no task id %d", Id)
}
func (gt *GuideTaskMod) GetActiveReward(Id int) ([]*item.Item, error) {
for _, v := range gt.Reward {
if v == Id {
return nil, fmt.Errorf("active reward already got")
}
}
items, needActive := GuideTaskCfg.GetActiveReward(Id)
if items == nil {
return nil, fmt.Errorf("no active reward id %d", Id)
}
if gt.Active < needActive {
return nil, fmt.Errorf("active not enough")
}
gt.Reward = append(gt.Reward, Id)
return items, nil
}
func (gt *GuideTaskMod) BackData() *msg.ResGuideTask {
resTask := make(map[int32]*msg.GuideTask)
for k, v := range gt.Tasks {
resTask[int32(k)] = &msg.GuideTask{
Status: int32(v.Status),
Progress: quest.QuestProgressToMsg(&v.Quest),
}
}
return &msg.ResGuideTask{
Task: resTask,
Active: int32(gt.Active),
UnlockTime: int32(gt.UnlockTime),
ActiveReward: GoUtil.SliceIntToInt32(gt.Reward),
}
}

View File

@ -18,6 +18,7 @@ const (
TRIGGER_LABEL_MERGELVTIME = "MergeLvTime"
TRIGGER_LABEL_FINISHORDER = "FinishOrder"
TRIGGER_LABEL_ENERGY = "Energy"
TRIGGER_LABEL_STAR = "Star" // 收集宠物币
TRIGGER_LABEL_MERGETIME = "MergeTime"
TRIGGER_LABEL_STOKECAT = "StokeCat"
TRIGGER_LABEL_TAKECAT = "TakeCat"
@ -32,6 +33,9 @@ const (
TRIGGER_LABEL_PETTREASURE = "PetTreasure" // 宠物寻宝
TRIGGER_LABEL_ROOMDEC = "RoomDec" // 房间装饰
TRIGGER_LABEL_PETWORK = "PetWork" // 宠物工作
TRIGGER_LABEL_DECORATE = "Decorate" // 装饰
TRIGGER_LABEL_PURCHASE = "Purchase" // 购买任意物品
TRIGGER_LABEL_BUBBLE = "Bubble" // 使用钻石打开气泡
)
type QuestProgress struct {
@ -69,7 +73,9 @@ func TriggerQuestProgress(q *QuestProgress, Tr *Trigger) bool {
}
switch q.Label {
case TRIGGER_LABEL_ENERGY: // 消耗x能量
case TRIGGER_LABEL_ENERGY,
TRIGGER_LABEL_STAR,
TRIGGER_LABEL_DECORATE: // 消耗x能量
AddNum := Tr.A[0].(int)
q.Num += AddNum
case TRIGGER_LABEL_MERGELVTIME: // 合成x级棋子y次
@ -79,9 +85,9 @@ func TriggerQuestProgress(q *QuestProgress, Tr *Trigger) bool {
q.Num += 1
}
case TRIGGER_LABEL_MERGETIME, // 合成x次
TRIGGER_LABEL_FINISHORDER: // 完成x次订单
TRIGGER_LABEL_FINISHORDER,
TRIGGER_LABEL_BUBBLE: // 完成x次订单
q.Num += 1
case TRIGGER_LABEL_INTERACT: // 互动x类型y次
InteractId := Tr.A[0].(int)
Ids := make([]int, 0)

File diff suppressed because it is too large Load Diff