ecs/servers/game/handler/player_hero.go
2025-06-20 15:34:46 +08:00

461 lines
14 KiB
Go

package handler
import (
"ecs/proto"
"ecs/proto/pb"
"ecs/servers/game/logic"
"github.com/oylshe1314/framework/net"
)
func (this *PlayerHandler) HeroUpgrade(player *logic.Player, msg *net.Message) {
var req = new(pb.HeroUpgradeReq)
var err = msg.Read(req)
if err != nil {
this.logger.Error("Read message failed, ", err)
_ = player.TipNotice(proto.TipMessageError)
return
}
if req.HeroUid == 0 {
this.logger.Error("Parameter error, req.HeroUid == 0")
_ = player.TipNotice(proto.TipParameterError)
return
}
var roleHero = player.RoleHero()
if roleHero == nil {
this.logger.Error("Server error, Role hero is nil, req.RoleId: ", player.RoleId)
_ = player.TipNotice(proto.TipServerError)
return
}
if req.HeroUid == roleHero.Uid {
this.logger.Error("Parameter error, Role hero can not upgrade here, req.HeroUid: ", req.HeroUid)
_ = player.TipNotice(proto.TipRoleHeroCanNotUpgrade)
return
}
if req.Levels != 1 && req.Levels != 5 {
_ = player.TipNotice(proto.TipParameterError)
return
}
var hero = player.Hero[req.HeroUid]
if hero == nil {
_ = player.TipNotice(proto.TipHeroNotFound)
return
}
var heroTable = this.tables.Hero.Find1(int(hero.Id))
if heroTable == nil {
_ = player.TipNotice(proto.TipDataTablesError)
return
}
if hero.Level >= uint32(heroTable.Level) {
_ = player.TipNotice(proto.TipLevelAlreadyMax)
return
}
var itemTables = this.tables.Item.Find2(int(pb.ItemType_ItemProp), int(pb.PropType_HeroExp))
if len(itemTables) == 0 {
_ = player.TipNotice(proto.TipDataTablesError)
return
}
var exp = hero.Exp
var level = hero.Level
var consumeItems = map[uint32]uint32{}
for range req.Levels {
var heroLevelTable = this.tables.HeroLevel.Find3(int(hero.Id), int(level))
if heroLevelTable == nil {
_ = player.TipNotice(proto.TipDataTablesError)
return
}
var hasItem = false
for _, itemTable := range itemTables {
var item = player.Item[uint32(itemTable.Id)]
if item == nil || item.Num == 0 {
continue
}
var consumedNum = consumeItems[item.Id]
if item.Num <= consumedNum {
continue
}
var needExp = uint64(heroLevelTable.NeedExp) - exp
var needNums = uint32(needExp / uint64(itemTable.Value))
if needExp%uint64(itemTable.Value) > 0 {
needNums += 1
}
if item.Num-consumedNum < needNums {
consumedNum = item.Num
exp += uint64(itemTable.Value) * uint64(item.Num-consumedNum)
} else {
hasItem = true
consumedNum += needNums
exp += uint64(itemTable.Value) * uint64(needNums)
}
if exp >= uint64(heroLevelTable.NeedExp) {
level += 1
exp -= uint64(heroLevelTable.NeedExp)
}
}
if !hasItem {
break
}
}
if exp == hero.Exp && level == hero.Level {
return
}
hero.Exp = exp
hero.Level = level
player.SaveModel(hero)
player.UpdateHeroAttrs(hero)
player.ReduceItems(consumeItems, logic.LogTypeItemConsumeByHeroUpgrade)
_ = player.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, &pb.HeroChangeListAck{
ChangeList: []*pb.HeroChange{{ChangeType: pb.ChangeType_Changed, Hero: hero.BuildMsgHero()}},
})
// switch proto.EquipType(component.Type) {
// case proto.EquipTypeHead:
// player.CheckTask(proto.TaskSection1UpgradeHeadComponents, 0, 1)
// player.CheckTask(proto.TaskSection1HeadComponentMaxLevel, 0, nextComponentTable.Level)
// case proto.EquipTypeBody:
// player.CheckTask(proto.TaskSection1UpgradeBodyComponents, 0, 1)
// player.CheckTask(proto.TaskSection1BodyComponentMaxLevel, 0, nextComponentTable.Level)
// case proto.EquipTypeTail:
// player.CheckTask(proto.TaskSection1UpgradeTailComponents, 0, 1)
// player.CheckTask(proto.TaskSection1TailComponentMaxLevel, 0, nextComponentTable.Level)
// }
//
// player.UpdateRigAttrs()
//
// player.CheckRigTrammelsStatus(uint32(nextComponentTable.ItemId), uint32(nextComponentTable.Level), 0)
//
// player.CheckTask(proto.TaskSection1UpgradeComponents, 0, 1)
// player.CheckTask(proto.TaskSection1ComponentsAllLevels, 0, int(player.GetAllRigComponentLevels()))
return
}
func (this *PlayerHandler) HeroBreak(player *logic.Player, msg *net.Message) {
var req = new(pb.HeroBreakReq)
var err = msg.Read(req)
if err != nil {
this.logger.Error("Read message failed, ", err)
_ = player.TipNotice(proto.TipMessageError)
return
}
if req.HeroUid == 0 || req.OptItemId == 0 {
_ = player.TipNotice(proto.TipParameterError)
return
}
var hero = player.Hero[req.HeroUid]
if hero == nil {
this.logger.Error("Parameter error, hero was not found, req.HeroUid: ", req.HeroUid)
_ = player.TipNotice(proto.TipHeroNotFound)
return
}
var heroTable = this.tables.Hero.Find1(int(hero.Id))
if heroTable == nil {
_ = player.TipNotice(proto.TipDataTablesError)
return
}
if hero.BreakLevel >= uint32(heroTable.BreaksLevels) {
_ = player.TipNotice(proto.TipHeroBreakLevelAlreadyMax)
return
}
var nextBreakLevelTable = this.tables.HeroBreak.Find3(int(hero.Id), int(hero.BreakLevel+1))
if nextBreakLevelTable == nil {
_ = player.TipNotice(proto.TipDataTablesError)
return
}
for i := range nextBreakLevelTable.ConsumeItems {
if ok, tip := player.CheckItem(uint32(nextBreakLevelTable.ConsumeItems[i]), uint32(nextBreakLevelTable.ConsumeNums[i])); !ok {
_ = player.TipNotice(tip)
return
}
}
var optItemId, optItemNum uint32
for i := range nextBreakLevelTable.OptionalConsumeItems {
if uint32(nextBreakLevelTable.OptionalConsumeItems[i]) == req.OptItemId {
optItemId, optItemNum = uint32(nextBreakLevelTable.OptionalConsumeItems[i]), uint32(nextBreakLevelTable.OptionalConsumeNums[i])
if ok, tip := player.CheckItem(optItemId, optItemNum); !ok {
_ = player.TipNotice(tip)
return
}
}
}
if optItemId == 0 {
_ = player.TipNotice(proto.TipParameterError)
return
}
hero.BreakLevel = uint32(nextBreakLevelTable.BreakLevel)
player.SaveModel(hero)
player.UpdateHeroAttrs(hero)
for i := range nextBreakLevelTable.ConsumeItems {
player.ReduceItem(uint32(nextBreakLevelTable.ConsumeItems[i]), uint32(nextBreakLevelTable.ConsumeNums[i]), logic.LogTypeItemConsumeByHeroBreak)
}
player.ReduceItem(optItemId, optItemNum, logic.LogTypeItemConsumeByHeroBreak)
}
func (this *PlayerHandler) HeroAwaken(player *logic.Player, msg *net.Message) {
}
func (this *PlayerHandler) HeroSoul(player *logic.Player, msg *net.Message) {
var req = new(pb.HeroSoulReq)
var err = msg.Read(req)
if err != nil {
this.logger.Error("Read message failed, ", err)
_ = player.TipNotice(proto.TipMessageError)
return
}
if req.HeroUid == 0 {
this.logger.Error("Parameter error, req.HeroUid == 0 ")
_ = player.TipNotice(proto.TipParameterError)
return
}
var hero = player.Hero[req.HeroUid]
if hero == nil {
this.logger.Error("Parameter error, hero was not found req.HeroUid: ", req.HeroUid)
_ = player.TipNotice(proto.TipHeroNotFound)
return
}
if req.SoulLevel == 0 {
this.logger.Error("Parameter error, req.SoulLevel == 0")
_ = player.TipNotice(proto.TipParameterError)
return
}
if req.SoulLevel > hero.SoulLevel+1 {
this.logger.Errorf("Parameter error, req.SoulLevel: %d, hero.SoulLevel: %d", req.SoulLevel, hero.SoulLevel)
_ = player.TipNotice(proto.TipHeroSoulCanNotUpgrade)
return
}
var soulTable = this.tables.HeroSoul.Find3(int(hero.Id), int(req.SoulLevel))
if soulTable == nil {
this.logger.Error("Parameter or data error, table 'HeroSoul' was not found, req.HeroUid: ", req.HeroUid)
_ = player.TipNotice(proto.TipDataTablesError)
return
}
if req.SoulSkill != uint32(soulTable.SoulSkillLeft) && req.SoulSkill != uint32(soulTable.SoulSkillRight) {
this.logger.Errorf("Parameter or data error, req.SoulSkill: %d, soulTable.SoulSkillLeft: %d, soulTable.SoulSkillRight: %d",
req.SoulSkill, soulTable.SoulSkillLeft, soulTable.SoulSkillRight)
_ = player.TipNotice(proto.TipDataTablesError)
return
}
var consumeItems = map[uint32]uint32{}
var consumeHeroes = map[uint64]*logic.PlayerHero{}
if req.SoulLevel == hero.SoulLevel {
if req.ConsumeLeftNum+uint32(len(req.ConsumeLeft)) != uint32(soulTable.ConsumeLeftNum) {
this.logger.Errorf("Parameter error, soulTable.ConsumeLeftNum: %d, req.ConsumeLeftNum: %d, req.ConsumeLeft: %v",
soulTable.ConsumeLeftNum,
req.ConsumeLeftNum,
req.ConsumeLeft)
_ = player.TipNotice(proto.TipParameterError)
return
}
if req.ConsumeRightNum+uint32(len(req.ConsumeRight)) != uint32(soulTable.ConsumeRightNum) {
this.logger.Errorf("Parameter error, soulTable.ConsumeRightNum: %d, req.ConsumeRightNum: %d, req.ConsumeRight: %v",
soulTable.ConsumeRightNum,
req.ConsumeRightNum,
req.ConsumeRight)
_ = player.TipNotice(proto.TipParameterError)
return
}
if req.ConsumeMiddleNum != uint32(soulTable.ConsumeMiddleNum) {
this.logger.Errorf("Parameter error, soulTable.ConsumeMiddleNum: %d, req.ConsumeMiddleNum: %d", soulTable.ConsumeMiddleNum, req.ConsumeMiddleNum)
_ = player.TipNotice(proto.TipParameterError)
return
}
if req.ConsumeLeftNum > 0 {
ok, tip := player.CheckItem(uint32(soulTable.ConsumeLeftFirst), req.ConsumeLeftNum)
if !ok {
_ = player.TipNotice(tip)
return
}
consumeItems[uint32(soulTable.ConsumeLeftFirst)] = req.ConsumeLeftNum
}
for i, consumeHeroUid := range req.ConsumeLeft {
if consumeHeroUid == 0 {
this.logger.Errorf("Parameter error, will be consumed hero was not found, req.ConsumeLeft[%d] = %d", i, consumeHeroUid)
_ = player.TipNotice(proto.TipParameterError)
return
}
if _, ok := consumeHeroes[consumeHeroUid]; ok {
this.logger.Errorf("Parameter error, repeated consume the same hero, req.ConsumeLeft[%d] = %d", i, consumeHeroUid)
_ = player.TipNotice(proto.TipParameterError)
return
}
if consumeHero, ok := player.Hero[consumeHeroUid]; !ok {
this.logger.Errorf("Parameter error, could not find the hero that will be consumed, req.ConsumeLeft[%d] = %d", i, consumeHeroUid)
_ = player.TipNotice(proto.TipParameterError)
return
} else {
consumeHeroes[consumeHero.Uid] = consumeHero
}
}
if req.ConsumeRightNum > 0 {
ok, tip := player.CheckItem(uint32(soulTable.ConsumeRightFirst), req.ConsumeRightNum)
if !ok {
_ = player.TipNotice(tip)
return
}
consumeItems[uint32(soulTable.ConsumeRightFirst)] = req.ConsumeRightNum
}
for i, consumeHeroUid := range req.ConsumeRight {
if consumeHeroUid == 0 {
this.logger.Errorf("Parameter error, req.ConsumeRight[%d] == 0", i)
_ = player.TipNotice(proto.TipParameterError)
return
}
if _, ok := consumeHeroes[consumeHeroUid]; ok {
this.logger.Errorf("Parameter error, repeated consume the same hero, req.ConsumeRight[%d] = %d", i, consumeHeroUid)
_ = player.TipNotice(proto.TipParameterError)
return
}
if consumeHero, ok := player.Hero[consumeHeroUid]; !ok {
this.logger.Errorf("Parameter error, could not find the hero that will be consumed, req.ConsumeRight[%d] = %d", i, consumeHeroUid)
_ = player.TipNotice(proto.TipParameterError)
return
} else {
consumeHeroes[consumeHero.Uid] = consumeHero
}
}
ok, tip := player.CheckItem(uint32(soulTable.ConsumeMiddle), uint32(soulTable.ConsumeMiddleNum))
if !ok {
_ = player.TipNotice(tip)
return
}
consumeItems[uint32(soulTable.ConsumeMiddle)] = uint32(soulTable.ConsumeMiddleNum)
}
if req.SoulLevel <= hero.SoulLevel {
if hero.SoulSkill[req.SoulLevel-1] != req.SoulSkill {
hero.SoulSkill[req.SoulLevel-1] = req.SoulSkill
player.SaveModel(hero)
_ = player.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, &pb.HeroChangeListAck{
ChangeList: []*pb.HeroChange{{ChangeType: pb.ChangeType_Changed, Hero: hero.BuildMsgHero()}},
})
}
} else {
hero.SoulLevel = uint32(soulTable.Level)
hero.SoulSkill = append(hero.SoulSkill, req.SoulSkill)
player.SaveModel(hero)
_ = player.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, &pb.HeroChangeListAck{
ChangeList: []*pb.HeroChange{{ChangeType: pb.ChangeType_Changed, Hero: hero.BuildMsgHero()}},
})
player.ReduceItems(consumeItems, logic.LogTypeItemConsumeByHeroSoul)
player.ReduceHeroes(consumeHeroes, logic.LogTypeHeroConsumeByHeroSoul)
}
}
func (this *PlayerHandler) HeroFateBreak(player *logic.Player, msg *net.Message) {
}
func (this *PlayerHandler) HeroQuality(player *logic.Player, msg *net.Message) {
}
func (this *PlayerHandler) HeroBookActivate(player *logic.Player, msg *net.Message) {
var req = new(pb.HeroBookActivateReq)
var err = msg.Read(req)
if err != nil {
this.logger.Error("Read message failed, ", err)
_ = player.TipNotice(proto.TipMessageError)
return
}
if req.HeroId == 0 {
this.logger.Error("Parameter error, req.HeroId == 0 ")
_ = player.TipNotice(proto.TipParameterError)
return
}
var heroBook = player.HeroBook[req.HeroId]
if heroBook == nil {
_ = player.TipNotice(proto.TipHeroNotFound)
return
}
if req.Index >= uint32(len(heroBook.Items)) {
_ = player.TipNotice(proto.TipParameterError)
return
}
var heroBookTables = this.tables.HeroBook.Find2(int(heroBook.HeroId))
if len(heroBookTables) != len(heroBook.Items) {
_ = player.TipNotice(proto.TipDataTablesError)
return
}
if pb.AbleStatus(heroBook.Items[req.Index][1]) == pb.AbleStatus_Already {
_ = player.TipNotice(proto.TipHeroBookActivated)
return
}
if pb.AbleStatus(heroBook.Items[req.Index][1]) == pb.AbleStatus_Unable {
_ = player.TipNotice(proto.TipHeroBookCanNotActivate)
return
}
heroBook.Items[req.Index][1] = uint32(pb.AbleStatus_Already)
player.SaveModel(heroBook)
for _, hero := range player.Hero {
if hero.Id == heroBook.HeroId {
player.UpdateHeroAttrs(hero)
}
}
_ = player.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroBookChange, &pb.HeroBookListAck{
BookList: []*pb.HeroBook{heroBook.BuildMsgHeroBook()},
})
}