feat: 添加战斗效果800-814及优化道具逻辑
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed

This commit is contained in:
xinian
2026-03-31 06:51:40 +08:00
committed by cnb
parent 8552eb61a8
commit b4a8048b85
7 changed files with 841 additions and 99 deletions

View File

@@ -11,119 +11,134 @@ import (
"github.com/pointernil/bitset32"
)
func (h Controller) DASHIbei(data *C2s_MASTER_REWARDS, c *player.Player) (result *S2C_MASTER_REWARDS, err errorcode.ErrorCode) {
const (
masterCupTaskID uint32 = 111
masterCupRewardItemMin uint32 = 80000000
masterCupRewardItemMax uint32 = 80000015
)
var masterCupRewardElementOrder = [...]uint32{1, 2, 3, 5, 11, 4, 6, 7, 9}
var masterCupRequiredItems = map[uint32][]ItemS{
8: {
{ItemId: 80000001, ItemCnt: 100},
{ItemId: 80000002, ItemCnt: 20},
{ItemId: 80000003, ItemCnt: 20},
{ItemId: 80000005, ItemCnt: 20},
{ItemId: 80000011, ItemCnt: 20},
},
7: {
{ItemId: 80000001, ItemCnt: 20},
{ItemId: 80000002, ItemCnt: 20},
{ItemId: 80000003, ItemCnt: 100},
{ItemId: 80000005, ItemCnt: 20},
{ItemId: 80000011, ItemCnt: 20},
},
1: {
{ItemId: 80000001, ItemCnt: 20},
{ItemId: 80000002, ItemCnt: 100},
{ItemId: 80000003, ItemCnt: 20},
{ItemId: 80000005, ItemCnt: 20},
{ItemId: 80000011, ItemCnt: 20},
},
}
func (h Controller) DASHIbei(req *C2s_MASTER_REWARDS, c *player.Player) (result *S2C_MASTER_REWARDS, err errorcode.ErrorCode) {
_ = req
result = &S2C_MASTER_REWARDS{}
//草","水","火","电","战斗","飞行","机械","地面","冰"
// 按顺序:草、水、火、电、战斗、飞行、机械、地面、冰
var ElementTypeNumbers = []int{1, 2, 3, 5, 11, 4, 6, 7, 9}
items := c.Service.Item.Get(80000000, 80000000+15)
result.Reward = make([]uint32, 9)
for i := 0; i < 9; i++ {
for _, v1 := range items {
if ElementTypeNumbers[i]+80000000 == int(v1.ItemId) {
result.Reward[i] = uint32(v1.ItemCnt)
}
}
}
items := c.Service.Item.Get(masterCupRewardItemMin, masterCupRewardItemMax)
result.Reward = buildMasterCupRewards(items)
return
}
func (h Controller) DASHIbeiR(data *C2s_MASTER_REWARDSR, c *player.Player) (result *S2C_MASTER_REWARDSR, err errorcode.ErrorCode) {
func (h Controller) DASHIbeiR(req *C2s_MASTER_REWARDSR, c *player.Player) (result *S2C_MASTER_REWARDSR, err errorcode.ErrorCode) {
result = &S2C_MASTER_REWARDSR{}
//ids := []uint32{8, 7, 1, 9, 14, 15, 16, 17, 18, 2, 3, 4, 5, 6, 10, 11, 12, 13}
tt, ok := nedds[data.ElementType]
requiredItems, ok := masterCupRequiredItems[req.ElementType]
if !ok {
return nil, errorcode.ErrorCode(errorcode.ErrorCodes.ErrSystemError)
}
taskInfo := task.GetTaskInfo(int(111), int(data.ElementType))
taskInfo := task.GetTaskInfo(int(masterCupTaskID), int(req.ElementType))
if taskInfo == nil {
return nil, errorcode.ErrorCodes.ErrNeedCompleteTaskForPrize
}
for _, v := range tt {
if c.Service.Item.CheakItem(v.ItemId) < int64(v.ItemCnt) {
return nil, errorcode.ErrorCode(errorcode.ErrorCodes.ErrInsufficientItems)
}
if !hasEnoughMasterCupItems(c, requiredItems) {
return nil, errorcode.ErrorCode(errorcode.ErrorCodes.ErrInsufficientItems)
}
c.Service.Task.Exec(uint32(111), func(te *model.Task) bool {
r := bitset32.From(te.Data)
// 分支未完成时,标记完成并发放奖励
if !r.Test(uint(data.ElementType)) {
for _, v := range tt {
c.Service.Item.UPDATE(v.ItemId, -int(v.ItemCnt))
}
r.Set(uint(data.ElementType))
te.Data = r.Bytes()
if taskInfo.Pet != nil {
c.Service.Pet.PetAdd(taskInfo.Pet, 0)
result.CaptureTime = taskInfo.Pet.CatchTime
result.PetTypeId = taskInfo.Pet.ID
}
for _, item := range taskInfo.ItemList {
success := c.ItemAdd(item.ItemId, item.ItemCnt)
if success {
result.ItemList = append(result.ItemList, item)
}
}
return true
} else {
result.ItemList = make([]data.ItemInfo, 0, len(taskInfo.ItemList))
c.Service.Task.Exec(masterCupTaskID, func(te *model.Task) bool {
progress := bitset32.From(te.Data)
if progress.Test(uint(req.ElementType)) {
err = errorcode.ErrorCode(errorcode.ErrorCodes.ErrAwardAlreadyClaimed)
return false
}
return false
consumeMasterCupItems(c, requiredItems)
progress.Set(uint(req.ElementType))
te.Data = progress.Bytes()
if taskInfo.Pet != nil {
c.Service.Pet.PetAdd(taskInfo.Pet, 0)
result.CaptureTime = taskInfo.Pet.CatchTime
result.PetTypeId = taskInfo.Pet.ID
}
appendMasterCupRewardItems(c, result, taskInfo.ItemList)
return true
})
return
}
var nedds = map[uint32][]ItemS{
8: []ItemS{
{ItemId: 80000001, ItemCnt: 100},
{ItemId: 80000002, ItemCnt: 20},
{ItemId: 80000003, ItemCnt: 20},
{ItemId: 80000005, ItemCnt: 20},
{ItemId: 80000011, ItemCnt: 20}},
7: []ItemS{
{ItemId: 80000001, ItemCnt: 20},
{ItemId: 80000002, ItemCnt: 20},
{ItemId: 80000003, ItemCnt: 100},
{ItemId: 80000005, ItemCnt: 20},
{ItemId: 80000011, ItemCnt: 20}},
1: []ItemS{
{ItemId: 80000001, ItemCnt: 20},
{ItemId: 80000002, ItemCnt: 100},
{ItemId: 80000003, ItemCnt: 20},
{ItemId: 80000005, ItemCnt: 20},
{ItemId: 80000011, ItemCnt: 20}},
}
type NeddItemS struct {
index uint32
needitem []ItemS
}
type ItemS struct {
ItemId uint32
ItemCnt uint32
}
func buildMasterCupRewards(items []model.Item) []uint32 {
itemCounts := make(map[uint32]uint32, len(items))
for _, item := range items {
itemCounts[item.ItemId] = uint32(item.ItemCnt)
}
rewards := make([]uint32, len(masterCupRewardElementOrder))
for i, elementType := range masterCupRewardElementOrder {
rewards[i] = itemCounts[masterCupRewardItemMin+elementType]
}
return rewards
}
func hasEnoughMasterCupItems(c *player.Player, requiredItems []ItemS) bool {
for _, item := range requiredItems {
if c.Service.Item.CheakItem(item.ItemId) < int64(item.ItemCnt) {
return false
}
}
return true
}
func consumeMasterCupItems(c *player.Player, requiredItems []ItemS) {
for _, item := range requiredItems {
c.Service.Item.UPDATE(item.ItemId, -int(item.ItemCnt))
}
}
func appendMasterCupRewardItems(c *player.Player, result *S2C_MASTER_REWARDSR, itemList []data.ItemInfo) {
for _, item := range itemList {
if c.ItemAdd(item.ItemId, item.ItemCnt) {
result.ItemList = append(result.ItemList, item)
}
}
}
type C2s_MASTER_REWARDS struct {
Head common.TomeeHeader `cmd:"2611" struc:"skip"` //玩家登录
}
// OutInfo 表示地图热度的出站消息
@@ -131,6 +146,7 @@ type S2C_MASTER_REWARDS struct {
ReLen uint32 `struc:"sizeof=Reward"`
Reward []uint32 `json:"Reward"`
}
type C2s_MASTER_REWARDSR struct {
Head common.TomeeHeader `cmd:"2612" struc:"skip"` //玩家登录
ElementType uint32

View File

@@ -45,6 +45,8 @@ func (h Controller) GET_XUANCAI(data *C2s_GET_XUANCAI, c *player.Player) (result
return nil, errorcode.ErrorCode(errorcode.ErrorCodes.ErrDailyGiftLimit)
}
c.Info.SetTask(13, model.Completed)
selectedItems := make([]uint32, 0, 10)
itemMask := make(map[uint32]uint32, 10)
// 循环直到选中10个元素
for selectedCount < 10 {
// 随机生成0~14的位索引对应1~15号元素
@@ -54,14 +56,20 @@ func (h Controller) GET_XUANCAI(data *C2s_GET_XUANCAI, c *player.Player) (result
// 检查该位是否未被选中(避免重复)
if (result.Status & mask) == 0 {
if c.ItemAdd(400686+int64(randBitIdx)+1, 1) {
result.Status |= mask // 标记该位为选中
}
itemID := uint32(400686 + randBitIdx + 1)
selectedItems = append(selectedItems, itemID)
itemMask[itemID] = mask
selectedCount++ // 选中数+1
}
}
successItems, addErr := c.Service.Item.AddUniqueItems(selectedItems)
if addErr != nil {
return nil, errorcode.ErrorCode(errorcode.ErrorCodes.ErrSystemError200007)
}
for _, itemID := range successItems {
result.Status |= itemMask[itemID]
}
return
}

View File

@@ -46,29 +46,46 @@ func (h Controller) UsePetItemOutOfFight(data *item.C2S_USE_PET_ITEM_OUT_OF_FIGH
return nil, errorcode.ErrorCodes.Err10401
}
if c.Service.Item.CheakItem(uint32(data.ItemID)) == 0 {
itemID := uint32(data.ItemID)
if c.Service.Item.CheakItem(itemID) == 0 {
return nil, errorcode.ErrorCodes.ErrSystemError
}
itemCfg, ok := xmlres.ItemsMAP[int(itemID)]
if !ok {
return nil, errorcode.ErrorCodes.ErrSystemError
}
oldHP := currentPet.Hp
var errcode errorcode.ErrorCode
switch data.ItemID {
case 300036:
switch {
case itemID == 300036:
errcode = h.handleNeuronItem(currentPet, c)
case 300212:
if errcode == 0 {
refreshPetPaneKeepHP(currentPet, oldHP)
}
case itemID == 300212:
errcode = h.handlexuancaiItem(currentPet, c)
case itemCfg.Bonus != 0:
errcode = errorcode.ErrorCodes.ErrItemUnusable
case itemCfg.HP != 0:
errcode = h.handleRecoverHPItemOutOfFight(itemCfg.HP, currentPet)
case itemCfg.PP != 0:
errcode = h.handleRecoverPPItemOutOfFight(itemCfg.PP, currentPet)
default:
errcode = h.handleRegularPetItem(uint32(data.ItemID), currentPet)
errcode = h.handleRegularPetItem(itemID, currentPet)
if errcode == 0 {
refreshPetPaneKeepHP(currentPet, oldHP)
}
}
if errcode != 0 {
return nil, errcode
}
c.Service.Item.UPDATE(uint32(data.ItemID), -1)
c.Service.Item.UPDATE(itemID, -1)
result = &item.S2C_USE_PET_ITEM_OUT_OF_FIGHT{}
currentPet.CalculatePetPane(100)
copier.Copy(&result, currentPet)
// defer c.Service.Info.Save(*c.Info)
return result, 0
}
@@ -113,14 +130,56 @@ func (h Controller) handlexuancaiItem(currentPet *model.PetInfo, c *player.Playe
return 0
}
func (h Controller) handleRecoverHPItemOutOfFight(recoverHP int, currentPet *model.PetInfo) errorcode.ErrorCode {
if currentPet.Hp >= currentPet.MaxHp {
return errorcode.ErrorCodes.ErrItemUnusable
}
currentPet.ModelHP(int64(recoverHP))
if currentPet.Hp == 0 {
currentPet.Hp = 1
}
return 0
}
func (h Controller) handleRecoverPPItemOutOfFight(recoverPP int, currentPet *model.PetInfo) errorcode.ErrorCode {
if !canRecoverPP(currentPet) {
return errorcode.ErrorCodes.ErrItemUnusable
}
currentPet.HealPP(recoverPP)
return 0
}
func canRecoverPP(currentPet *model.PetInfo) bool {
for _, skill := range currentPet.SkillList {
skillCfg, ok := xmlres.SkillMap[int(skill.ID)]
if ok && skill.PP < uint32(skillCfg.MaxPP) {
return true
}
}
return false
}
func refreshPetPaneKeepHP(currentPet *model.PetInfo, hp uint32) {
currentPet.CalculatePetPane(100)
if hp > currentPet.MaxHp {
currentPet.Hp = currentPet.MaxHp
return
}
currentPet.Hp = hp
}
// handleRegularPetItem 处理普通宠物道具
func (h Controller) handleRegularPetItem(itemID uint32, currentPet *model.PetInfo) errorcode.ErrorCode {
handler := item.PetItemRegistry.GetHandler(itemID)
if handler == nil {
return errorcode.ErrorCodes.ErrSystemError
return errorcode.ErrorCodes.ErrItemUnusable
}
if !handler(itemID, currentPet) {
return errorcode.ErrorCodes.ErrSystemError
return errorcode.ErrorCodes.ErrItemUnusable
}
return 0
}
@@ -139,8 +198,9 @@ func (h Controller) ResetNature(data *item.C2S_PET_RESET_NATURE, c *player.Playe
return nil, errorcode.ErrorCodes.ErrSystemError
}
currentHP := currentPet.Hp
currentPet.Nature = data.Nature
currentPet.CalculatePetPane(100)
refreshPetPaneKeepHP(currentPet, currentHP)
c.Service.Item.UPDATE(data.ItemId, -1)
return result, 0
}