副本,关卡,战斗,奖励

This commit is contained in:
sk 2025-06-20 15:34:32 +08:00
parent f4db5a7d3b
commit 2ce71b7a2c
19 changed files with 1052 additions and 177 deletions

View File

@ -21,5 +21,5 @@ func CheckChannel(channel uint32) bool {
}
func CheckAttrType(attrType int) bool {
return pb.AttrType(attrType) > pb.AttrType_AttrTypeNone && pb.AttrType(attrType) < pb.AttrType_Nums
return pb.AttrType(attrType) > pb.AttrType_AttrTypeNone && pb.AttrType(attrType) < pb.AttrType_AttrNums
}

View File

@ -8,15 +8,33 @@ import "mod_item.proto";
//
// ,
//
// MsgId.ModBattleEnter = 4001;
//
message BattleEnterReq {
uint32 SceneId = 1; //ID
}
//Buff
message BattleBuff {
uint32 Skill = 1; //Buff技能
uint32 Layers = 2; //Buff层数
}
//
message BattleValue {
int64 Value = 1; //
uint64 Hp = 2; //
uint32 Status = 3; //0., 1., 2.3.4.5., 6., 7.
}
//
message BattleTarget {
uint32 Type = 1; //, 1.2.()
uint64 Id = 2; //ID
uint32 Position = 2; //1-6
uint64 HpMax = 3; //
uint32 Rage = 4; //
repeated uint32 Status = 5; //
repeated uint64 Value = 6; //
repeated uint64 Hp = 7; //
repeated BattleBuff BuffList = 5; //DeBuff状态ID
repeated BattleValue ValueList = 6; //
}
//
@ -33,10 +51,10 @@ message BattleRound {
repeated BattleAction ActionList = 2; //
}
//
message BattleUnit {
uint64 UnitId = 1;
uint64 UnitId = 1; //IDIDID
uint32 SuitId = 2; //ID
//
}
// MsgId.ModBattleEnter = 4001;

View File

