package logic import ( "ecs/proto/pb" "ecs/servers/game/data" "github.com/oylshe1314/framework/util" "slices" ) type Attrs [pb.AttrType_Nums]uint64 type PlayerHero struct { Uid uint64 `json:"uid" key:"1"` Id uint32 `bson:"id"` Exp uint64 `bson:"exp"` Level uint32 `bson:"level"` BreakLevel uint32 `bson:"break_level"` SoulLevel uint32 `bson:"soul_level"` SoulSkill []uint32 `bson:"soul_skill"` Awaken uint32 `bson:"awaken"` InLineup bool `bson:"in_lineup"` attrs Attrs } func (this *PlayerHero) BuildMsgHero() *pb.Hero { return &pb.Hero{ Uid: this.Uid, Id: this.Id, Exp: this.Exp, Level: this.Level, BreakLevel: this.BreakLevel, SoulLevel: this.SoulLevel, SoulSkill: this.SoulSkill, Awaken: this.Awaken, InLineup: this.InLineup, Attrs: this.attrs[:], } } func (this *PlayerHero) Attrs() Attrs { return this.attrs } func (this *Player) newHero(heroTable *data.Hero) *PlayerHero { var hero = &PlayerHero{ Uid: util.RandomUid(), Id: uint32(heroTable.Id), } var heroLevelTable *data.HeroLevel if heroTable.Level > 0 { heroLevelTable = this.manager.tables.HeroLevel.Find3(heroTable.Id, 1) if heroLevelTable == nil { this.manager.logger.Errorf("Find hero level table failed, heroId %d, level: %d", heroTable.Id, 1) return nil } hero.Level = uint32(heroLevelTable.Level) } var heroBreakTable *data.HeroBreak if heroTable.BreaksLevels > 0 { heroBreakTable = this.manager.tables.HeroBreak.Find3(heroTable.Id, 0) if heroBreakTable == nil { this.manager.logger.Errorf("Find hero break table failed, heroId %d, level: %d", heroTable.Id, 1) return nil } hero.BreakLevel = uint32(heroBreakTable.BreakLevel) } //SoulLevel //Awaken return hero } func (this *Player) AddHero(heroId uint32) bool { var heroTable = this.manager.tables.Hero.Find1(int(heroId)) if heroTable == nil { this.manager.logger.Error("Find hero table failed, heroId: ", heroId) return false } var hero = this.newHero(heroTable) if hero == nil { return false } this.Hero[hero.Uid] = hero this.SaveModel(hero) this.addHeroBook(hero.Id) return true } func (this *Player) calcHeroLevelAttrs(hero *PlayerHero) (attrs Attrs) { var heroLevelTable = this.manager.tables.HeroLevel.Find3(int(hero.Id), int(hero.Level)) if heroLevelTable != nil { attrs[heroLevelTable.AttrType1] = uint64(heroLevelTable.AttrValue1) attrs[heroLevelTable.AttrType2] = uint64(heroLevelTable.AttrValue2) attrs[heroLevelTable.AttrType3] = uint64(heroLevelTable.AttrValue3) attrs[heroLevelTable.AttrType4] = uint64(heroLevelTable.AttrValue4) attrs[heroLevelTable.AttrType5] = uint64(heroLevelTable.AttrValue5) attrs[heroLevelTable.AttrType6] = uint64(heroLevelTable.AttrValue6) attrs[heroLevelTable.AttrType7] = uint64(heroLevelTable.AttrValue7) attrs[heroLevelTable.AttrType8] = uint64(heroLevelTable.AttrValue8) attrs[heroLevelTable.AttrType9] = uint64(heroLevelTable.AttrValue9) attrs[heroLevelTable.AttrType10] = uint64(heroLevelTable.AttrValue10) } return } func (this *Player) calcHeroBreakAttrs(hero *PlayerHero) (attrs Attrs) { var heroBreakTable = this.manager.tables.HeroBreak.Find3(int(hero.Id), int(hero.BreakLevel)) if heroBreakTable != nil { attrs[heroBreakTable.AttrType1] = uint64(heroBreakTable.AttrValue1) attrs[heroBreakTable.AttrType2] = uint64(heroBreakTable.AttrValue2) attrs[heroBreakTable.AttrType3] = uint64(heroBreakTable.AttrValue3) attrs[heroBreakTable.AttrType4] = uint64(heroBreakTable.AttrValue4) attrs[heroBreakTable.AttrType5] = uint64(heroBreakTable.AttrValue5) attrs[heroBreakTable.AttrType6] = uint64(heroBreakTable.AttrValue6) attrs[heroBreakTable.AttrType7] = uint64(heroBreakTable.AttrValue7) attrs[heroBreakTable.AttrType8] = uint64(heroBreakTable.AttrValue8) attrs[heroBreakTable.AttrType9] = uint64(heroBreakTable.AttrValue9) attrs[heroBreakTable.AttrType10] = uint64(heroBreakTable.AttrValue10) } return } func (this *Player) calcHeroAwakenAttrs(hero *PlayerHero) (attrs Attrs) { return } func (this *Player) calcHeroBookAttrs(hero *PlayerHero) (attrs Attrs) { var heroBook = this.HeroBook[hero.Id] if heroBook == nil { return } for _, item := range heroBook.Items { if pb.AbleStatus(item[1]) != pb.AbleStatus_Already { continue } var heroGeneralTable = this.manager.tables.HeroBook.Find1(int(item[0])) if heroGeneralTable == nil { continue } attrs[heroGeneralTable.AttrType1] += uint64(heroGeneralTable.AttrValue1) attrs[heroGeneralTable.AttrType2] += uint64(heroGeneralTable.AttrValue2) attrs[heroGeneralTable.AttrType3] += uint64(heroGeneralTable.AttrValue3) } return } func (this *Player) calcHeroBondAttrs(hero *PlayerHero, lineup *PlayerLineup, lineupHero *PlayerLineupHero) (attrs Attrs) { if lineup == nil || lineupHero == nil { return } var heroBondTables = this.manager.tables.HeroBond.Find(int(hero.Id)) for i := range heroBondTables { var yes = false switch heroBondTables[i].BondType { case 1: //装备 for _, equipUid := range lineupHero.Equip { if equipUid == 0 { continue } if equip, ok := this.Equip[equipUid]; ok && slices.Contains(heroBondTables[i].BondId, int(equip.Id)) { yes = true break } } case 2: //宝物 for _, treasureUid := range lineupHero.Treasure { if treasureUid == 0 { continue } if treasure, ok := this.Treasure[treasureUid]; ok && slices.Contains(heroBondTables[i].BondId, int(treasure.Id)) { yes = true break } } case 3: //神兵 for _, artifactUid := range lineupHero.Artifact { if artifactUid == 0 { continue } if artifact, ok := this.Artifact[artifactUid]; ok && slices.Contains(heroBondTables[i].BondId, int(artifact.Id)) { yes = true break } } case 4: //英雄 var bondIdMap = map[int]struct{}{} for _, bondId := range heroBondTables[i].BondId { bondIdMap[bondId] = struct{}{} } for hi := range lineup.Heroes { if lineup.Heroes[i] == nil { continue } if another, ok := this.Hero[lineup.Heroes[hi].HeroUid]; ok { delete(bondIdMap, int(another.Id)) } } for hi := range lineup.Helper { if lineup.Helper[hi] == 0 { continue } if helper, ok := this.Hero[lineup.Helper[hi]]; ok { delete(bondIdMap, int(helper.Id)) } } yes = len(bondIdMap) == 0 } if yes { attrs[heroBondTables[i].AttrType1] += uint64(heroBondTables[i].AttrValue1) attrs[heroBondTables[i].AttrType2] += uint64(heroBondTables[i].AttrValue2) attrs[heroBondTables[i].AttrType3] += uint64(heroBondTables[i].AttrValue3) } } return } func (this *Player) calcHeroEquipsAttrs(hero *PlayerHero, lineup *PlayerLineup, lineupHero *PlayerLineupHero) (attrs Attrs) { if lineup == nil || lineupHero == nil { return } for _, equipUid := range lineupHero.Equip { if equipUid == 0 { continue } var equip = this.Equip[equipUid] var equipLevelTable = this.manager.tables.EquipLevel.Find3(int(equip.Id), int(equip.Level)) if equipLevelTable != nil { attrs[equipLevelTable.AttrType] += uint64(equipLevelTable.AttrValue) } } return } func (this *Player) calcHeroTreasuresAttrs(hero *PlayerHero, lineup *PlayerLineup, lineupHero *PlayerLineupHero) (attrs Attrs) { if lineup == nil || lineupHero == nil { return } for _, treasureUid := range lineupHero.Treasure { if treasureUid == 0 { continue } var treasure = this.Treasure[treasureUid] var treasureLevelTable = this.manager.tables.TreasureLevel.Find3(int(treasure.Id), int(treasure.Level)) if treasureLevelTable != nil { attrs[treasureLevelTable.AttrType] += uint64(treasureLevelTable.AttrValue) } } return } func (this *Player) calcHeroMountsAttrs(hero *PlayerHero, lineup *PlayerLineup, lineupHero *PlayerLineupHero) (attrs Attrs) { if lineup == nil || lineupHero == nil { return } return } func (this *Player) calcHeroArtifactAttrs(hero *PlayerHero, lineup *PlayerLineup, lineupHero *PlayerLineupHero) (attrs Attrs) { if lineup == nil || lineupHero == nil { return } return } func (this *Player) calcHeroAttrs(hero *PlayerHero, attrsList ...Attrs) bool { var newAttrs Attrs for _, attrs := range attrsList { for i, attr := range attrs { newAttrs[i] += attr } } for i := range newAttrs { if hero.attrs[i] != newAttrs[i] { hero.attrs = newAttrs return true } } return false } func (this *Player) updateHeroAttrs(hero *PlayerHero, lineup *PlayerLineup, lineupHero *PlayerLineupHero) bool { return this.calcHeroAttrs(hero, this.calcHeroLevelAttrs(hero), this.calcHeroBreakAttrs(hero), this.calcHeroAwakenAttrs(hero), this.calcHeroBookAttrs(hero), this.calcHeroBondAttrs(hero, lineup, lineupHero), this.calcHeroEquipsAttrs(hero, lineup, lineupHero), this.calcHeroTreasuresAttrs(hero, lineup, lineupHero), this.calcHeroMountsAttrs(hero, lineup, lineupHero), this.calcHeroArtifactAttrs(hero, lineup, lineupHero), ) } func (this *Player) UpdateHeroAttrs(hero *PlayerHero) bool { if hero == nil { return false } for _, lineup := range this.Lineup { if lineup.Active { for _, lineupHero := range lineup.Heroes { if lineupHero != nil && lineupHero.HeroUid == hero.Uid { return this.updateHeroAttrs(hero, lineup, lineupHero) } } } } return this.updateHeroAttrs(hero, nil, nil) } func (this *Player) reduceHero(hero *PlayerHero, logType LogType) *pb.HeroChange { delete(this.Hero, hero.Uid) this.WipeModel(hero) //if logType > LogTypeNone { // this.manager.eventManager.PlayerHeroConsume(this, logType, hero.Id, itemNum) //} return &pb.HeroChange{ChangeType: pb.ChangeType_Delete, Hero: hero.BuildMsgHero()} } func (this *Player) ReduceHeroes(heroes map[uint64]*PlayerHero, logType LogType) { var changeList = make([]*pb.HeroChange, 0, len(heroes)) for _, hero := range heroes { changeList = append(changeList, this.reduceHero(hero, logType)) } _ = this.Send(uint16(pb.ModId_ModuleHero), uint16(pb.MsgId_ModHeroChange), &pb.HeroChangeListAck{ChangeList: changeList}) } func (this *Player) BuildMsgHeroListAck() *pb.HeroListAck { var list = []*pb.Hero{this.RoleHero.BuildMsgHero()} for _, hero := range this.Hero { list = append(list, hero.BuildMsgHero()) } return &pb.HeroListAck{HeroList: list} }