pet_home_server/src/server/game/mod/chess/Chess.go
2025-08-22 16:47:13 +08:00

620 lines
14 KiB
Go

package chess
import (
"errors"
"fmt"
"server/GoUtil"
mergeDataCfg "server/conf/mergeData"
startMergeCfg "server/conf/startMerge"
userCfg "server/conf/user"
"server/game/mod/item"
"server/msg"
"sort"
"strings"
)
const (
ModuleName = "chess"
ChessBoradMaxNum = 63
CHESS_ENERGY_CHEST = 562
CHESS_SURPRISE_CHEST_LOCK = 563
CHESS_SURPRISE_CHEST = 564
CHESS_ZIXUAN_CHEST = 701 // 自选宝箱
CHESS_HIGH_ZIXUAN_CHEST = 702 // 高级自选宝箱
CHESS_TREASURE_CHEST = 703 // 宝藏宝箱
CHESS_HIGH_TREASURE_CHEST = 704 // 高级宝藏宝箱
CHESS_SOURCE_CHEST = 705 // 资源补给箱
CHESS_HIGH_SOURCE_CHEST = 706 // 高级资源补给箱
CHESS_SEPARATE = 707 // 分解器
CHESS_UPGRADE = 708 // 升级器
)
const (
EMIT_RETIRE_START = 1
EMIT_RETIRE_ING = 2
EMIT_RETIRE_END = 3
)
type ChessBorad struct {
ChessList []int
EmitList map[int]int
ChessBuff []int
ChessBag ChessBag
PartBag PartBag
ChessMap map[string]int32
Honor map[int]int // 荣誉室
Retire map[string]int // 退役发射器系列
RetireChessMap map[string][]int
}
type PartBag struct {
List map[int]PartBagGrid // 零件背包
}
type ChessBag struct {
List map[int]ChessBagGrid
Buy int
Free int
}
type ChessBagGrid struct {
ChessId int // 棋子id
EmitId int // 发射器id
}
type PartBagGrid struct {
PartId int // 零件id
Num int // 零件数量
}
func (cb *ChessBorad) IsEmpty() bool {
cb.ver()
return len(cb.ChessList) == 0
}
// 初始化棋盘
func (cb *ChessBorad) InitData() {
StartMerge := startMergeCfg.GetStartChessList()
cb.EmitList = make(map[int]int)
cb.ChessList = StartMerge
if cb.ChessBag.List == nil {
cb.ChessBag.List = make(map[int]ChessBagGrid)
InitNum := mergeDataCfg.GetChessBagInitNum()
for i := 1; i <= InitNum; i++ {
cb.ChessBag.List[i] = ChessBagGrid{}
}
}
}
func (cb *ChessBorad) ver() {
if cb.EmitList == nil {
cb.EmitList = make(map[int]int)
}
if cb.ChessBag.List == nil {
cb.ChessBag.List = make(map[int]ChessBagGrid)
InitNum := mergeDataCfg.GetChessBagInitNum()
for i := 1; i <= InitNum; i++ {
cb.ChessBag.List[i] = ChessBagGrid{}
}
}
if cb.ChessMap == nil {
cb.ChessMap = make(map[string]int32)
}
if cb.RetireChessMap == nil {
cb.RetireChessMap = make(map[string][]int)
}
if cb.Retire == nil {
cb.Retire = make(map[string]int)
}
if cb.Honor == nil {
cb.Honor = make(map[int]int)
}
}
func (cb *ChessBorad) GetChessBuf() []int {
return cb.ChessBuff
}
// 棋子合成
func (cb *ChessBorad) ComposeChess(id int) (int, error) {
CfgRecord, err := mergeDataCfg.GetOne(id)
if err != nil {
return 0, errors.New("配置错误")
}
if CfgRecord.Lv == CfgRecord.MaxLv {
return 0, errors.New("已达最大等级")
}
count := 0
newList := make([]int, 0)
for _, chess := range cb.ChessList {
if chess == id && count < 2 {
count++
continue
}
newList = append(newList, chess)
}
if count < 2 {
return 0, errors.New("次数不足" + fmt.Sprintf("Id: %d", id))
}
ChessType := mergeDataCfg.GetTypeById(id)
if ChessType == "Emitter" {
cb.EmitList[id+1]++
cb.EmitList[id]--
cb.EmitList[id]--
}
id++
newList = append(newList, id)
cb.ChessList = newList
return id, nil
}
func (cb *ChessBorad) GetChessList() []int {
return cb.ChessList
}
func (cb *ChessBorad) GetUnlockChessList() []int {
r := make([]int, 0, len(cb.ChessList))
for k, v := range cb.ChessMap {
arr := strings.Split(k, "@")
if arr[2] == "0" {
r = append(r, int(v))
}
}
return r
}
// func (cb *ChessBorad) GetUnlockChessList() []int {
// return cb.ChessBag.List
// }
// 添加棋子
func (cb *ChessBorad) AddChess(id int) error {
_, err := mergeDataCfg.GetOne(id)
if err != nil {
return errors.New("配置错误")
}
NewChessList := append(cb.ChessList, id)
if len(NewChessList) > ChessBoradMaxNum { // 棋盘满了 加入缓存区
cb.ChessBuff = append(cb.ChessBuff, id)
return nil
}
ChessType := mergeDataCfg.GetTypeById(id)
if ChessType == "Emitter" {
cb.EmitList[id]++
}
cb.ChessList = append(cb.ChessList, id)
return nil
}
// 购买棋子
func (cb *ChessBorad) BuyChess(id int) (int, error) {
CfgRecord, err := mergeDataCfg.GetOne(id)
if err != nil {
return 0, errors.New("配置错误")
}
cb.ChessList = append(cb.ChessList, id)
ChessType := mergeDataCfg.GetTypeById(id)
if ChessType == "Emitter" {
cb.EmitList[id]++
}
return CfgRecord.SellNum, nil
}
// 出售棋子
func (cb *ChessBorad) SellChess(id int) ([]*item.Item, error) {
CfgRecord, err := mergeDataCfg.GetOne(id)
if err != nil {
return nil, errors.New("配置错误")
}
count := 0
newList := make([]int, 0, len(cb.ChessList))
for _, chess := range cb.ChessList {
if chess == id && count < 1 {
count++
continue
}
newList = append(newList, chess)
}
if count < 1 {
return nil, errors.New("次数不足")
}
cb.ChessList = newList
var items []*item.Item
switch CfgRecord.SellType {
case "star":
items = append(items, &item.Item{Id: item.ITEM_STAR_ID, Num: CfgRecord.SellNum})
case "diamond":
items = append(items, &item.Item{Id: item.ITEM_DIAMOND_ID, Num: CfgRecord.SellNum})
case "energy":
items = append(items, &item.Item{Id: item.ITEM_ENERGY_ID, Num: CfgRecord.SellNum})
case "Racing Battery":
items = append(items, &item.Item{Id: item.ITEM_RACING_BATTERY_ID, Num: CfgRecord.SellNum})
}
return items, nil
}
// 移除棋子
func (cb *ChessBorad) RemoveChess(Id int) error {
find := false
for k, v := range cb.ChessList {
if v == Id {
cb.ChessList = append(cb.ChessList[:k], cb.ChessList[k+1:]...)
find = true
break
}
}
if !find {
return errors.New("chess id not exist")
}
ChessType := mergeDataCfg.GetTypeById(Id)
if ChessType == "Emitter" {
v, ok := cb.EmitList[Id]
if v > 0 && ok {
cb.EmitList[Id]--
}
}
return nil
}
func (cb *ChessBorad) GetEmitList() []int {
result := make([]int, 0, len(cb.EmitList))
EM := make(map[string]int)
for k, v := range cb.EmitList {
if v <= 0 {
delete(cb.EmitList, k)
continue
}
EmitID := mergeDataCfg.GetEmitId(k)
if EmitID == "" {
continue
}
if cb.Retire[EmitID] == EMIT_RETIRE_START {
continue
}
EmitType := mergeDataCfg.GetEmitType(k)
if EmitType == "sub" {
continue
}
if v > 0 {
EM[EmitID] = max(EM[EmitID], k)
}
}
for _, v := range EM {
result = append(result, v)
}
return result
}
// 完成订单 移除棋子
func (cb *ChessBorad) FinishOrder(ChessId []int) error {
for _, v := range ChessId {
err := cb.FinishOrderChess(v)
if err != nil {
return err
}
}
return nil
}
func (cb *ChessBorad) FinishOrderChess(Chess int) error {
for k, v := range cb.ChessList {
if v == Chess {
cb.ChessList = append(cb.ChessList[:k], cb.ChessList[k+1:]...)
return nil
}
}
for k, v := range cb.ChessBag.List {
if v.ChessId == Chess {
cb.ChessBag.List[k] = ChessBagGrid{}
return nil
}
}
return errors.New("order finish chess id not exist")
}
// 棋子转换
func (cb *ChessBorad) ExChess(OldChessId, NewChessId int) error {
if OldChessId > 0 {
newList, b := GoUtil.PopElemSlice(cb.ChessList, OldChessId)
if !b {
return fmt.Errorf("ExChess chess id not exist")
}
cb.ChessList = newList
}
return cb.AddChess(NewChessId)
}
// 增加棋盘缓冲器
func (cb *ChessBorad) AddChessBuff(chess int) {
cb.ChessBuff = append(cb.ChessBuff, chess)
}
func (cb *ChessBorad) AddHonor(Id int) {
cb.Honor[Id] = 1
}
func (cb *ChessBorad) RemoveHonor(Id int) {
delete(cb.Honor, Id)
}
func (cb *ChessBorad) GetChessFromBuff(Chess int) error {
for i, v := range cb.ChessBuff {
if v == Chess {
cb.ChessBuff = append(cb.ChessBuff[:i], cb.ChessBuff[i+1:]...)
cb.AddChess(Chess)
return nil
}
}
return errors.New("chess id not exist")
}
// 返回数据
func (cb *ChessBorad) BackData() *msg.ResPlayerChessInfo {
var ChessBagGrids []*msg.ChessBagGrid
for k, v := range cb.ChessBag.List {
ChessBagGrids = append(ChessBagGrids, &msg.ChessBagGrid{
Id: int32(k),
ChessId: int32(v.ChessId),
EmitId: int32(v.EmitId),
})
}
var PartBagGrids []*msg.PartBagGrid
for k, v := range cb.PartBag.List {
PartBagGrids = append(PartBagGrids, &msg.PartBagGrid{
PartId: int32(k),
Count: int32(v.Num),
})
}
Re := make([]string, 0)
for k, v := range cb.Retire {
if v == 3 {
Re = append(Re, k)
}
}
Ho := make([]int32, 0)
for k := range cb.Honor {
Ho = append(Ho, int32(k))
}
return &msg.ResPlayerChessInfo{
ChessList: GoUtil.SliceIntToInt32(cb.ChessList),
ChessBuff: GoUtil.SliceIntToInt32(cb.ChessBuff),
RetireEmit: Re,
Honor: Ho,
ChessBag: &msg.ChessBag{
ChessBagGrids: ChessBagGrids,
ChessBuyCnt: int32(cb.ChessBag.Buy),
ChessFreeCnt: int32(cb.ChessBag.Free),
},
PartBag: &msg.PartBag{
PartBagGrids: PartBagGrids,
},
}
}
// 解锁棋盘背包
func (cb *ChessBorad) BuyChessBagGrid() error {
if cb.ChessBag.Free > 0 {
cb.ChessBag.List[len(cb.ChessBag.List)+1] = ChessBagGrid{}
cb.ChessBag.Free--
return nil
}
MaxBuy := mergeDataCfg.GetChessBagBugNum()
if cb.ChessBag.Buy >= MaxBuy {
return fmt.Errorf("ChessBag can buy is full")
}
cb.ChessBag.Buy++
cb.ChessBag.List[len(cb.ChessBag.List)+1] = ChessBagGrid{}
return nil
}
func (cb *ChessBorad) GetBuyChessBagGridCost() []*item.Item {
if cb.ChessBag.Free > 0 {
return nil
}
NeedDiamond := 10 + 15*cb.ChessBag.Buy
return []*item.Item{{Id: item.ITEM_DIAMOND_ID, Num: -NeedDiamond}}
}
// 升级触发解锁棋盘背包
func (cb *ChessBorad) TriggerChessBagUnlock(Lv int) bool {
UnlockPack := userCfg.GetUnlockPack(Lv)
if UnlockPack > 0 {
cb.ChessBag.Free += UnlockPack
return true
}
return false
}
func (cb *ChessBorad) PutChessInBag(Grid, ChessId, EmitId int) error {
err := cb.RemoveChess(ChessId)
if err != nil {
return err
}
EmitColorId := mergeDataCfg.GetEmitId(ChessId)
ChessLv := mergeDataCfg.GetLvById(ChessId)
ChessMaxLv := mergeDataCfg.GetMaxLvById(ChessId)
if ChessLv == ChessMaxLv && cb.Retire[EmitColorId] == 3 { // 退役发射器 加入荣誉室
cb.AddHonor(ChessId)
return nil
}
v, ok := cb.ChessBag.List[Grid]
if !ok {
return errors.New("ChessBag Grid unlock")
}
if v.ChessId > 0 {
return errors.New("ChessBag Grid is not empty")
}
cb.ChessBag.List[Grid] = ChessBagGrid{
ChessId: ChessId,
EmitId: EmitId,
}
return nil
}
func (cb *ChessBorad) PutPartInBag(ChessId int) error {
err := cb.RemoveChess(ChessId)
if err != nil {
return err
}
ChessLv := mergeDataCfg.GetLvById(ChessId)
ChessMaxLv := mergeDataCfg.GetMaxLvById(ChessId)
if ChessLv != ChessMaxLv { // 零件只能放入满级棋子
return errors.New("part Lv is not max")
}
Num := 0
v, ok := cb.PartBag.List[ChessId]
if ok {
Num = v.Num
}
cb.PartBag.List[ChessId] = PartBagGrid{
PartId: ChessId,
Num: Num + 1,
}
return nil
}
func (cb *ChessBorad) TakeChessOutBag(Grid int) (int, error) {
if Grid < 0 {
cb.RemoveHonor(-Grid)
cb.AddChess(-Grid)
return 0, nil
}
GridInfo, ok := cb.ChessBag.List[Grid]
if !ok {
return 0, errors.New("ChessBag Grid unlock")
}
if GridInfo.ChessId == 0 {
return 0, errors.New("ChessBag Grid is empty")
}
cb.ChessBag.List[Grid] = ChessBagGrid{}
return GridInfo.ChessId, cb.AddChess(GridInfo.ChessId)
}
func (cb *ChessBorad) GetOrderEmit() []int {
return cb.GetEmitList()
}
func (cb *ChessBorad) GetRetireEmit() map[string]int {
return cb.Retire
}
func (cb *ChessBorad) GetRetireChess(EmitType string) []int {
v, ok := cb.RetireChessMap[EmitType]
if !ok {
return nil
}
if len(v) == 1 {
cb.RetireChessMap[EmitType] = nil
return v
}
if len(v) == 0 {
return nil
}
cb.RetireChessMap[EmitType] = v[2:]
return v[:2]
}
func (cb *ChessBorad) BeginRetire(EmitType string) error {
_, ok := cb.Retire[EmitType]
if ok {
return errors.New("chess has been retired")
}
cb.Retire[EmitType] = EMIT_RETIRE_START
return nil
}
func (cb *ChessBorad) RetireOrder(EmitType string) error {
if cb.Retire[EmitType] != 1 {
return errors.New("chess has not been retired")
}
chess := make([]int, 0)
EmitProduct := mergeDataCfg.GetEmitProduce(EmitType)
for k, v := range cb.ChessMap {
arr := strings.Split(k, "@")
Color := mergeDataCfg.GetColorById(int(v))
if arr[2] == "0" && GoUtil.InStringArray(Color, EmitProduct) {
chess = append(chess, int(v))
}
}
sort.Sort(sort.Reverse(sort.IntSlice(chess)))
cb.RetireChessMap[EmitType] = chess
cb.Retire[EmitType] = EMIT_RETIRE_ING
return nil
}
func (cb *ChessBorad) FinishRetire(EmitType string) error {
_, ok := cb.Retire[EmitType]
if !ok {
return errors.New("chess has not been retired")
}
cb.Retire[EmitType] = EMIT_RETIRE_END
return nil
}
func (cb *ChessBorad) SourceChest(ChessId int) ([]*item.Item, error) {
err := cb.RemoveChess(ChessId)
if err != nil {
return nil, err
}
if ChessId == CHESS_SOURCE_CHEST {
return mergeDataCfg.GetSourceChestItem(), nil
}
if ChessId == CHESS_HIGH_SOURCE_CHEST {
return mergeDataCfg.GetHighSourceChestItem(), nil
}
return nil, nil
}
func (cb *ChessBorad) SeparateChess(ChessId int) (int, error) {
ChessLv := mergeDataCfg.GetLvById(ChessId)
if ChessLv == 1 {
return 0, errors.New("chess lv is 1")
}
ChessType := mergeDataCfg.GetTypeById(ChessId)
if ChessType != "Product" {
return 0, errors.New("chess type is not product")
}
err := cb.RemoveChess(ChessId)
if err != nil {
return 0, err
}
err = cb.RemoveChess(CHESS_SEPARATE)
if err != nil {
return 0, err
}
ChessColor := mergeDataCfg.GetColorById(ChessId)
NewChess := mergeDataCfg.GetChessIdByLvAndColor(ChessLv-1, ChessColor)
cb.AddChess(NewChess)
cb.AddChess(NewChess)
return NewChess, nil
}
func (cb *ChessBorad) UpgradeChess(ChessId int) (int, error) {
ChessLv := mergeDataCfg.GetLvById(ChessId)
ChessMaxLv := mergeDataCfg.GetMaxLvById(ChessId)
if ChessLv == ChessMaxLv {
return 0, errors.New("chess lv is max")
}
ChessType := mergeDataCfg.GetTypeById(ChessId)
if ChessType != "Product" {
return 0, errors.New("chess type is not product")
}
err := cb.RemoveChess(ChessId)
if err != nil {
return 0, err
}
err = cb.RemoveChess(CHESS_UPGRADE)
if err != nil {
return 0, err
}
NewChess := mergeDataCfg.GetChessIdByLvAndColor(ChessLv+1, mergeDataCfg.GetColorById(ChessId))
cb.AddChess(NewChess)
return NewChess, nil
}