diff --git a/proto/check.go b/proto/check.go index 4dc25fa..fda5227 100644 --- a/proto/check.go +++ b/proto/check.go @@ -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 } diff --git a/proto/idl/mod_battle.proto b/proto/idl/mod_battle.proto index 1438c8f..f35be2f 100644 --- a/proto/idl/mod_battle.proto +++ b/proto/idl/mod_battle.proto @@ -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; //自己是英雄唯一ID,敌人是怪物表ID,敌对玩家是英雄表ID uint32 SuitId = 2; //时装ID - // } // MsgId.ModBattleEnter = 4001; diff --git a/proto/idl/mod_level.proto b/proto/idl/mod_level.proto index 58a554c..6162df3 100644 --- a/proto/idl/mod_level.proto +++ b/proto/idl/mod_level.proto @@ -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 { diff --git a/proto/idl/mod_role.proto b/proto/idl/mod_role.proto index 0410a58..ef1f71e 100644 --- a/proto/idl/mod_role.proto +++ b/proto/idl/mod_role.proto @@ -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 { diff --git a/servers/game/data/drop.go b/servers/game/data/drop.go new file mode 100644 index 0000000..af0c414 --- /dev/null +++ b/servers/game/data/drop.go @@ -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 +} diff --git a/servers/game/data/monster.go b/servers/game/data/monster.go index c07c20c..cb01e24 100644 --- a/servers/game/data/monster.go +++ b/servers/game/data/monster.go @@ -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"` diff --git a/servers/game/data/scene.go b/servers/game/data/scene.go index 1686fde..d2e755a 100644 --- a/servers/game/data/scene.go +++ b/servers/game/data/scene.go @@ -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"` diff --git a/servers/game/data/skill.go b/servers/game/data/skill.go index d0adc94..86160ed 100644 --- a/servers/game/data/skill.go +++ b/servers/game/data/skill.go @@ -3,9 +3,10 @@ package data import json "github.com/json-iterator/go" type Skill struct { - Id int `json:"id"` - SkillType int `json:"skill_type"` - SkillBuff []int `json:"skill_buff"` + Id int `json:"id"` + SkillType int `json:"skill_type"` + RageConsume int `json:"rage_consume"` + SkillBuff []int `json:"skill_buff"` } type SkillTable struct { diff --git a/servers/game/data/skill_buff.go b/servers/game/data/skill_buff.go index 63b56df..0b05ae3 100644 --- a/servers/game/data/skill_buff.go +++ b/servers/game/data/skill_buff.go @@ -3,9 +3,22 @@ package data import json "github.com/json-iterator/go" type SkillBuff struct { - Id int `json:"id"` - SkillBuffType int `json:"SkillBuff_type"` - SkillBuffBuff []int `json:"SkillBuff_buff"` + Id int `json:"id"` + 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 { diff --git a/servers/game/data/tables.go b/servers/game/data/tables.go index f7aa4c5..53ef0e6 100644 --- a/servers/game/data/tables.go +++ b/servers/game/data/tables.go @@ -19,6 +19,7 @@ type Tables struct { Copy CopyTable CopyMain CopyMainTable + Drop DropTable Equip EquipTable EquipLevel EquipLevelTable EquipRefine EquipRefineTable diff --git a/servers/game/handler/player_level.go b/servers/game/handler/player_level.go index a6eb111..49da23c 100644 --- a/servers/game/handler/player_level.go +++ b/servers/game/handler/player_level.go @@ -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 } diff --git a/servers/game/logic/player_battle.go b/servers/game/logic/player_battle.go index c4e4ed0..5e7e57f 100644 --- a/servers/game/logic/player_battle.go +++ b/servers/game/logic/player_battle.go @@ -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 + 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 - attrs Attrs + 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, + SceneId: uint32(sceneTable.Id), } 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} - } - if enemies[i] != nil { - ack.Enemies[i] = &pb.BattleUnit{UnitId: enemies[i].id} + for i := range me.unitList { + if me.unitList[i] != nil { + ack.Heroes[i] = &pb.BattleUnit{ + UnitId: me.unitList[i].id, + } } } - ack.Succeed, ack.Score, ack.RoundList = this.calcBattle(heroes, enemies) - ack.BattleRounds = uint32(len(ack.RoundList)) + 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 { @@ -220,30 +349,48 @@ func (this *Player) loadSkills(skillIds []int) (skillList []*_BattleSkill, tip p } var skill = &_BattleSkill{ - id: uint32(skillId), + 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 } diff --git a/servers/game/logic/player_battle_calculator.go b/servers/game/logic/player_battle_calculator.go new file mode 100644 index 0000000..9bca3d3 --- /dev/null +++ b/servers/game/logic/player_battle_calculator.go @@ -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 +} diff --git a/servers/game/logic/player_battle_define.go b/servers/game/logic/player_battle_define.go new file mode 100644 index 0000000..41bbfde --- /dev/null +++ b/servers/game/logic/player_battle_define.go @@ -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 +) diff --git a/servers/game/logic/player_copy_status.go b/servers/game/logic/player_copy_status.go index 1dea7f9..c76aaed 100644 --- a/servers/game/logic/player_copy_status.go +++ b/servers/game/logic/player_copy_status.go @@ -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 { diff --git a/servers/game/logic/player_hero.go b/servers/game/logic/player_hero.go index 0ddf485..2fbb5d4 100644 --- a/servers/game/logic/player_hero.go +++ b/servers/game/logic/player_hero.go @@ -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 { diff --git a/servers/game/logic/player_hero_attrs.go b/servers/game/logic/player_hero_attrs.go index b96cd45..df8dcae 100644 --- a/servers/game/logic/player_hero_attrs.go +++ b/servers/game/logic/player_hero_attrs.go @@ -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), ) } diff --git a/servers/game/logic/player_lineup.go b/servers/game/logic/player_lineup.go index c6a75fd..3b206f6 100644 --- a/servers/game/logic/player_lineup.go +++ b/servers/game/logic/player_lineup.go @@ -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()}}, }) } diff --git a/servers/game/logic/player_lineup_hero.go b/servers/game/logic/player_lineup_hero.go index 7ba48a3..0533b18 100644 --- a/servers/game/logic/player_lineup_hero.go +++ b/servers/game/logic/player_lineup_hero.go @@ -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) }