2025-09-14 01:35:16 +08:00
|
|
|
|
package fight
|
2025-09-04 02:00:57 +08:00
|
|
|
|
|
|
|
|
|
|
import (
|
2025-10-27 01:11:31 +08:00
|
|
|
|
"blazing/common/utils"
|
2025-09-14 01:35:16 +08:00
|
|
|
|
"blazing/logic/service/common"
|
2025-09-28 08:13:42 +00:00
|
|
|
|
"blazing/logic/service/fight/action"
|
2025-09-04 02:00:57 +08:00
|
|
|
|
"blazing/logic/service/fight/info"
|
2025-09-14 01:35:16 +08:00
|
|
|
|
"blazing/logic/service/fight/input"
|
|
|
|
|
|
"blazing/logic/service/player"
|
2025-10-27 01:11:31 +08:00
|
|
|
|
"blazing/modules/blazing/model"
|
2025-09-04 03:14:43 +08:00
|
|
|
|
"fmt"
|
2025-09-04 23:57:22 +08:00
|
|
|
|
"math/rand"
|
2025-10-10 00:40:32 +08:00
|
|
|
|
"reflect"
|
2025-09-14 01:35:16 +08:00
|
|
|
|
"sort"
|
2025-09-04 03:14:43 +08:00
|
|
|
|
"time"
|
2025-09-04 02:00:57 +08:00
|
|
|
|
|
2025-09-26 21:15:58 +00:00
|
|
|
|
"github.com/barkimedes/go-deepcopy"
|
2025-09-04 02:00:57 +08:00
|
|
|
|
"github.com/jinzhu/copier"
|
2025-09-26 13:33:55 +08:00
|
|
|
|
"github.com/shopspring/decimal"
|
2025-09-04 02:00:57 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type FightC struct {
|
2025-09-08 01:23:12 +08:00
|
|
|
|
Info info.NoteReadyToFightInfo
|
2025-09-07 05:58:47 +08:00
|
|
|
|
|
2025-09-19 06:58:42 +00:00
|
|
|
|
ownerID uint32 // 战斗发起者ID
|
|
|
|
|
|
Our *input.Input //始终等于房主ID
|
|
|
|
|
|
Opp *input.Input //对手ID
|
2025-09-28 08:13:42 +00:00
|
|
|
|
Switch []*action.ActiveSwitchAction
|
2025-09-19 06:58:42 +00:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
rand *rand.Rand
|
2025-09-04 23:57:22 +08:00
|
|
|
|
StartTime time.Time
|
2025-09-28 08:13:42 +00:00
|
|
|
|
actionChan chan action.BattleActionI // 所有操作统一从这里进入
|
|
|
|
|
|
Round int //回合数
|
2025-09-14 03:36:26 +08:00
|
|
|
|
|
2025-09-14 19:59:58 +08:00
|
|
|
|
First *input.Input
|
|
|
|
|
|
Second *input.Input
|
|
|
|
|
|
closefight bool
|
2025-09-08 01:23:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
func (f *FightC) Ownerid() uint32 {
|
|
|
|
|
|
|
|
|
|
|
|
return f.ownerID
|
|
|
|
|
|
}
|
|
|
|
|
|
func (f *FightC) GetInputByPlayer(c common.PlayerI, isOpposite bool) *input.Input {
|
2025-09-08 01:23:12 +08:00
|
|
|
|
// 判断当前玩家是否为我方玩家
|
2025-09-24 12:40:13 +08:00
|
|
|
|
isOurPlayer := c.GetInfo().UserID == f.ownerID
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-09-23 13:24:40 +08:00
|
|
|
|
// 当isOurPlayer与isOpposite值不同时返回我方,相同时返回对方
|
|
|
|
|
|
if isOurPlayer != isOpposite {
|
|
|
|
|
|
return f.Our
|
2025-09-08 01:23:12 +08:00
|
|
|
|
}
|
2025-09-23 13:24:40 +08:00
|
|
|
|
return f.Opp
|
2025-09-08 01:23:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-28 08:13:42 +00:00
|
|
|
|
func (f *FightC) GetInputByAction(c action.BattleActionI, isOpposite bool) *input.Input {
|
2025-09-08 01:23:12 +08:00
|
|
|
|
// 判断动作所属玩家是否为我方
|
2025-09-21 14:56:37 +00:00
|
|
|
|
isOurAction := c.GetPlayerID() == f.Our.Player.GetInfo().UserID
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据isOpposite决定是否返回相反方向的输入
|
|
|
|
|
|
if isOurAction == !isOpposite {
|
|
|
|
|
|
return f.Our
|
|
|
|
|
|
}
|
|
|
|
|
|
return f.Opp
|
2025-09-05 22:40:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
// 玩家使用技能
|
|
|
|
|
|
func (f *FightC) GetCurrPET(c common.PlayerI) *info.BattlePetEntity {
|
2025-09-21 14:56:37 +00:00
|
|
|
|
if f.Our.Player.GetInfo().UserID == c.GetInfo().UserID {
|
2025-09-14 01:35:16 +08:00
|
|
|
|
return f.Our.CurrentPet
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return f.Opp.CurrentPet
|
|
|
|
|
|
}
|
2025-09-11 02:44:21 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-14 03:36:26 +08:00
|
|
|
|
// 获取随机数
|
|
|
|
|
|
func (f *FightC) GetRand() *rand.Rand {
|
2025-09-04 02:00:57 +08:00
|
|
|
|
|
2025-09-14 03:36:26 +08:00
|
|
|
|
return f.rand
|
2025-09-05 22:40:36 +08:00
|
|
|
|
|
2025-09-04 23:57:22 +08:00
|
|
|
|
}
|
2025-09-07 00:23:28 +08:00
|
|
|
|
|
2025-09-30 18:32:15 +08:00
|
|
|
|
// 获取随机数
|
|
|
|
|
|
func (f *FightC) IsFirst(play common.PlayerI) bool {
|
|
|
|
|
|
|
2025-10-14 01:26:59 +08:00
|
|
|
|
return f.First.Player == play
|
2025-09-30 18:32:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-25 14:51:11 +00:00
|
|
|
|
// 加载进度
|
|
|
|
|
|
func (f *FightC) LoadPercent(c common.PlayerI, percent int32) {
|
|
|
|
|
|
f.GetInputByPlayer(c, true).Player.SendLoadPercent(info.LoadPercentOutboundInfo{
|
|
|
|
|
|
Id: c.GetInfo().UserID,
|
|
|
|
|
|
Percent: uint32(percent),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-28 22:08:27 +08:00
|
|
|
|
func (f *FightC) initplayer(c common.PlayerI, opp bool) bool {
|
|
|
|
|
|
if len(c.GetInfo().PetList) == 0 {
|
|
|
|
|
|
return false
|
2025-09-04 23:57:22 +08:00
|
|
|
|
|
2025-10-28 22:08:27 +08:00
|
|
|
|
}
|
2025-09-14 04:48:38 +08:00
|
|
|
|
temp := input.NewInput(f, c)
|
2025-09-14 01:35:16 +08:00
|
|
|
|
temp.AllPet = make([]*info.BattlePetEntity, 0)
|
2025-10-21 22:14:30 +08:00
|
|
|
|
|
2025-09-21 14:56:37 +00:00
|
|
|
|
for i := 0; i < len(c.GetInfo().PetList); i++ {
|
2025-09-14 01:35:16 +08:00
|
|
|
|
if f.Info.MAXPET == 0 || i < int(f.Info.MAXPET) {
|
|
|
|
|
|
|
2025-09-21 14:56:37 +00:00
|
|
|
|
temp.AllPet = append(temp.AllPet, info.CreateBattlePetEntity(&c.GetInfo().PetList[i], f.rand))
|
2025-09-08 01:23:12 +08:00
|
|
|
|
}
|
2025-09-04 23:57:22 +08:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
}
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
|
|
|
|
|
sort.Slice(temp.AllPet, func(i, j int) bool {
|
|
|
|
|
|
x, y := temp.AllPet[i], temp.AllPet[j]
|
|
|
|
|
|
// 若x血量>0且y血量=0,则x排在前
|
|
|
|
|
|
if x.Info.Hp > 0 && y.Info.Hp <= 0 {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
// 若x血量=0且y血量>0,则x排在后
|
|
|
|
|
|
if x.Info.Hp <= 0 && y.Info.Hp > 0 {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
// 同类型(都>0或都=0)保持原有顺序
|
|
|
|
|
|
return i < j
|
|
|
|
|
|
})
|
|
|
|
|
|
if opp {
|
|
|
|
|
|
f.Opp = temp //这里是对方的
|
|
|
|
|
|
copier.Copy(&f.Info.OpponentInfo, f.Opp.Player.GetInfo())
|
|
|
|
|
|
f.Info.OpponentPetList = make([]info.ReadyFightPetInfo, len(temp.AllPet))
|
|
|
|
|
|
for i := 0; i < len(temp.AllPet); i++ {
|
|
|
|
|
|
|
2025-09-25 13:07:56 +08:00
|
|
|
|
err := copier.CopyWithOption(&f.Info.OpponentPetList[i], &temp.AllPet[i].Info, copier.Option{IgnoreEmpty: true, DeepCopy: true})
|
2025-09-14 01:35:16 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
panic(err)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
f.Our = temp
|
|
|
|
|
|
copier.Copy(&f.Info.OurInfo, f.Our.Player.GetInfo())
|
|
|
|
|
|
f.Info.OurPetList = make([]info.ReadyFightPetInfo, len(temp.AllPet))
|
|
|
|
|
|
for i := 0; i < len(temp.AllPet); i++ {
|
|
|
|
|
|
|
|
|
|
|
|
err := copier.CopyWithOption(&f.Info.OurPetList[i], &temp.AllPet[i].Info, copier.Option{IgnoreEmpty: true, DeepCopy: true})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
panic(err)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-07 05:58:47 +08:00
|
|
|
|
}
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
|
|
|
|
|
for _, v := range temp.AllPet {
|
|
|
|
|
|
if v.Info.Hp == 0 {
|
|
|
|
|
|
v.NotAlive = true
|
|
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
}
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
temp.CurrentPet = temp.AllPet[0]
|
2025-10-28 22:08:27 +08:00
|
|
|
|
return true
|
2025-09-14 01:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建新战斗,邀请方和被邀请方,或者玩家和野怪方
|
2025-09-25 14:51:11 +00:00
|
|
|
|
func NewFight(mode, status info.EnumBattleMode, p1 common.PlayerI, p2 common.PlayerI) *FightC {
|
2025-09-14 01:35:16 +08:00
|
|
|
|
f := &FightC{}
|
2025-09-21 14:56:37 +00:00
|
|
|
|
f.ownerID = p1.GetInfo().UserID
|
2025-09-25 14:51:11 +00:00
|
|
|
|
f.Info.Status = status //房主
|
|
|
|
|
|
f.Info.Mode = mode
|
|
|
|
|
|
switch mode {
|
|
|
|
|
|
case info.BattleMode.SINGLE_MODE:
|
2025-09-20 00:17:29 +08:00
|
|
|
|
f.Info.MAXPET = 1
|
2025-09-25 14:51:11 +00:00
|
|
|
|
default:
|
2025-09-20 00:17:29 +08:00
|
|
|
|
}
|
2025-10-22 00:25:38 +08:00
|
|
|
|
f.StartTime = time.Now()
|
2025-09-21 14:56:37 +00:00
|
|
|
|
seed := f.StartTime.UnixNano() ^ int64(p1.GetInfo().UserID) ^ int64(p2.GetInfo().UserID) // ^ int64(f.Round) // 用异或运算混合多维度信息
|
2025-09-14 01:35:16 +08:00
|
|
|
|
f.rand = rand.New(rand.NewSource(seed))
|
|
|
|
|
|
f.Info = info.NoteReadyToFightInfo{
|
|
|
|
|
|
|
2025-09-25 14:51:11 +00:00
|
|
|
|
Status: status,
|
2025-09-06 00:31:08 +08:00
|
|
|
|
}
|
2025-10-28 22:08:27 +08:00
|
|
|
|
ok := f.initplayer(p1, false)
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
2025-10-28 22:08:27 +08:00
|
|
|
|
ok = f.initplayer(p2, true)
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2025-09-06 00:31:08 +08:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
defer func() {
|
|
|
|
|
|
rr := Fightpool.Submit(f.battleLoop)
|
|
|
|
|
|
if rr != nil {
|
|
|
|
|
|
panic(rr)
|
|
|
|
|
|
}
|
2025-09-14 01:35:16 +08:00
|
|
|
|
f.Broadcast(func(ff *input.Input) {
|
2025-09-04 03:14:43 +08:00
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
ff.Player.SendNoteReadyToFightInfo(f.Info)
|
2025-09-08 01:23:12 +08:00
|
|
|
|
})
|
|
|
|
|
|
}()
|
2025-10-21 22:14:30 +08:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
return f
|
2025-09-04 03:14:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
// 被击败的ID
|
|
|
|
|
|
func (b *FightC) IsWin(c *input.Input, cache uint32) bool {
|
|
|
|
|
|
|
|
|
|
|
|
var tt []*info.BattlePetEntity
|
|
|
|
|
|
bbb := b.Our.AllPet
|
|
|
|
|
|
|
2025-09-21 14:56:37 +00:00
|
|
|
|
if c.Player.GetInfo().UserID == b.ownerID { //如果是房主
|
2025-09-14 01:35:16 +08:00
|
|
|
|
bbb = b.Opp.AllPet
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, v := range bbb {
|
|
|
|
|
|
if v.Info.CatchTime == cache {
|
|
|
|
|
|
v.NotAlive = true
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
tt = append(tt, v)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, v := range tt {
|
|
|
|
|
|
if !v.NotAlive { //如果存活
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-05 22:40:36 +08:00
|
|
|
|
// 广播,并是否结束回合
|
2025-09-14 01:35:16 +08:00
|
|
|
|
func (f *FightC) Broadcast(t func(ff *input.Input)) {
|
2025-09-07 05:58:47 +08:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
t(f.Our)
|
|
|
|
|
|
t(f.Opp)
|
2025-09-07 05:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-04 23:57:22 +08:00
|
|
|
|
// 战斗回合循环
|
2025-09-04 03:14:43 +08:00
|
|
|
|
func (f *FightC) battleLoop() {
|
2025-10-22 00:25:38 +08:00
|
|
|
|
|
2025-09-28 08:13:42 +00:00
|
|
|
|
f.actionChan = make(chan action.BattleActionI, 2) // 初始化全局操作通道
|
2025-09-21 14:56:37 +00:00
|
|
|
|
fmt.Println("战斗开始精灵", f.Our.Player.GetInfo().PetList[0].CatchTime)
|
2025-09-08 01:23:12 +08:00
|
|
|
|
//战斗开始前操作
|
|
|
|
|
|
|
2025-09-04 23:57:22 +08:00
|
|
|
|
for {
|
2025-09-07 05:58:47 +08:00
|
|
|
|
|
2025-09-14 19:59:58 +08:00
|
|
|
|
if f.closefight { //回合数超过250,战斗平局结束f.Round > 250 ||
|
|
|
|
|
|
close(f.actionChan)
|
2025-09-10 00:41:09 +08:00
|
|
|
|
break
|
2025-09-05 22:40:36 +08:00
|
|
|
|
}
|
2025-09-14 19:59:58 +08:00
|
|
|
|
|
2025-09-28 08:13:42 +00:00
|
|
|
|
f.Round++ //回合数自增
|
|
|
|
|
|
actions := make(map[uint32]action.BattleActionI) // 每个玩家一条记录
|
2025-10-21 22:14:30 +08:00
|
|
|
|
timeout := time.After(60 * time.Second)
|
2025-09-04 23:57:22 +08:00
|
|
|
|
|
|
|
|
|
|
for len(actions) < 2 {
|
2025-09-04 03:14:43 +08:00
|
|
|
|
select {
|
2025-09-28 08:13:42 +00:00
|
|
|
|
case paction, ok := <-f.actionChan:
|
2025-09-08 01:23:12 +08:00
|
|
|
|
// 只接受有效玩家 ID\
|
2025-09-28 08:13:42 +00:00
|
|
|
|
if paction == nil {
|
2025-09-04 23:57:22 +08:00
|
|
|
|
continue
|
|
|
|
|
|
}
|
2025-09-14 19:59:58 +08:00
|
|
|
|
if !ok {
|
|
|
|
|
|
fmt.Println("战斗结束")
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2025-10-22 21:30:05 +08:00
|
|
|
|
if f.closefight { //回合数超过250,战斗平局结束f.Round > 250 ||
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-10-22 21:30:05 +08:00
|
|
|
|
break
|
|
|
|
|
|
}
|
2025-09-28 08:13:42 +00:00
|
|
|
|
if paction.GetPlayerID() != f.Our.Player.GetInfo().UserID && paction.GetPlayerID() != f.Opp.Player.GetInfo().UserID {
|
2025-09-08 01:23:12 +08:00
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-10 00:40:32 +08:00
|
|
|
|
if _, isExpelled := paction.(*action.ActiveSwitchAction); isExpelled {
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-09-28 08:13:42 +00:00
|
|
|
|
if f.GetInputByAction(paction, false).CanChange {
|
2025-09-08 01:23:12 +08:00
|
|
|
|
//如果是被动切换,不计入回合结算
|
2025-09-28 08:13:42 +00:00
|
|
|
|
f.GetInputByAction(paction, false).CanChange = false
|
2025-09-07 00:23:28 +08:00
|
|
|
|
continue
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-09-07 00:23:28 +08:00
|
|
|
|
}
|
2025-09-05 22:40:36 +08:00
|
|
|
|
|
2025-09-07 00:23:28 +08:00
|
|
|
|
}
|
2025-09-05 22:40:36 +08:00
|
|
|
|
|
2025-10-10 00:40:32 +08:00
|
|
|
|
if paction.GetPlayerID() != 0 {
|
|
|
|
|
|
if f.Info.Status == info.BattleStatus.FIGHT_WITH_BOSS || f.Info.Status == info.BattleStatus.FIGHT_WITH_NPC {
|
|
|
|
|
|
//AI的action实质上就是放技能,如果阻止掉,比如中毒,那就也不能逃跑
|
|
|
|
|
|
f.GetInputByAction(paction, true).GetAction(f.Our)
|
|
|
|
|
|
}
|
2025-09-05 22:40:36 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-09-04 23:57:22 +08:00
|
|
|
|
// 如果该玩家已经提交过,就忽略重复动作
|
2025-09-28 08:13:42 +00:00
|
|
|
|
if _, exists := actions[uint32(paction.GetPlayerID())]; exists {
|
|
|
|
|
|
fmt.Printf("玩家%d 已经提交过动作,忽略重复\n", paction.GetPlayerID())
|
2025-09-04 23:57:22 +08:00
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-28 08:13:42 +00:00
|
|
|
|
actions[uint32(paction.GetPlayerID())] = paction
|
|
|
|
|
|
fmt.Println("玩家 执行动作", paction.GetPlayerID(), paction.Priority())
|
2025-09-04 23:57:22 +08:00
|
|
|
|
|
2025-09-04 03:14:43 +08:00
|
|
|
|
case <-timeout:
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-09-21 14:56:37 +00:00
|
|
|
|
if _, exists := actions[f.Our.Player.GetInfo().UserID]; !exists {
|
2025-09-23 16:42:10 +00:00
|
|
|
|
f.Over(f.Opp.Player, info.BattleOverReason.PlayerOVerTime)
|
2025-09-04 03:14:43 +08:00
|
|
|
|
}
|
2025-09-21 14:56:37 +00:00
|
|
|
|
if _, exists := actions[f.Opp.Player.GetInfo().UserID]; !exists {
|
2025-09-14 03:36:26 +08:00
|
|
|
|
|
2025-10-22 21:30:05 +08:00
|
|
|
|
f.Over(f.Our.Player, info.BattleOverReason.PlayerOVerTime)
|
2025-09-04 03:14:43 +08:00
|
|
|
|
}
|
2025-09-14 19:59:58 +08:00
|
|
|
|
|
2025-09-04 03:14:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-04 23:57:22 +08:00
|
|
|
|
// 双方动作齐了,取出来结算
|
2025-09-08 23:17:42 +08:00
|
|
|
|
//todo 如果一方没有选择,实际上就是后端判断PP是否还有,前端是直接发的
|
2025-09-21 14:56:37 +00:00
|
|
|
|
p1Action := actions[f.Our.Player.GetInfo().UserID]
|
|
|
|
|
|
p2Action := actions[f.Opp.Player.GetInfo().UserID]
|
2025-09-05 22:40:36 +08:00
|
|
|
|
fmt.Println("开始结算回合")
|
2025-09-24 12:40:13 +08:00
|
|
|
|
// 统一赋值,减少重复代码
|
2025-09-14 03:36:26 +08:00
|
|
|
|
|
2025-09-28 08:13:42 +00:00
|
|
|
|
var BattleActionI [2]action.BattleActionI
|
2025-09-16 23:58:03 +08:00
|
|
|
|
BattleActionI[0], BattleActionI[1] = f.Compare(p1Action, p2Action)
|
2025-09-05 22:40:36 +08:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
switch faction := BattleActionI[0].(type) {
|
2025-10-21 00:41:59 +08:00
|
|
|
|
case *action.PlayerOfflineAction: // 单方掉线
|
2025-09-14 01:35:16 +08:00
|
|
|
|
f.Broadcast(func(ff *input.Input) {
|
2025-10-21 00:41:59 +08:00
|
|
|
|
ff.Player.SendFightEndInfo(faction.Reason) // 广播逃跑原因
|
2025-09-08 01:23:12 +08:00
|
|
|
|
})
|
2025-09-14 19:59:58 +08:00
|
|
|
|
f.closefight = true
|
2025-09-06 00:31:08 +08:00
|
|
|
|
|
2025-10-21 00:41:59 +08:00
|
|
|
|
case *action.EscapeAction: // 优先逃跑
|
2025-09-14 01:35:16 +08:00
|
|
|
|
f.Broadcast(func(ff *input.Input) {
|
2025-10-21 00:41:59 +08:00
|
|
|
|
ff.Player.SendFightEndInfo(faction.Reason) // 广播逃跑原因
|
2025-09-08 01:23:12 +08:00
|
|
|
|
})
|
2025-09-14 19:59:58 +08:00
|
|
|
|
f.closefight = true
|
|
|
|
|
|
|
2025-10-21 00:41:59 +08:00
|
|
|
|
case *action.ActiveSwitchAction: // 切换上场的, 切换方放弃出手
|
|
|
|
|
|
|
|
|
|
|
|
// 如果后手不是技能,替换成空技能(放弃出手)
|
2025-10-21 22:14:30 +08:00
|
|
|
|
if _, ok := BattleActionI[1].(*action.SelectSkillAction); !ok {
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
f.enterturn(nil, nil) //双方都不出手
|
2025-10-21 22:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
} else {
|
2025-10-26 20:56:03 +08:00
|
|
|
|
//后手方先手,先手方放弃出手
|
|
|
|
|
|
f.enterturn(BattleActionI[1].(*action.SelectSkillAction), nil)
|
2025-10-21 22:14:30 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
2025-09-11 02:44:21 +08:00
|
|
|
|
|
2025-10-21 00:41:59 +08:00
|
|
|
|
case *action.UseItemAction: // 使用道具
|
2025-09-11 02:44:21 +08:00
|
|
|
|
switch {
|
2025-10-21 00:41:59 +08:00
|
|
|
|
case faction.ItemID >= 30001 && faction.ItemID <= 300010: // 胶囊
|
2025-09-30 10:40:36 +00:00
|
|
|
|
tt, ok := f.Our.Player.(*player.Player)
|
2025-09-23 13:24:40 +08:00
|
|
|
|
mo, ism := f.Opp.Player.(*player.AI_player)
|
|
|
|
|
|
|
2025-10-21 00:41:59 +08:00
|
|
|
|
if ok && ism && mo.CanCapture {
|
2025-09-25 13:07:56 +08:00
|
|
|
|
ok, res := f.Our.Capture(f.Opp.CurrentPet, faction.ItemID, -1)
|
2025-10-21 00:41:59 +08:00
|
|
|
|
if ok {
|
2025-09-25 13:07:56 +08:00
|
|
|
|
fmt.Println(res)
|
2025-09-23 13:24:40 +08:00
|
|
|
|
tt.Service.PetAdd(*f.Opp.CurrentPet.Info)
|
|
|
|
|
|
tt.CatchPetInfo(info.CatchMonsterOutboundInfo{
|
|
|
|
|
|
CatchTime: uint32(f.Opp.CurrentPet.Info.CatchTime),
|
|
|
|
|
|
PetId: uint32(f.Opp.CurrentPet.ID),
|
|
|
|
|
|
})
|
|
|
|
|
|
tt.SendFightEndInfo(info.FightOverInfo{
|
|
|
|
|
|
WinnerId: f.ownerID,
|
|
|
|
|
|
})
|
|
|
|
|
|
f.closefight = true
|
|
|
|
|
|
} else {
|
2025-09-21 17:01:31 +00:00
|
|
|
|
tt.CatchPetInfo(info.CatchMonsterOutboundInfo{})
|
2025-09-11 02:44:21 +08:00
|
|
|
|
}
|
2025-10-21 00:41:59 +08:00
|
|
|
|
} else {
|
2025-09-23 13:24:40 +08:00
|
|
|
|
tt.CatchPetInfo(info.CatchMonsterOutboundInfo{})
|
|
|
|
|
|
}
|
2025-09-11 02:44:21 +08:00
|
|
|
|
fmt.Println("ItemID 在范围内")
|
|
|
|
|
|
case faction.ItemID == 300001:
|
|
|
|
|
|
fmt.Println("ItemID 是 300001")
|
|
|
|
|
|
default:
|
|
|
|
|
|
fmt.Println("ItemID 不在指定范围内")
|
|
|
|
|
|
}
|
2025-10-21 00:41:59 +08:00
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
if _, ok := BattleActionI[1].(*action.SelectSkillAction); !ok {
|
|
|
|
|
|
f.enterturn(nil, nil)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
f.enterturn(BattleActionI[1].(*action.SelectSkillAction), nil)
|
2025-10-21 00:41:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
default: // 双方都是技能或者默认情况
|
2025-09-06 00:31:08 +08:00
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
f.enterturn(BattleActionI[0].(*action.SelectSkillAction), BattleActionI[1].(*action.SelectSkillAction))
|
2025-09-06 00:31:08 +08:00
|
|
|
|
}
|
2025-09-07 00:23:28 +08:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-09-06 01:47:08 +08:00
|
|
|
|
|
2025-09-08 02:51:21 +00:00
|
|
|
|
// 处理技能攻击逻辑
|
2025-09-28 08:13:42 +00:00
|
|
|
|
func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.SelectSkillAction) {
|
|
|
|
|
|
|
2025-09-30 18:32:15 +08:00
|
|
|
|
attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中
|
2025-09-28 08:13:42 +00:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
t.Skill_Hit_Pre(input.Ctx{ //调基础命中
|
2025-10-26 20:56:03 +08:00
|
|
|
|
Input: defender,
|
|
|
|
|
|
SelectSkillAction: a,
|
2025-09-28 08:13:42 +00:00
|
|
|
|
}) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率
|
2025-09-08 02:51:21 +00:00
|
|
|
|
|
2025-09-28 01:58:42 +08:00
|
|
|
|
return true
|
|
|
|
|
|
})
|
2025-10-26 20:56:03 +08:00
|
|
|
|
a.AttackTimeC(attacker.GetProp(5, true)) //计算命中
|
|
|
|
|
|
defender.Exec(func(t input.Effect) bool { //计算闪避 ,然后修改对方命中),同时相当于计算属性无效这种
|
2025-10-03 20:20:17 +08:00
|
|
|
|
t.Skill_Hit_to(input.Ctx{ //计算命中后,我方强制改命中效果
|
2025-10-26 20:56:03 +08:00
|
|
|
|
Input: attacker,
|
|
|
|
|
|
SelectSkillAction: a,
|
2025-09-28 08:13:42 +00:00
|
|
|
|
})
|
2025-09-14 16:56:31 +08:00
|
|
|
|
|
2025-09-24 18:53:54 +00:00
|
|
|
|
return true
|
2025-09-12 00:27:49 +08:00
|
|
|
|
})
|
2025-09-14 03:36:26 +08:00
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
attacker.AttackValue.AttackTime = a.AttackTime //是否命中赋值
|
|
|
|
|
|
attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中
|
2025-09-26 21:15:58 +00:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
t.Skill_Hit(input.Ctx{ //计算变威力
|
2025-10-26 20:56:03 +08:00
|
|
|
|
Input: attacker,
|
|
|
|
|
|
SelectSkillAction: a,
|
2025-10-05 00:29:22 +08:00
|
|
|
|
}) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率
|
2025-09-26 21:15:58 +00:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
return true
|
|
|
|
|
|
})
|
|
|
|
|
|
//技能命中+效果失效 这里就是修改效果命中为false
|
|
|
|
|
|
//技能miss+效果生效 这里属于强制改命中效果,但是正常来说,技能miss掉后效果也应该失效
|
|
|
|
|
|
//技能失效+效果失效
|
2025-10-22 00:25:38 +08:00
|
|
|
|
// 记录技能信息
|
2025-10-26 20:56:03 +08:00
|
|
|
|
attacker.AttackValue.SkillID = uint32(a.ID) //获取技能ID
|
|
|
|
|
|
if attacker.AttackValue.AttackTime > 0 { //如果命中
|
|
|
|
|
|
attacker.UseSkill(defender, a) //暴击计算
|
|
|
|
|
|
attacker.AttackValue.IsCritical = a.Crit
|
2025-10-05 00:29:22 +08:00
|
|
|
|
attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中
|
2025-09-26 02:09:33 +00:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
t.Calculate_Pre(input.Ctx{ //计算视为效果
|
2025-10-26 20:56:03 +08:00
|
|
|
|
Input: defender,
|
|
|
|
|
|
SelectSkillAction: a,
|
2025-10-05 00:29:22 +08:00
|
|
|
|
}) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率
|
2025-09-26 02:09:33 +00:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
return true
|
|
|
|
|
|
})
|
2025-10-26 20:56:03 +08:00
|
|
|
|
attacker.DamageZone.Damage = attacker.CalculatePower(defender, a.SkillEntity)
|
2025-09-26 02:09:33 +00:00
|
|
|
|
|
|
|
|
|
|
if attacker.AttackValue.IsCritical == 1 {
|
|
|
|
|
|
|
2025-09-29 02:40:35 +08:00
|
|
|
|
//暴击翻倍
|
|
|
|
|
|
attacker.DamageZone.Damage = attacker.DamageZone.Damage.Mul(decimal.NewFromInt(2))
|
2025-09-26 02:09:33 +00:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
for _, e := range attacker.EffectCache {
|
|
|
|
|
|
//这里实现应该参考本地技能是否命中,然后
|
2025-10-26 20:56:03 +08:00
|
|
|
|
e.Hit(a.AttackTime != 0) //我方效果命中
|
2025-10-05 00:29:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
for _, t := range defender.EffectCache {
|
|
|
|
|
|
if t.GetInput() == attacker { //如果取反,说明是给对方添加的回合效果
|
2025-10-26 20:56:03 +08:00
|
|
|
|
t.Hit(a.AttackTime != 0)
|
2025-10-05 00:29:22 +08:00
|
|
|
|
}
|
2025-09-26 02:09:33 +00:00
|
|
|
|
}
|
2025-09-08 01:23:12 +08:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
// 扣减防御方血量
|
2025-09-26 21:15:58 +00:00
|
|
|
|
attacker.Exec(func(t input.Effect) bool {
|
|
|
|
|
|
|
2025-09-29 02:40:35 +08:00
|
|
|
|
t.OnSkill(input.Ctx{
|
2025-10-26 20:56:03 +08:00
|
|
|
|
Input: defender,
|
|
|
|
|
|
SelectSkillAction: a,
|
2025-09-29 02:40:35 +08:00
|
|
|
|
}) //调用伤害计算
|
2025-09-26 21:15:58 +00:00
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
2025-09-29 02:40:35 +08:00
|
|
|
|
|
|
|
|
|
|
defender.Damage(input.Ctx{
|
|
|
|
|
|
|
|
|
|
|
|
Input: attacker,
|
|
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
SelectSkillAction: a,
|
2025-09-29 02:40:35 +08:00
|
|
|
|
DamageZone: &info.DamageZone{
|
|
|
|
|
|
Type: info.DamageType.Red,
|
|
|
|
|
|
Damage: attacker.DamageZone.Damage,
|
|
|
|
|
|
},
|
2025-09-26 13:33:55 +08:00
|
|
|
|
})
|
2025-09-28 08:13:42 +00:00
|
|
|
|
//这里其实是受到致死伤害
|
|
|
|
|
|
//然后先触发死亡效果,消除所有buff
|
|
|
|
|
|
//然后触发回神效果
|
2025-09-08 02:51:21 +00:00
|
|
|
|
}
|
2025-10-10 00:40:32 +08:00
|
|
|
|
func IsNil(x interface{}) bool {
|
|
|
|
|
|
if x == nil {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
rv := reflect.ValueOf(x)
|
|
|
|
|
|
return rv.Kind() == reflect.Ptr && rv.IsNil()
|
|
|
|
|
|
}
|
2025-10-26 20:56:03 +08:00
|
|
|
|
func copyskill(t *action.SelectSkillAction) *action.SelectSkillAction {
|
|
|
|
|
|
|
|
|
|
|
|
oldskill, _ := deepcopy.Anything(t) //备份技能
|
|
|
|
|
|
|
|
|
|
|
|
return oldskill.(*action.SelectSkillAction)
|
|
|
|
|
|
}
|
2025-09-10 22:59:10 +08:00
|
|
|
|
|
2025-09-14 04:48:38 +08:00
|
|
|
|
//回合有先手方和后手方,同时有攻击方和被攻击方
|
|
|
|
|
|
|
2025-09-30 18:32:15 +08:00
|
|
|
|
func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
|
2025-09-14 03:36:26 +08:00
|
|
|
|
|
2025-09-23 13:24:40 +08:00
|
|
|
|
if f.closefight { //战斗结束
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-09-30 18:32:15 +08:00
|
|
|
|
// 伤害值
|
|
|
|
|
|
|
|
|
|
|
|
// 根据攻击方归属设置当前战斗的主/次攻击方属性
|
|
|
|
|
|
|
|
|
|
|
|
if fattack.GetPlayerID() == f.ownerID {
|
|
|
|
|
|
f.First, f.Second = f.Our, f.Opp // 攻击方为我方时,主攻击方是我方
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
f.First, f.Second = f.Opp, f.Our // 攻击方为对方时,主攻击方是对方
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-10-21 22:14:30 +08:00
|
|
|
|
f.First.InitAttackValue()
|
|
|
|
|
|
f.Second.InitAttackValue()
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2025-10-10 00:44:45 +08:00
|
|
|
|
switch {
|
2025-10-26 20:56:03 +08:00
|
|
|
|
case sattack != nil:
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2025-10-10 00:44:45 +08:00
|
|
|
|
f.Second.Parseskill(f.Second, sattack) //解析到临时数据
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2025-10-10 00:44:45 +08:00
|
|
|
|
f.Second.Exec(func(t input.Effect) bool { //回合开始前
|
2025-10-10 00:40:32 +08:00
|
|
|
|
|
2025-10-10 00:44:45 +08:00
|
|
|
|
//结算状态
|
|
|
|
|
|
t.Compare_Pre(fattack, sattack) //先结算技能的优先级
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
2025-10-10 00:40:32 +08:00
|
|
|
|
switch {
|
2025-10-26 20:56:03 +08:00
|
|
|
|
case fattack != nil: //房主也放弃出手
|
2025-10-10 00:44:45 +08:00
|
|
|
|
//是否miss都应该施加解析effect
|
|
|
|
|
|
f.First.Parseskill(f.Second, fattack) //解析到临时数据
|
|
|
|
|
|
|
|
|
|
|
|
f.First.Exec(func(t input.Effect) bool { //回合开始前
|
|
|
|
|
|
|
|
|
|
|
|
//结算状态
|
|
|
|
|
|
t.Compare_Pre(fattack, sattack) //先结算技能的优先级
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
2025-10-10 00:40:32 +08:00
|
|
|
|
switch {
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
case fattack.SkillEntity.Priority < sattack.SkillEntity.Priority:
|
2025-10-10 00:40:32 +08:00
|
|
|
|
|
|
|
|
|
|
fattack, sattack = sattack, fattack //互换先手权
|
|
|
|
|
|
f.First, f.Second = f.Second, f.First
|
2025-10-26 20:56:03 +08:00
|
|
|
|
case fattack.SkillEntity.Priority == sattack.SkillEntity.Priority:
|
2025-10-10 00:40:32 +08:00
|
|
|
|
|
|
|
|
|
|
if f.Second.GetProp(4, false) > f.First.GetProp(4, false) {
|
|
|
|
|
|
fattack, sattack = sattack, fattack //互换先手权
|
|
|
|
|
|
f.First, f.Second = f.Second, f.First
|
|
|
|
|
|
}
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2025-10-10 00:40:32 +08:00
|
|
|
|
}
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2025-10-10 00:40:32 +08:00
|
|
|
|
default: //房主放弃出手
|
2025-09-30 18:32:15 +08:00
|
|
|
|
fattack, sattack = sattack, fattack //互换先手权
|
2025-10-10 00:40:32 +08:00
|
|
|
|
f.First, f.Second = f.Second, f.First
|
2025-09-30 18:32:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-10-10 00:40:32 +08:00
|
|
|
|
|
2025-09-30 10:40:36 +00:00
|
|
|
|
var attacker, defender *input.Input
|
2025-10-15 14:24:46 +00:00
|
|
|
|
f.First.Exec(func(t input.Effect) bool { //回合开始前
|
|
|
|
|
|
|
|
|
|
|
|
//结算状态
|
|
|
|
|
|
t.Turn_Start(input.Ctx{Input: f.First})
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
|
|
|
|
|
f.Second.Exec(func(t input.Effect) bool { //回合开始前
|
|
|
|
|
|
|
|
|
|
|
|
//结算状态
|
|
|
|
|
|
t.Turn_Start(input.Ctx{Input: f.Second})
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
2025-09-14 03:36:26 +08:00
|
|
|
|
//开始回合操作
|
2025-09-10 01:35:08 +08:00
|
|
|
|
for i := 0; i < 2; i++ {
|
2025-10-26 20:56:03 +08:00
|
|
|
|
var oldskill *action.SelectSkillAction //原始技能
|
|
|
|
|
|
var currentskill *action.SelectSkillAction //当前技能
|
|
|
|
|
|
if i == 0 { //
|
2025-09-30 10:40:36 +00:00
|
|
|
|
attacker, defender = f.First, f.Second
|
2025-10-26 20:56:03 +08:00
|
|
|
|
oldskill = copyskill(fattack)
|
|
|
|
|
|
currentskill = fattack
|
2025-09-30 10:40:36 +00:00
|
|
|
|
|
|
|
|
|
|
} else {
|
2025-09-10 01:35:08 +08:00
|
|
|
|
attacker, defender = f.Second, f.First
|
2025-10-26 20:56:03 +08:00
|
|
|
|
oldskill = copyskill(sattack)
|
|
|
|
|
|
currentskill = sattack
|
2025-09-10 01:35:08 +08:00
|
|
|
|
}
|
2025-09-14 04:48:38 +08:00
|
|
|
|
|
2025-09-29 02:40:35 +08:00
|
|
|
|
canuseskill := true
|
2025-09-30 10:40:36 +00:00
|
|
|
|
// 实际上攻击方 还有系统选择放弃出手的
|
2025-10-26 20:56:03 +08:00
|
|
|
|
if IsNil(currentskill) || attacker.CurrentPet.Info.Hp <= 0 {
|
2025-10-10 00:40:32 +08:00
|
|
|
|
|
|
|
|
|
|
// attacker.AttackValue.SkillID = 0
|
2025-09-25 13:07:56 +08:00
|
|
|
|
canuseskill = false
|
2025-09-07 05:58:47 +08:00
|
|
|
|
|
2025-10-10 00:40:32 +08:00
|
|
|
|
} else {
|
2025-10-26 20:56:03 +08:00
|
|
|
|
if !action.CanUse(currentskill) {
|
2025-10-10 00:40:32 +08:00
|
|
|
|
// attacker.AttackValue.SkillID = 0
|
|
|
|
|
|
canuseskill = false
|
|
|
|
|
|
}
|
2025-09-25 13:07:56 +08:00
|
|
|
|
}
|
2025-09-28 01:58:42 +08:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
canuseskillok := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能
|
|
|
|
|
|
//结算状态
|
|
|
|
|
|
//然后这里还可以处理自爆类
|
|
|
|
|
|
return t.Skill_Hit_Pre(input.Ctx{
|
2025-10-26 20:56:03 +08:00
|
|
|
|
Input: defender,
|
|
|
|
|
|
SelectSkillAction: currentskill,
|
2025-10-05 00:29:22 +08:00
|
|
|
|
}) //返回本身结算,如果false,说明不能使用技能了
|
2025-09-28 01:58:42 +08:00
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
})
|
|
|
|
|
|
if canuseskill && canuseskillok { //可以使用技能
|
2025-10-26 20:56:03 +08:00
|
|
|
|
|
|
|
|
|
|
f.processSkillAttack(attacker, defender, currentskill)
|
|
|
|
|
|
currentskill = oldskill
|
2025-10-27 01:11:31 +08:00
|
|
|
|
_, skill, ok := utils.FindWithIndex(attacker.CurrentPet.Info.SkillList, func(item model.SkillInfo) bool {
|
|
|
|
|
|
return item.ID == currentskill.Info.ID
|
|
|
|
|
|
})
|
|
|
|
|
|
if ok {
|
|
|
|
|
|
|
|
|
|
|
|
skill.PP--
|
|
|
|
|
|
}
|
2025-09-10 02:11:16 +00:00
|
|
|
|
|
2025-09-10 02:16:47 +00:00
|
|
|
|
}
|
2025-09-29 02:40:35 +08:00
|
|
|
|
|
|
|
|
|
|
//技能使用后
|
|
|
|
|
|
defender.Exec(func(t input.Effect) bool {
|
|
|
|
|
|
t.Skill_Use(input.Ctx{Input: attacker})
|
|
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
//技能使用后
|
|
|
|
|
|
attacker.Exec(func(t input.Effect) bool { //技能使用后的我方效果
|
|
|
|
|
|
t.Skill_Useed(input.Ctx{Input: defender, SelectSkillAction: currentskill})
|
|
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2025-09-10 01:35:08 +08:00
|
|
|
|
fmt.Println(i,
|
2025-10-10 00:40:32 +08:00
|
|
|
|
// "玩家技能:", oldskill.(*info.SkillEntity).ID,
|
2025-09-29 02:40:35 +08:00
|
|
|
|
"玩家技能伤害:", attacker.DamageZone.Damage,
|
2025-09-10 01:35:08 +08:00
|
|
|
|
"自身剩余血量:", attacker.CurrentPet.Info.Hp,
|
|
|
|
|
|
"对手剩余血量:", defender.CurrentPet.Info.Hp,
|
|
|
|
|
|
)
|
|
|
|
|
|
if defender.CurrentPet.Info.Hp == 0 {
|
2025-10-10 00:40:32 +08:00
|
|
|
|
// defender.AttackValue.SkillID = 0
|
|
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
defender.CanChange = true //被打死就可以切精灵了
|
|
|
|
|
|
if f.IsWin(attacker, defender.CurrentPet.Info.CatchTime) { //然后检查是否战斗结束
|
2025-09-10 01:35:08 +08:00
|
|
|
|
var WinnerId uint32
|
|
|
|
|
|
if i == 0 {
|
2025-09-21 14:56:37 +00:00
|
|
|
|
WinnerId = f.First.Player.GetInfo().UserID
|
2025-09-10 01:35:08 +08:00
|
|
|
|
} else {
|
2025-09-21 14:56:37 +00:00
|
|
|
|
WinnerId = f.Second.Player.GetInfo().UserID
|
2025-09-10 01:35:08 +08:00
|
|
|
|
}
|
2025-09-14 01:35:16 +08:00
|
|
|
|
defer f.Broadcast(func(ff *input.Input) {
|
2025-09-10 22:59:10 +08:00
|
|
|
|
//todo 将血量和技能pp传回enterturn
|
|
|
|
|
|
|
2025-09-10 00:41:09 +08:00
|
|
|
|
ff.Player.SendFightEndInfo(info.FightOverInfo{
|
2025-09-10 01:35:08 +08:00
|
|
|
|
WinnerId: WinnerId,
|
2025-09-10 00:41:09 +08:00
|
|
|
|
})
|
|
|
|
|
|
})
|
2025-10-14 01:26:59 +08:00
|
|
|
|
f.closefight = true
|
2025-09-07 05:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
2025-09-07 00:23:28 +08:00
|
|
|
|
}
|
2025-09-06 01:47:08 +08:00
|
|
|
|
|
2025-09-04 03:14:43 +08:00
|
|
|
|
}
|
2025-09-23 19:11:03 +00:00
|
|
|
|
|
2025-09-24 16:36:32 +00:00
|
|
|
|
f.First.Exec(func(t input.Effect) bool { //这个是能否使用技能
|
2025-09-23 19:11:03 +00:00
|
|
|
|
//结算状态
|
2025-09-29 02:40:35 +08:00
|
|
|
|
t.Turn_End(input.Ctx{
|
|
|
|
|
|
Input: f.Second,
|
|
|
|
|
|
}) //返回本身结算,如果false,说明不能使用技能了
|
2025-09-23 19:11:03 +00:00
|
|
|
|
return true
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2025-09-24 16:36:32 +00:00
|
|
|
|
f.Second.Exec(func(t input.Effect) bool { //这个是能否使用技能
|
2025-09-23 22:20:52 +00:00
|
|
|
|
//结算状态
|
2025-09-29 02:40:35 +08:00
|
|
|
|
t.Turn_End(input.Ctx{
|
|
|
|
|
|
Input: f.First,
|
|
|
|
|
|
})
|
2025-09-23 22:20:52 +00:00
|
|
|
|
return true
|
|
|
|
|
|
})
|
2025-09-26 02:09:33 +00:00
|
|
|
|
f.First.AttackValue.RemainHp = int32(f.First.CurrentPet.Info.Hp)
|
2025-10-26 20:56:03 +08:00
|
|
|
|
f.First.AttackValue.SkillList = f.First.CurrentPet.Info.SkillList
|
2025-10-27 01:11:31 +08:00
|
|
|
|
|
|
|
|
|
|
f.Second.AttackValue.SkillList = f.Second.CurrentPet.Info.SkillList
|
2025-09-26 02:09:33 +00:00
|
|
|
|
f.Second.AttackValue.RemainHp = int32(f.Second.CurrentPet.Info.Hp)
|
2025-09-14 19:59:58 +08:00
|
|
|
|
ret := info.AttackValueS{
|
|
|
|
|
|
FAttack: *f.First.AttackValue,
|
|
|
|
|
|
SAttack: *f.Second.AttackValue,
|
|
|
|
|
|
}
|
2025-09-17 00:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
for i := 0; i < 20; i++ { //堆叠状态剩余回合
|
2025-09-19 00:29:55 +08:00
|
|
|
|
|
2025-09-25 13:07:56 +08:00
|
|
|
|
t := f.First.GetEffect(input.EffectType.Status, i)
|
2025-09-26 02:09:33 +00:00
|
|
|
|
if t.ID != 0 {
|
|
|
|
|
|
ret.FAttack.Status[i] = int8(t.Effect.Duration())
|
2025-09-25 13:07:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
t = f.Second.GetEffect(input.EffectType.Status, i)
|
2025-09-26 02:09:33 +00:00
|
|
|
|
if t.ID != 0 {
|
2025-10-22 00:25:38 +08:00
|
|
|
|
ret.SAttack.Status[i] = int8(t.Effect.Duration())
|
2025-09-25 13:07:56 +08:00
|
|
|
|
}
|
2025-09-19 00:29:55 +08:00
|
|
|
|
|
2025-09-17 00:50:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
f.Broadcast(func(ff *input.Input) {
|
2025-09-19 06:58:42 +00:00
|
|
|
|
for _, v := range f.Switch {
|
2025-10-21 22:14:30 +08:00
|
|
|
|
|
2025-09-21 14:56:37 +00:00
|
|
|
|
if ff.Player.GetInfo().UserID != v.PlayerID {
|
2025-09-19 06:58:42 +00:00
|
|
|
|
ff.Player.SendChangePet(v.Reason)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-10-21 22:14:30 +08:00
|
|
|
|
|
2025-09-08 01:23:12 +08:00
|
|
|
|
ff.Player.SendAttackValue(ret)
|
|
|
|
|
|
})
|
2025-10-21 22:14:30 +08:00
|
|
|
|
f.Switch = []*action.ActiveSwitchAction{}
|
2025-09-04 03:14:43 +08:00
|
|
|
|
}
|