@ -12,13 +12,6 @@ message SceneEnterAck {
uint32 SceneId = 1;//ID
}
// MsgId.ModLevelEnter: 3001
//
message LevelEnterAck {
uint32 CopyType = 1; //
uint32 LevelId = 2; //ID
}
// CopyStatus
message CopyStatus {
uint32 CopyType = 1; //
@ -46,6 +39,14 @@ message LevelEnterReq {
uint32 LevelId = 2; //ID
}
// MsgId.ModLevelEnter = 3004;
//
//message LevelEnterAck {
// uint32 CopyType = 1; //
// uint32 LevelId = 2; //ID
// uint32 SceneId = 3; //ID
//}
// MsgId.ModLevelSweep = 3005;
//
message LevelSweepReq {

View File

@ -120,6 +120,13 @@ message LineupHeroPositionReq {
repeated uint32 PositionList = 3; // 6
}
// MsgId.ModRoleLineupHeroPosition = 2008;
//
message LineupHeroPositionAck {
uint64 LineupUid = 1;
repeated uint32 PositionList = 3; // 6
}
// MsgId.ModRoleLineupHeroEquip = 2009;
//
message LineupHeroEquipReq {

141
servers/game/data/drop.go Normal file
View File

@ -0,0 +1,141 @@
package data
import (
json "github.com/json-iterator/go"
"github.com/oylshe1314/framework/util"
"sort"
)
type Drop struct {
Id int `json:"id"`
DropId int `json:"drop_id"`
BoxId int `json:"box_id"`
BoxRate int `json:"box_rate"`
MinNum int `json:"min_num"`
MaxNum int `json:"max_num"`
ItemId int `json:"item_id"`
ItemNum int `json:"item_num"`
ItemRate int `json:"item_rate"`
}
type dropItem struct {
drop *Drop
}
type dropBox struct {
boxId int
rate int
min int
max int
rates int
items []*dropItem
}
type dropStore struct {
dropId int
boxes map[int]*dropBox
}
type DropTable struct {
l []*Drop
m map[int]*dropStore
}
func (this *DropTable) load(buf []byte) error {
var err = json.Unmarshal(buf, &this.l)
if err != nil {
return err
}
this.m = make(map[int]*dropStore)
for _, drop := range this.l {
var item = &dropItem{drop}
var store = this.m[item.drop.DropId]
if store == nil {
store = &dropStore{
dropId: drop.DropId,
boxes: map[int]*dropBox{
item.drop.BoxId: {
boxId: item.drop.BoxId,
rate: item.drop.BoxRate,
min: item.drop.MinNum,
max: item.drop.MaxNum,
rates: item.drop.ItemRate,
items: []*dropItem{item},
},
},
}
this.m[drop.DropId] = store
} else {
var box = store.boxes[item.drop.BoxId]
if box == nil {
box = &dropBox{
boxId: item.drop.BoxId,
rate: item.drop.BoxRate,
min: item.drop.MinNum,
max: item.drop.MaxNum,
rates: item.drop.ItemRate,
items: []*dropItem{item},
}
store.boxes[item.drop.BoxId] = box
} else {
box.rates += item.drop.ItemRate
box.items = append(box.items, item)
}
}
}
for _, store := range this.m {
for _, box := range store.boxes {
sort.Slice(box.items, func(i, j int) bool {
return box.items[i].drop.Id < box.items[j].drop.Id
})
}
}
return nil
}
// Drop 掉落算法
func (this *DropTable) Drop(dropId int, times int) [][2]int {
if dropId <= 0 {
return nil
}
if times <= 0 {
return nil
}
var store = this.m[dropId]
if store == nil {
return nil
}
var rd = util.NewRand()
var result [][2]int
for range times {
for _, box := range store.boxes {
if len(box.items) == 0 {
continue
}
if rd.Float64()*10000.0 > float64(box.rate) {
continue
}
var dropNum = box.min
if box.max > dropNum {
dropNum += rd.IntN(box.max - box.min)
}
var rates = float64(box.rates)
var factor = rd.Float64() * rates
for _, item := range box.items {
rates -= float64(item.drop.ItemRate)
if factor >= rates {
result = append(result, [2]int{item.drop.ItemId, item.drop.ItemNum * dropNum})
break
}
}
}
}
return result
}

View File

@ -4,7 +4,10 @@ import json "github.com/json-iterator/go"
type Monster struct {
Id int `json:"id"`
Gender int `json:"gender"`
Country int `json:"country"`
Level int `json:"level"`
Speed int `json:"speed"`
AttackSkills []int `json:"attack_skills"`
PassiveSkills []int `json:"passive_skills"`
AttrValue1 int `json:"attr_value1"`

View File

@ -21,8 +21,8 @@ type Scene struct {
Monster6 int `json:"monster6"`
EnterTimes int `json:"enter_times"`
RestTimes int `json:"rest_times"`
PassExpRate int `json:"pass_exp_rate"`
PassCoinRate int `json:"pass_coin_rate"`
ExpMultiple int `json:"exp_multiple"`
CoinMultiple int `json:"coin_multiple"`
FirstDrop int `json:"first_drop"`
PassDrop int `json:"pass_drop"`
Star1Type int `json:"star1_type"`

View File

@ -5,6 +5,7 @@ import json "github.com/json-iterator/go"
type Skill struct {
Id int `json:"id"`
SkillType int `json:"skill_type"`
RageConsume int `json:"rage_consume"`
SkillBuff []int `json:"skill_buff"`
}

View File

@ -4,8 +4,21 @@ import json "github.com/json-iterator/go"
type SkillBuff struct {
Id int `json:"id"`
SkillBuffType int `json:"SkillBuff_type"`
SkillBuffBuff []int `json:"SkillBuff_buff"`
TargetType int `json:"target_type"`
TargetArgs []int `json:"target_args"`
RangeType int `json:"range_type"`
RangeNum int `json:"range_num"`
PriorityType []int `json:"priority_type"`
PriorityArgs []int `json:"priority_args"`
BuffType int `json:"buff_type"`
BuffArgs []int `json:"buff_args"`
DurationType int `json:"durationType"`
Duration int `json:"duration"`
EffectId string `json:"effectId"`
CanMerge bool `json:"can_merge"`
CanCover bool `json:"can_cover"`
CanStack bool `json:"can_stack"`
CanClean bool `json:"can_clean"`
}
type SkillBuffTable struct {

View File

@ -19,6 +19,7 @@ type Tables struct {
Copy CopyTable
CopyMain CopyMainTable
Drop DropTable
Equip EquipTable
EquipLevel EquipLevelTable
EquipRefine EquipRefineTable

View File

@ -9,14 +9,14 @@ import (
)
func (this *PlayerHandler) checkLevelConsume(sceneTable *data.Scene, player *logic.Player, times uint32) proto.TipError {
var consume = map[uint32]uint32{}
var consumeItems = map[uint32]uint32{}
for i := range sceneTable.ConsumeItems {
consume[uint32(sceneTable.ConsumeItems[i])] += uint32(sceneTable.ConsumeNums[i]) * times
consumeItems[uint32(sceneTable.ConsumeItems[i])] += uint32(sceneTable.ConsumeNums[i]) * times
}
for i := range sceneTable.SuConsumeItems {
consume[uint32(sceneTable.SuConsumeItems[i])] += uint32(sceneTable.SuConsumeNums[i]) * times
consumeItems[uint32(sceneTable.SuConsumeItems[i])] += uint32(sceneTable.SuConsumeNums[i]) * times
}
for itemId, itemNum := range consume {
for itemId, itemNum := range consumeItems {
if ok, tip := player.CheckItem(itemId, itemNum); !ok {
return tip
}

View File

@ -5,6 +5,7 @@ import (
"ecs/proto/pb"
"ecs/servers/game/data"
"github.com/oylshe1314/framework/util"
"sort"
)
func (this *Player) EnterBattle(sceneTable *data.Scene) {
@ -32,25 +33,66 @@ func (this *Player) copyBattle(sceneTable *data.Scene) {
this.PassedCopy(sceneTable, ack.Score)
}
_ = this.Send(uint16(pb.ModId_ModuleBattle), uint16(pb.MsgId_ModBattleEnter), ack)
_ = this.Send(pb.ModId_ModuleBattle, pb.MsgId_ModBattleEnter, ack)
}
type _BattleBuff struct {
id uint32
targetType uint32
targetArgs []uint32
rangeType uint32
rangeNum uint32
priorityType []uint32
priorityArgs []uint32
buffType uint32
buffArgs []int64
durationType uint32
duration uint32
canMerge bool
canCover bool
canStack bool
canClean bool
}
type _BattleSkill struct {
id uint32
tipe uint32
rage uint32
buffs []*_BattleBuff
}
type _BattleUnit struct {
id uint64
position uint32
gender uint32
country uint32
hp uint64
rage uint32
speed uint32
baseSpeed uint32
posSpeed uint32
amuletSpeed uint32
harnessSpeed uint32
attrs Attrs
role *_BattleRole
buffs []*_BattleBuff
deBuffs []*_BattleBuff
attackSkills []*_BattleSkill
passiveSkills []*_BattleSkill
}
type _BattleRole struct {
attacker bool
addSpeed uint32
capacity uint64
unitList []*_BattleUnit
//sellList []*_BattleUnit
}
func (this *Player) virtualBattle(sceneTable *data.Scene) (ack *pb.BattleEnterAck, tip proto.TipError) {
var lineup = util.MapFindValue(this.Lineup, func(lineup *PlayerLineup) bool {
return lineup.Active
@ -59,110 +101,177 @@ func (this *Player) virtualBattle(sceneTable *data.Scene) (ack *pb.BattleEnterAc
return nil, proto.TipLineupNotFound
}
var heroes = make([]*_BattleUnit, 6)
for i := range 6 {
if lineup.Heroes[i] != nil {
if hero := this.Hero[lineup.Heroes[i].HeroUid]; hero != nil {
heroes[lineup.Heroes[i].Position-1] = &_BattleUnit{
id: lineup.Heroes[i].HeroUid,
attrs: hero.Attrs(),
}
}
}
var me = &_BattleRole{attacker: true}
me.capacity, me.unitList, tip = this.loadHeroes(me, lineup)
if tip != nil {
_ = this.TipNotice(tip)
return
}
var enemies []*_BattleUnit
//sort.Slice(me.unitList, func(i, j int) bool {
// return me.unitList[i].pos < me.unitList[j].pos
//})
var he = &_BattleRole{attacker: false}
if pb.CopyType(sceneTable.CopyType) == pb.CopyType_CopyArena {
} else {
enemies, tip = this.loadMonsters([]int{sceneTable.Monster1, sceneTable.Monster2, sceneTable.Monster3, sceneTable.Monster4, sceneTable.Monster5, sceneTable.Monster6})
he.capacity, he.unitList, tip = this.loadMonsters(he, []int{sceneTable.Monster1, sceneTable.Monster2, sceneTable.Monster3, sceneTable.Monster4, sceneTable.Monster5, sceneTable.Monster6})
if tip != nil {
_ = this.TipNotice(tip)
return
}
}
//sort.Slice(he.unitList, func(i, j int) bool {
// return he.unitList[i].pos < he.unitList[j].pos
//})
ack = &pb.BattleEnterAck{
SceneId: uint32(sceneTable.Id),
RewardList: nil,
}
ack.Heroes = make([]*pb.BattleUnit, 6)
ack.Enemies = make([]*pb.BattleUnit, 6)
for i := range 6 {
if heroes[i] != nil {
ack.Heroes[i] = &pb.BattleUnit{UnitId: heroes[i].id}
for i := range me.unitList {
if me.unitList[i] != nil {
ack.Heroes[i] = &pb.BattleUnit{
UnitId: me.unitList[i].id,
}
if enemies[i] != nil {
ack.Enemies[i] = &pb.BattleUnit{UnitId: enemies[i].id}
}
}
ack.Succeed, ack.Score, ack.RoundList = this.calcBattle(heroes, enemies)
ack.Enemies = make([]*pb.BattleUnit, 6)
for i := range he.unitList {
if he.unitList[i] != nil {
ack.Enemies[i] = &pb.BattleUnit{
UnitId: he.unitList[i].id,
}
}
}
if len(me.unitList) == 0 {
ack.Succeed = false
ack.Score = 0
} else if len(he.unitList) == 0 {
ack.Succeed = true
ack.Score = 3
} else {
var calculator = &_BattleCalculator{
rd: util.NewRand(),
me: me,
he: he,
}
ack.Succeed, ack.RoundList = calculator.calcBattle(sceneTable.BattleRound, me, he)
ack.BattleRounds = uint32(len(ack.RoundList))
if ack.Succeed {
//TODO calc stars
ack.Score = 2
if me.unitList[0].hp > 0 {
ack.Score = 3
}
this.addExp(this.RoleLevel*uint32(sceneTable.ExpMultiple), LogTypeItemObtainByCopy)
this.addMoney(pb.MoneyType_Coin, this.RoleLevel*uint32(sceneTable.CoinMultiple), LogTypeItemObtainByCopy)
//TODO calc reward
var rewardItems = map[uint32]uint32{}
if this.GetCopyPassed(pb.CopyType(sceneTable.CopyType), uint32(sceneTable.CopyId)) == 0 {
var dropResult = this.manager.tables.Drop.Drop(sceneTable.FirstDrop, 1)
for _, items := range dropResult {
rewardItems[uint32(items[0])] += uint32(items[1])
ack.RewardList = append(ack.RewardList, &pb.Item{
ItemId: uint32(items[0]),
ItemNum: uint32(items[1]),
})
}
}
var dropResult = this.manager.tables.Drop.Drop(sceneTable.PassDrop, 1)
for _, items := range dropResult {
rewardItems[uint32(items[0])] += uint32(items[1])
ack.RewardList = append(ack.RewardList, &pb.Item{
ItemId: uint32(items[0]),
ItemNum: uint32(items[1]),
})
}
this.AddItems(rewardItems, LogTypeItemObtainByCopy)
}
}
return ack, nil
}
func (this *Player) calcBattle(heroes, enemies []*_BattleUnit) (bool, int32, []*pb.BattleRound) {
return true, 3, []*pb.BattleRound{
{
BattleRound: 1,
ActionList: []*pb.BattleAction{
{
Caster: &pb.BattleTarget{
Type: 1,
Id: heroes[0].id,
HpMax: heroes[0].attrs[pb.AttrType_Hp],
Rage: 0,
Status: nil,
Value: nil,
Hp: nil,
},
Type: 0,
SkillId: 100021,
TargetList: []*pb.BattleTarget{
{
Type: 2,
Id: enemies[0].id,
HpMax: enemies[0].attrs[pb.AttrType_Hp],
Rage: 0,
Status: nil,
Value: []uint64{heroes[0].attrs[pb.AttrType_Attack]},
Hp: []uint64{enemies[0].attrs[pb.AttrType_Hp] - heroes[0].attrs[pb.AttrType_Attack]},
},
},
},
{
Caster: &pb.BattleTarget{
Type: 2,
Id: enemies[1].id,
HpMax: enemies[1].attrs[pb.AttrType_Hp],
Rage: 0,
Status: nil,
Value: nil,
Hp: nil,
},
Type: 0,
SkillId: 100191,
TargetList: []*pb.BattleTarget{
{
Type: 1,
Id: heroes[0].id,
HpMax: heroes[0].attrs[pb.AttrType_Hp],
Rage: 0,
Status: nil,
Value: []uint64{enemies[1].attrs[pb.AttrType_Attack]},
Hp: []uint64{heroes[0].attrs[pb.AttrType_Hp] - enemies[1].attrs[pb.AttrType_Attack]},
},
},
},
},
},
}
func (this *Player) calcAttrsCapacity(attrs Attrs) uint64 {
return uint64((float64(attrs[pb.AttrType_Attack]) * 2) +
(float64(attrs[pb.AttrType_Hp]) * 0.2) +
(float64(attrs[pb.AttrType_PhysicalDefense]) * 6) +
(float64(attrs[pb.AttrType_MagicDefense]) * 6) +
(float64(attrs[pb.AttrType_DamageRatio]) * 12) +
(float64(attrs[pb.AttrType_DamageRelief]) * 12) +
(float64(attrs[pb.AttrType_CriticalRate]) * 12) +
(float64(attrs[pb.AttrType_CriticalResistance]) * 12) +
(float64(attrs[pb.AttrType_CriticalDamage]) * 12) +
(float64(attrs[pb.AttrType_CriticalDamageRelief]) * 12) +
(float64(attrs[pb.AttrType_HitRate]) * 12) +
(float64(attrs[pb.AttrType_DodgeRate]) * 12) +
(float64(attrs[pb.AttrType_TreatRatio]) * 12) +
(float64(attrs[pb.AttrType_ByTreatedRate]) * 12) +
(float64(attrs[pb.AttrType_FinalDamageRatio]) * 12))
}
func (this *Player) loadMonsters(monsterIds []int) (unitList []*_BattleUnit, tip proto.TipError) {
unitList = make([]*_BattleUnit, len(monsterIds))
func (this *Player) loadHeroes(role *_BattleRole, lineup *PlayerLineup) (capacity uint64, unitList []*_BattleUnit, tip proto.TipError) {
unitList = make([]*_BattleUnit, 6)
var heroIndex = 0
for i := range 6 {
if lineup.Heroes[i] != nil {
if hero := this.Hero[lineup.Heroes[i].HeroUid]; hero != nil {
capacity += lineup.Heroes[i].Capacity
var unit = &_BattleUnit{
id: lineup.Heroes[i].HeroUid,
position: lineup.Heroes[i].Position,
attrs: hero.Attrs(),
role: role,
}
var heroTable = this.manager.tables.Hero.Find1(int(hero.Id))
if heroTable == nil {
return 0, nil, proto.TipDataTablesError
}
unit.gender = uint32(heroTable.Sex)
unit.country = uint32(heroTable.Country)
unit.attackSkills, tip = this.loadSkills(heroTable.Skill)
if tip != nil {
return
}
sort.Slice(unit.attackSkills, func(i, j int) bool {
return unit.attackSkills[i].tipe > unit.attackSkills[j].tipe
})
unit.hp = unit.attrs[pb.AttrType_Hp]
unit.rage = 4
unit.baseSpeed = 100
unit.posSpeed = uint32(20 - 4*heroIndex)
unit.amuletSpeed = 0 //TODO calc speed
unit.harnessSpeed = 0 //TODO calc speed
//TODO load hero passive skills, from equip, break, soul
unitList[lineup.Heroes[i].Position-1] = unit
}
}
}
return
}
func (this *Player) loadMonsters(role *_BattleRole, monsterIds []int) (capacity uint64, unitList []*_BattleUnit, tip proto.TipError) {
unitList = make([]*_BattleUnit, 6)
var monsterIndex uint64 = 0
for i, monsterId := range monsterIds {
if monsterId == 0 {
continue
@ -170,16 +279,26 @@ func (this *Player) loadMonsters(monsterIds []int) (unitList []*_BattleUnit, tip
var monsterTable = this.manager.tables.Monster.Find(int(monsterId))
if monsterTable == nil {
return nil, proto.TipDataTablesError
return 0, nil, proto.TipDataTablesError
}
var unit = &_BattleUnit{id: uint64(monsterTable.Id)}
var unit = &_BattleUnit{
id: uint64(monsterTable.Id),
position: uint32(i + 1),
gender: uint32(monsterTable.Gender),
country: uint32(monsterTable.Country),
role: role,
}
unit.attackSkills, tip = this.loadSkills(monsterTable.AttackSkills)
if tip != nil {
return
}
sort.Slice(unit.attackSkills, func(i, j int) bool {
return unit.attackSkills[i].tipe > unit.attackSkills[j].tipe
})
unit.passiveSkills, tip = this.loadSkills(monsterTable.PassiveSkills)
if tip != nil {
return
@ -187,24 +306,34 @@ func (this *Player) loadMonsters(monsterIds []int) (unitList []*_BattleUnit, tip
unit.attrs[pb.AttrType_Attack] = uint64(monsterTable.AttrValue1)
unit.attrs[pb.AttrType_Hp] = uint64(monsterTable.AttrValue2)
unit.attrs[pb.AttrType_AttrPhysicalDefense] = uint64(monsterTable.AttrValue3)
unit.attrs[pb.AttrType_AttrMagicDefense] = uint64(monsterTable.AttrValue4)
unit.attrs[pb.AttrType_AttrAttackRatio] = uint64(monsterTable.AttrValue5)
unit.attrs[pb.AttrType_AttrHpRatio] = uint64(monsterTable.AttrValue6)
unit.attrs[pb.AttrType_AttrPhysicalDefenseRatio] = uint64(monsterTable.AttrValue7)
unit.attrs[pb.AttrType_AttrMagicDefenseRatio] = uint64(monsterTable.AttrValue8)
unit.attrs[pb.AttrType_AttrDamageRatio] = uint64(monsterTable.AttrValue9)
unit.attrs[pb.AttrType_AttrDamageRelief] = uint64(monsterTable.AttrValue10)
unit.attrs[pb.AttrType_AttrCriticalRatio] = uint64(monsterTable.AttrValue11)
unit.attrs[pb.AttrType_AttrCriticalResistance] = uint64(monsterTable.AttrValue12)
unit.attrs[pb.AttrType_AttrCriticalDamage] = uint64(monsterTable.AttrValue13)
unit.attrs[pb.AttrType_AttrCriticalDamageRelief] = uint64(monsterTable.AttrValue14)
unit.attrs[pb.AttrType_AttrHitRate] = uint64(monsterTable.AttrValue15)
unit.attrs[pb.AttrType_AttrDodgeRate] = uint64(monsterTable.AttrValue16)
unit.attrs[pb.AttrType_AttrTreatRatio] = uint64(monsterTable.AttrValue17)
unit.attrs[pb.AttrType_AttrByTreatedRatio] = uint64(monsterTable.AttrValue18)
unit.attrs[pb.AttrType_AttrFinalDamageRatio] = uint64(monsterTable.AttrValue19)
unit.attrs[pb.AttrType_AttrFinalDamageRelief] = uint64(monsterTable.AttrValue20)
unit.attrs[pb.AttrType_PhysicalDefense] = uint64(monsterTable.AttrValue3)
unit.attrs[pb.AttrType_MagicDefense] = uint64(monsterTable.AttrValue4)
unit.attrs[pb.AttrType_AttackRatio] = uint64(monsterTable.AttrValue5)
unit.attrs[pb.AttrType_HpRatio] = uint64(monsterTable.AttrValue6)
unit.attrs[pb.AttrType_PhysicalDefenseRatio] = uint64(monsterTable.AttrValue7)
unit.attrs[pb.AttrType_MagicDefenseRatio] = uint64(monsterTable.AttrValue8)
unit.attrs[pb.AttrType_DamageRatio] = uint64(monsterTable.AttrValue9)
unit.attrs[pb.AttrType_DamageRelief] = uint64(monsterTable.AttrValue10)
unit.attrs[pb.AttrType_CriticalRate] = uint64(monsterTable.AttrValue11)
unit.attrs[pb.AttrType_CriticalResistance] = uint64(monsterTable.AttrValue12)
unit.attrs[pb.AttrType_CriticalDamage] = uint64(monsterTable.AttrValue13)
unit.attrs[pb.AttrType_CriticalDamageRelief] = uint64(monsterTable.AttrValue14)
unit.attrs[pb.AttrType_HitRate] = uint64(monsterTable.AttrValue15)
unit.attrs[pb.AttrType_DodgeRate] = uint64(monsterTable.AttrValue16)
unit.attrs[pb.AttrType_TreatRatio] = uint64(monsterTable.AttrValue17)
unit.attrs[pb.AttrType_ByTreatedRate] = uint64(monsterTable.AttrValue18)
unit.attrs[pb.AttrType_FinalDamageRatio] = uint64(monsterTable.AttrValue19)
unit.attrs[pb.AttrType_FinalDamageRelief] = uint64(monsterTable.AttrValue20)
monsterIndex += 1
unit.hp = unit.attrs[pb.AttrType_Hp]
unit.rage = 4
unit.baseSpeed = 0
unit.posSpeed = uint32(20 - 4*monsterIndex)
unit.amuletSpeed = 0 //TODO calc speed
unit.harnessSpeed = 0 //TODO calc speed
capacity += this.calcAttrsCapacity(unit.attrs)
unitList[i] = unit
}
@ -212,7 +341,7 @@ func (this *Player) loadMonsters(monsterIds []int) (unitList []*_BattleUnit, tip
}
func (this *Player) loadSkills(skillIds []int) (skillList []*_BattleSkill, tip proto.TipError) {
skillList = make([]*_BattleSkill, len(skillIds))
skillList = make([]*_BattleSkill, 0, len(skillIds))
for _, skillId := range skillIds {
var skillTable = this.manager.tables.Skill.Find(skillId)
if skillTable == nil {
@ -221,29 +350,47 @@ func (this *Player) loadSkills(skillIds []int) (skillList []*_BattleSkill, tip p
var skill = &_BattleSkill{
id: uint32(skillId),
tipe: uint32(skillTable.SkillType),
rage: uint32(skillTable.RageConsume),
}
skill.buffs, tip = this.loadSkillsBuff(skillTable.SkillBuff)
if tip != nil {
return
}
skillList = append(skillList, skill)
}
return
}
func (this *Player) loadSkillsBuff(buffIds []int) (buffList []*_BattleBuff, tip proto.TipError) {
buffList = make([]*_BattleBuff, len(buffIds))
for i, skillId := range buffIds {
var buff = this.manager.tables.SkillBuff.Find(skillId)
if buff == nil {
buffList = make([]*_BattleBuff, 0, len(buffIds))
for _, buffId := range buffIds {
var buffTable = this.manager.tables.SkillBuff.Find(buffId)
if buffTable == nil {
return nil, proto.TipDataTablesError
}
var battleBuff = &_BattleBuff{
id: uint32(skillId),
var buff = &_BattleBuff{
id: uint32(buffId),
targetType: uint32(buffTable.TargetType),
targetArgs: util.NumbersConvert2(buffTable.TargetArgs, uint32(0)),
rangeType: uint32(buffTable.RangeType),
rangeNum: uint32(buffTable.RangeNum),
priorityType: util.NumbersConvert2(buffTable.PriorityType, uint32(0)),
priorityArgs: util.NumbersConvert2(buffTable.PriorityArgs, uint32(0)),
buffType: uint32(buffTable.BuffType),
buffArgs: util.NumbersConvert2(buffTable.BuffArgs, int64(0)),
durationType: uint32(buffTable.DurationType),
duration: uint32(buffTable.Duration),
canMerge: buffTable.CanMerge,
canCover: buffTable.CanCover,
canStack: buffTable.CanStack,
canClean: buffTable.CanClean,
}
buffList[i] = battleBuff
buffList = append(buffList, buff)
}
return buffList, nil
}

View File

@ -0,0 +1,490 @@
package logic
import (
"ecs/proto/pb"
"github.com/oylshe1314/framework/util"
"math/rand/v2"
"sort"
)
type _BattleCalculator struct {
rd *rand.Rand
me *_BattleRole
he *_BattleRole
}
func (tnis *_BattleCalculator) calcNextCaster(lastIndex int, unitList []*_BattleUnit) (dead bool, newIndex int, caster *_BattleUnit) {
dead = true
var posIndex = 0
for i, unit := range unitList {
if i == lastIndex || unit == nil {
continue
}
if unit.hp > 0 {
dead = false
posIndex += 1
unit.posSpeed = uint32(20 - (4 * posIndex))
unit.speed = unit.baseSpeed + unit.posSpeed + unit.amuletSpeed + unit.harnessSpeed
if lastIndex < 0 || unit.speed <= unitList[lastIndex].speed {
if caster == nil || unit.speed > caster.speed {
caster = unit
newIndex = i
}
}
}
}
return
}
func (this *_BattleCalculator) calcBattle(rounds int, me, he *_BattleRole) (succeed bool, roundList []*pb.BattleRound) {
var roles = [2]*_BattleRole{me, he}
var ri = 0
if he.capacity > me.capacity {
ri = 1
}
var dead bool
var index = [2]int{-1, -1}
var caster, aCaster, bCaster *_BattleUnit
for i, unit := range roles[ri].unitList {
if unit != nil {
unit.speed = unit.baseSpeed + unit.posSpeed + unit.amuletSpeed + unit.harnessSpeed
if aCaster == nil || unit.speed > aCaster.speed {
aCaster = unit
index[ri] = i
}
}
}
caster = aCaster
for round := range rounds {
var battleRound = &pb.BattleRound{BattleRound: uint32(round) + 1}
dead = false
for {
var ai, bi = ri, (ri + 1) % 2
var battleAction = &pb.BattleAction{}
battleRound.ActionList = append(battleRound.ActionList, battleAction)
battleAction.Caster, battleAction.SkillId, battleAction.TargetList = this.calcSkill(caster, roles[ai], roles[bi])
dead, index[bi], bCaster = this.calcNextCaster(index[bi], roles[bi].unitList)
if dead {
succeed = bi != 0
break
}
dead, index[ai], aCaster = this.calcNextCaster(index[ai], roles[ai].unitList)
if dead {
succeed = ai != 0
break
}
if bCaster == nil {
if aCaster == nil {
index[ai] = -1
index[bi] = -1
break
} else {
caster = aCaster
}
} else {
if aCaster == nil {
caster = bCaster
ri = bi
} else {
if aCaster.speed > bCaster.speed {
caster = aCaster
} else {
caster = bCaster
ri = bi
}
}
}
}
roundList = append(roundList, battleRound)
if dead {
break
}
}
return succeed, roundList
}
func (this *_BattleCalculator) calcSkill(unit *_BattleUnit, a, b *_BattleRole) (caster *pb.BattleTarget, skillId uint32, targetList []*pb.BattleTarget) {
for _, skill := range unit.attackSkills {
if unit.rage < skill.rage {
continue
}
switch skill.tipe {
case skillTypeAttack:
skillId = skill.id
caster, targetList = this.calcBuff(unit, skill, a, b)
unit.rage += 2
case skillTypeActive:
skillId = skill.id
unit.rage -= skill.rage
caster, targetList = this.calcBuff(unit, skill, a, b)
default:
continue
}
break
}
return
}
func (this *_BattleCalculator) calcBuff(unit *_BattleUnit, skill *_BattleSkill, a, b *_BattleRole) (caster *pb.BattleTarget, targetList []*pb.BattleTarget) {
caster = &pb.BattleTarget{Type: uint32(util.If(unit.role.attacker, 1, 2)), Position: unit.position}
caster.HpMax = unit.attrs[pb.AttrType_Hp]
caster.Rage = unit.rage
var targetMap = map[uint32]*pb.BattleTarget{}
for _, buff := range skill.buffs {
if buff.buffType == buffTypeNone || len(buff.buffArgs) == 0 {
continue
}
//switch buff.targetType {
//case targetTypeSelf:
// targets = []*_BattleUnit{unit}
//case targetTypeTeammate:
//case targetTypeEnemy:
//case targetTypeTeammateGender:
// if len(buff.targetArgs) == 0 {
// continue
// }
// for _, teammate := range a.unitList {
// if teammate != nil {
// if slices.Contains(buff.targetArgs, teammate.gender) {
// targets = append(targets, teammate)
// }
// }
// }
//case targetTypeEnemyGender:
// if len(buff.targetArgs) == 0 {
// continue
// }
// for _, enemy := range b.unitList {
// if enemy != nil {
// if slices.Contains(buff.targetArgs, enemy.gender) {
// targets = append(targets, enemy)
// }
// }
// }
//case targetTypeTeammateCountry:
// if len(buff.targetArgs) == 0 {
// continue
// }
// for _, teammate := range a.unitList {
// if teammate != nil {
// if slices.Contains(buff.targetArgs, teammate.country) {
// targets = append(targets, teammate)
// }
// }
// }
//case targetTypeEnemyCountry:
// if len(buff.targetArgs) == 0 {
// continue
// }
// for _, enemy := range b.unitList {
// if enemy != nil {
// if slices.Contains(buff.targetArgs, enemy.country) {
// targets = append(targets, enemy)
// }
// }
// }
//case targetTypeTeammateStatus:
// if len(buff.targetArgs) == 0 {
// continue
// }
// for _, teammate := range a.unitList {
// if teammate != nil {
// if slices.ContainsFunc(buff.targetArgs, func(targetArg uint32) bool {
// return slices.ContainsFunc(teammate.deBuffs, func(buff *_BattleBuff) bool {
// return buff.id == targetArg
// })
// }) {
// targets = append(targets, teammate)
// }
// }
// }
//case targetTypeEnemyStatus:
// if len(buff.targetArgs) == 0 {
// continue
// }
// for _, enemy := range b.unitList {
// if enemy != nil {
// if slices.ContainsFunc(buff.targetArgs, func(targetArg uint32) bool {
// return slices.ContainsFunc(enemy.deBuffs, func(buff *_BattleBuff) bool {
// return buff.id == targetArg
// })
// }) {
// targets = append(targets, enemy)
// }
// }
// }
//case targetTypeAttackRate:
//}
var targets []*_BattleUnit
switch buff.buffType {
case buffTypePhysicalDamage:
if buff.targetType != targetTypeEnemy {
continue
}
targets = this.calcAttackTarget(b.unitList, buff.priorityType, buff.priorityArgs, buff.rangeType, buff.rangeNum)
for _, target := range targets {
var damage = this.calcDamage(buff, unit, target)
this.calcHp(target, damage, targetMap)
}
case buffTypeMagicDamage:
if buff.targetType != targetTypeEnemy {
continue
}
targets = this.calcAttackTarget(b.unitList, buff.priorityType, buff.priorityArgs, buff.rangeType, buff.rangeNum)
for _, target := range targets {
var damage = this.calcDamage(buff, unit, target)
this.calcHp(target, damage, targetMap)
}
case buffTypeStatusAbnormal:
case buffTypeChangeAttr:
case buffTypeRevive:
case buffTypeDamageReturn:
case buffTypeBisect:
case buffTypeShield:
case buffTypeChangeHp:
case buffTypeSteal:
case buffTypeAddRage:
case buffTypeImmune:
case buffTypeUndead:
case buffTypeDamageShare:
case buffTypeEffectAbnormal:
}
}
for _, target := range targetMap {
targetList = append(targetList, target)
}
return
}
func (this *_BattleCalculator) calcHp(unit *_BattleUnit, damage int64, targetMap map[uint32]*pb.BattleTarget) {
var newHp = int64(unit.hp) + damage
if newHp < 0 {
newHp = 0
}
unit.hp = uint64(newHp)
var target = targetMap[unit.position]
if target == nil {
target = &pb.BattleTarget{
Type: uint32(util.If(unit.role.attacker, 1, 2)),
Position: unit.position,
HpMax: unit.attrs[pb.AttrType_Hp],
Rage: unit.rage,
BuffList: nil,
ValueList: nil,
}
targetMap[target.Position] = target
}
target.ValueList = append(target.ValueList, &pb.BattleValue{
Value: damage,
Hp: unit.hp,
})
}
func (this *_BattleCalculator) calcAttackTarget(unitList []*_BattleUnit, priorityType, priorityArgs []uint32, rangeType, rangeNum uint32) []*_BattleUnit {
var targets []*_BattleUnit
if len(priorityType) == 0 {
for ui := range unitList {
if unitList[ui] != nil && unitList[ui].hp > 0 {
targets = append(targets, unitList[ui])
}
}
return util.RandomSelect(this.rd, targets, util.If(rangeType == rangeTypeSingle, 1, util.If(rangeNum > 0, int(rangeNum), len(targets))))
}
for i := range priorityType {
if len(priorityArgs) <= i {
continue
}
switch priorityType[i] {
case priorityTypeNone:
if len(priorityType) == 0 {
for ui := range unitList {
if unitList[ui] != nil && unitList[ui].hp > 0 {
targets = append(targets, unitList[ui])
}
}
return util.RandomSelect(this.rd, targets, util.If(rangeType == rangeTypeSingle, 1, util.If(rangeNum > 0, int(rangeNum), len(targets))))
}
case priorityTypePosition:
switch priorityArgs[i] {
case priorityArgFront:
for ui := range []int{0, 1, 2} {
if unitList[ui] != nil && unitList[i].hp > 0 {
targets = append(targets, unitList[ui])
}
}
if len(targets) == 0 {
continue
}
case priorityArgBack:
for ui := range []int{3, 4, 5} {
if unitList[ui] != nil && unitList[i].hp > 0 {
targets = append(targets, unitList[ui])
}
}
if len(targets) == 0 {
continue
}
case priorityArgColumn:
var columns [][]*_BattleUnit
for _, ui := range []int{0, 1, 2} {
var column []*_BattleUnit
if unitList[ui] != nil && unitList[i].hp > 0 {
column = append(column, unitList[ui])
}
if unitList[ui+3] != nil && unitList[i].hp > 0 {
column = append(column, unitList[ui+3])
}
if len(column) > 0 {
columns = append(columns, column)
}
}
for _, column := range util.RandomSelect(this.rd, columns, int(rangeNum)) {
for ui := range column {
targets = append(targets, column[ui])
}
}
return targets
}
case priorityTypeHp:
for ui := range unitList {
if unitList[ui] != nil && unitList[i].hp > 0 {
targets = append(targets, unitList[ui])
}
}
sort.Slice(targets, func(i, j int) bool {
if priorityArgs[i] == priorityArgMin {
return targets[i].hp < targets[j].hp
} else {
return targets[i].hp > targets[j].hp
}
})
break
case priorityTypeGender:
for ui := range unitList {
if unitList[ui] == nil || unitList[ui].hp == 0 || unitList[ui].gender != priorityArgs[i] {
continue
}
targets = append(targets, unitList[ui])
}
if len(targets) == 0 {
continue
}
case priorityTypeRage:
for ui := range unitList {
if unitList[ui] != nil && unitList[i].hp > 0 {
targets = append(targets, unitList[ui])
}
}
sort.Slice(targets, func(i, j int) bool {
if priorityArgs[i] == priorityArgMin {
return targets[i].rage < targets[j].rage
} else {
return targets[i].rage > targets[j].rage
}
})
break
case priorityTypeAttack:
for ui := range unitList {
if unitList[ui] != nil && unitList[i].hp > 0 {
targets = append(targets, unitList[ui])
}
}
sort.Slice(targets, func(i, j int) bool {
if priorityArgs[i] == priorityArgMin {
return float64(unitList[i].attrs[pb.AttrType_Attack])*(1.0+float64(unitList[i].attrs[pb.AttrType_AttackRatio])*ratioIn) < float64(unitList[j].attrs[pb.AttrType_Attack])*(1.0+float64(unitList[j].attrs[pb.AttrType_AttackRatio])*ratioIn)
} else {
return float64(unitList[i].attrs[pb.AttrType_Attack])*(1.0+float64(unitList[i].attrs[pb.AttrType_AttackRatio])*ratioIn) > float64(unitList[j].attrs[pb.AttrType_Attack])*(1.0+float64(unitList[j].attrs[pb.AttrType_AttackRatio])*ratioIn)
}
})
break
}
}
if len(targets) == 0 {
for ui := range unitList {
if unitList[ui] != nil && unitList[ui].hp > 0 {
targets = append(targets, unitList[ui])
}
}
}
if rangeType == rangeTypeSingle {
return targets[:1]
} else {
if uint32(len(targets)) <= rangeNum {
return targets
} else {
return targets[:rangeNum]
}
}
}
func (this *_BattleCalculator) calcDamage(buff *_BattleBuff, unit *_BattleUnit, target *_BattleUnit) int64 {
var defense float64
switch buff.buffType {
case buffTypePhysicalDamage:
defense = float64(target.attrs[pb.AttrType_PhysicalDefense]) * (1.0 + float64(target.attrs[pb.AttrType_PhysicalDefenseRatio])*ratioIn)
case buffTypeMagicDamage:
defense = float64(target.attrs[pb.AttrType_MagicDefense]) * (1.0 + float64(target.attrs[pb.AttrType_MagicDefenseRatio])*ratioIn)
default:
return 0
}
if len(buff.buffArgs) < 2 {
return 0
}
var attack = float64(unit.attrs[pb.AttrType_Attack]) * (1.0 + float64(unit.attrs[pb.AttrType_AttackRatio])*ratioIn)
var damage float64
if buff.buffArgs[0] == 1 {
damage = float64(buff.buffArgs[1])
} else {
damage = attack * (float64(buff.buffArgs[1]) * ratioIn)
}
var damageRatio = 1.0 + float64(unit.attrs[pb.AttrType_DamageRatio]-target.attrs[pb.AttrType_DamageRelief])*ratioIn
var finalDamageRatio = 1.0 + float64(unit.attrs[pb.AttrType_FinalDamageRatio])*ratioIn
var finalDamageRelief = 1.0 - float64(target.attrs[pb.AttrType_FinalDamageRelief])*ratioIn
var criticalRate = (float64(unit.attrs[pb.AttrType_CriticalRate]) - float64(target.attrs[pb.AttrType_CriticalResistance])) * ratioIn
var factor = this.rd.Float64()
if factor <= criticalRate {
var criticalDamage = float64(unit.attrs[pb.AttrType_CriticalDamage]) * ratioIn
var criticalDamageRelief = float64(unit.attrs[pb.AttrType_CriticalDamageRelief]) * ratioIn
damage = ((damage - defense) * damageRatio * 2) * (criticalDamage - criticalDamageRelief) * finalDamageRatio * finalDamageRelief
} else {
damage = (damage - defense) * damageRatio * finalDamageRatio * finalDamageRelief
if damage <= 0 {
damage = 1
}
}
return int64(-damage)
}
func (this *_BattleCalculator) calcTreat(buff _BattleBuff, unit *_BattleUnit, target *_BattleUnit) int64 {
return 0
}

View File

@ -0,0 +1,76 @@
package logic
const (
targetTypeSelf = 0 //自身
targetTypeTeammate = 1 //友方
targetTypeEnemy = 2 //敌方
targetTypeTeammateGender = 3 //友方特定性别
targetTypeEnemyGender = 4 //敌方特定性别
targetTypeTeammateCountry = 5 //友方特定国家
targetTypeEnemyCountry = 6 //敌方特定国家
targetTypeTeammateStatus = 7 //友方异常目标
targetTypeEnemyStatus = 8 //敌方异常目标
targetTypeAttackRate = 9 //击中数量少于目标数量万分比
)
const (
countryNone = 0 //无国家
countryWei = 1 //魏
countryShu = 2 //蜀
countryMouse = 3 //鼠辈
countryCrowd = 4 //群雄
)
const (
rangeTypeSingle = 0 //单个
rangeTypeMulti = 0 //多个
)
const (
priorityTypeNone = 0 //没有优先
priorityTypePosition = 1 //位置优先
priorityTypeHp = 2 //血量优先
priorityTypeGender = 3 //性别优先
priorityTypeRage = 4 //怒气优先
priorityTypeAttack = 5 //攻击力优先
)
const (
priorityArgFront = 0 //前排
priorityArgBack = 1 //后排
priorityArgColumn = 2 //纵排
priorityArgFemale = 0 //女性
priorityArgMale = 1 //男性
priorityArgMin = 0 //最低
priorityArgMax = 1 //最高
)
const (
buffTypeNone = 0
buffTypePhysicalDamage = 1 //物理伤害
buffTypeMagicDamage = 2 //法术伤害
buffTypeStatusAbnormal = 3 //异常状态(无法攻击,无法移动等)
buffTypeChangeAttr = 4 //改变属性
buffTypeRevive = 5 //复活
buffTypeDamageReturn = 6 //伤害反弹
buffTypeBisect = 7 //伤害平摊(分担)
buffTypeShield = 8 //护盾
buffTypeChangeHp = 9 //改变血量
buffTypeSteal = 10 //窃取属性
buffTypeAddRage = 11 //增加怒气
buffTypeImmune = 12 //免疫
buffTypeUndead = 13 //不死
buffTypeDamageShare = 14 //伤害共享(共享)
buffTypeEffectAbnormal = 15 //异常效果DeBuff
)
const (
skillTypeAttack = 1 //普击
skillTypeActive = 2 //主动
skillTypePassive = 3 //被动
)
const (
ratioIn float64 = 0.0001
ratioOut float64 = 10000
)

View File

@ -47,7 +47,7 @@ func (this *Player) PassedCopyMain(copyMainTable *data.CopyMain, maxScore int32)
//this.CopyMainSceneId = uint32(copyChapterTable.SceneId)
//this.SaveField("role.mainline_scene_id", this.Role.CopyMainSceneId)
_ = this.Send(uint16(pb.ModId_ModuleLevel), uint16(pb.MsgId_ModLevelCopyStatusChange), &pb.MsgCopyStatusChangeAck{Status: copyStatus.BuildMsgCopyStatus()})
_ = this.Send(pb.ModId_ModuleLevel, pb.MsgId_ModLevelCopyStatusChange, &pb.MsgCopyStatusChangeAck{Status: copyStatus.BuildMsgCopyStatus()})
//var copyMainRanking = this.manager.arenaManager.copyMainRanking
//if copyMainRanking != nil {

View File

@ -5,7 +5,7 @@ import (
"github.com/oylshe1314/framework/util"
)
type Attrs [pb.AttrType_Nums]uint64
type Attrs [pb.AttrType_AttrNums]uint64
type PlayerHero struct {
Uid uint64 `json:"uid" key:"1"`
@ -69,10 +69,12 @@ func (this *Player) AddHero(heroId uint32) bool {
hero.Level = 1
}
this.updateHeroAttrs(hero, nil, nil)
this.Hero[hero.Uid] = hero
this.SaveModel(hero)
_ = this.Send(uint16(pb.ModId_ModuleHero), uint16(pb.MsgId_ModHeroChange), &pb.HeroChangeListAck{
_ = this.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, &pb.HeroChangeListAck{
ChangeList: []*pb.HeroChange{{ChangeType: pb.ChangeType_Add, Hero: hero.BuildMsgHero()}},
})
@ -100,6 +102,8 @@ func (this *Player) AddHeroes(heroId, nums uint32) bool {
Level: level,
}
this.updateHeroAttrs(hero, nil, nil)
this.Hero[hero.Uid] = hero
this.SaveModel(hero)
@ -108,7 +112,7 @@ func (this *Player) AddHeroes(heroId, nums uint32) bool {
//this.CheckAchievement(proto.AchievementTypeEquipLevel, uint32(equipTable.Level), 1)
}
_ = this.Send(uint16(pb.ModId_ModuleHero), uint16(pb.MsgId_ModHeroChange), &pb.HeroChangeListAck{
_ = this.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, &pb.HeroChangeListAck{
ChangeList: changeList,
})
@ -133,7 +137,7 @@ func (this *Player) ReduceHeroes(heroes map[uint64]*PlayerHero, logType LogType)
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})
_ = this.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, &pb.HeroChangeListAck{ChangeList: changeList})
}
func (this *Player) BuildMsgHeroListAck() *pb.HeroListAck {

View File

@ -298,14 +298,6 @@ func (this *Player) calcHeroArtifactAttrs(hero *PlayerHero, lineup *PlayerLineup
return
}
func (this *Player) calcHeroSpeedAttrs(hero *PlayerHero, lineup *PlayerLineup, lineupHero *PlayerLineupHero) (attrs Attrs) {
if lineup == nil || lineupHero == nil {
return
}
hero.attrs[pb.AttrType_AttrSpeed] = 100 + uint64(20-(4*((lineupHero.Position-1)%3)))
return
}
func (this *Player) calcHeroAttrs(hero *PlayerHero, attrsList ...Attrs) bool {
var newAttrs Attrs
for _, attrs := range attrsList {
@ -333,7 +325,6 @@ func (this *Player) updateHeroAttrs(hero *PlayerHero, lineup *PlayerLineup, line
this.calcHeroTreasuresAttrs(hero, lineup, lineupHero),
this.calcHeroMountsAttrs(hero, lineup, lineupHero),
this.calcHeroArtifactAttrs(hero, lineup, lineupHero),
this.calcHeroSpeedAttrs(hero, lineup, lineupHero),
)
}

View File

@ -74,7 +74,7 @@ func (this *Player) SendLineupHeroChange(lineups ...*PlayerLineup) {
}
}
if len(heroChangeList) > 0 {
_ = this.Send(uint16(pb.ModId_ModuleHero), uint16(pb.MsgId_ModHeroChange), pb.HeroChangeListAck{
_ = this.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, pb.HeroChangeListAck{
ChangeList: heroChangeList,
})
}
@ -178,10 +178,10 @@ func (this *Player) SendUpgradeMaster(masterType pb.UpgradeMasterType, preLevel,
ack.PreLevel = uint32(preMasterTable.Level)
}
_ = this.Send(uint16(pb.ModId_ModuleRole), uint16(pb.MsgId_ModRoleUpgradeMaster), ack)
_ = this.Send(pb.ModId_ModuleRole, pb.MsgId_ModRoleUpgradeMaster, ack)
if this.updateHeroAttrs(hero, lineup, lineupHero) {
_ = this.Send(uint16(pb.ModId_ModuleHero), uint16(pb.MsgId_ModHeroChange), pb.HeroChangeListAck{
_ = this.Send(pb.ModId_ModuleHero, pb.MsgId_ModHeroChange, pb.HeroChangeListAck{
ChangeList: []*pb.HeroChange{{ChangeType: pb.ChangeType_Changed, Hero: hero.BuildMsgHero()}},
})
}

View File

@ -49,23 +49,5 @@ func (this *Player) UpdateBattleHeroCapacity(lineupHero *PlayerLineupHero) {
return
}
var attrs = hero.Attrs()
var capacity = (float64(attrs[pb.AttrType_Attack]) * 2) +
(float64(attrs[pb.AttrType_Hp]) * 0.2) +
(float64(attrs[pb.AttrType_AttrPhysicalDefense]) * 6) +
(float64(attrs[pb.AttrType_AttrMagicDefense]) * 6) +
(float64(attrs[pb.AttrType_AttrDamageRatio]) * 12) +
(float64(attrs[pb.AttrType_AttrDamageRelief]) * 12) +
(float64(attrs[pb.AttrType_AttrCriticalRatio]) * 12) +
(float64(attrs[pb.AttrType_AttrCriticalResistance]) * 12) +
(float64(attrs[pb.AttrType_AttrCriticalDamage]) * 12) +
(float64(attrs[pb.AttrType_AttrCriticalDamageRelief]) * 12) +
(float64(attrs[pb.AttrType_AttrHitRate]) * 12) +
(float64(attrs[pb.AttrType_AttrDodgeRate]) * 12) +
(float64(attrs[pb.AttrType_AttrTreatRatio]) * 12) +
(float64(attrs[pb.AttrType_AttrByTreatedRatio]) * 12) +
(float64(attrs[pb.AttrType_AttrFinalDamageRatio]) * 12)
lineupHero.Capacity = uint64(capacity)
lineupHero.Capacity = this.calcAttrsCapacity(hero.attrs)
}