feat(player): 添加 UseCoins 方法统一处理玩家金币消耗逻辑

重构购买物品和变更外观功能,使用 UseCoins 方法替代手动操作 Coins 字段,
确保金币扣除的安全性和一致性。同时修复可能因并发导致的金币超扣问题。

此外,调整部分战斗系统接口参数传递方式,将 DamageZone 指
This commit is contained in:
2025-11-13 21:36:18 +08:00
parent 6e01848b04
commit 5e3d558d30
24 changed files with 306 additions and 114 deletions

View File

@@ -46,20 +46,16 @@ func (h Controller) PlayerExp(data *item.ExpTotalRemainInboundInfo, c *player.Pl
func (h Controller) BuyItem(data *item.BuyInboundInfo, c *player.Player) (result *item.BuyOutboundInfo, err errorcode.ErrorCode) { func (h Controller) BuyItem(data *item.BuyInboundInfo, c *player.Player) (result *item.BuyOutboundInfo, err errorcode.ErrorCode) {
tt, ok := xmlres.ItemsMAP[int(data.ItemId)] tt, ok := xmlres.ItemsMAP[int(data.ItemId)]
if ok && tt.Price != 0 { if ok && tt.Price != 0 && c.UseCoins(data.Count*uint32(tt.Price)) {
if (data.Count * uint32(tt.Price)) <= c.Info.Coins {
c.Info.Coins -= data.Count * uint32(tt.Price)
r := c.ItemAdd(model.SingleItemInfo{ItemId: data.ItemId, ItemCnt: data.Count})
if len(r) != 0 {
return &item.BuyOutboundInfo{
ItemId: data.ItemId,
Level: 1,
Count: data.Count,
Coins: c.Info.Coins,
}, 0
}
r := c.ItemAdd(model.SingleItemInfo{ItemId: data.ItemId, ItemCnt: data.Count})
if len(r) != 0 {
return &item.BuyOutboundInfo{
ItemId: data.ItemId,
Level: 1,
Count: data.Count,
Coins: c.Info.Coins,
}, 0
} }
} }

View File

@@ -69,8 +69,12 @@ func (h Controller) Chat(data *user.ChatInboundInfo, c *player.Player) (result *
return nil, -1 return nil, -1
} }
func (h Controller) ChangePlayerColor(data *user.ChangeColorInboundInfo, c *player.Player) (result *user.ChangeColorOutboundInfo, err errorcode.ErrorCode) { func (h Controller) ChangePlayerColor(data *user.ChangeColorInboundInfo, c *player.Player) (result *user.ChangeColorOutboundInfo, err errorcode.ErrorCode) {
c.Info.Coins -= 200
if !c.UseCoins(200) { //如果花不了200,直接返回
return
}
c.Info.Color = data.Color c.Info.Color = data.Color
c.Info.Texture = 0
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) { defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) {
data.Head.Result = 0 data.Head.Result = 0
@@ -86,7 +90,9 @@ func (h Controller) ChangePlayerColor(data *user.ChangeColorInboundInfo, c *play
return nil, -1 return nil, -1
} }
func (h Controller) ChangePlayerDoodle(data *user.ChangeDoodleInboundInfo, c *player.Player) (result *user.ChangeDoodleOutboundInfo, err errorcode.ErrorCode) { func (h Controller) ChangePlayerDoodle(data *user.ChangeDoodleInboundInfo, c *player.Player) (result *user.ChangeDoodleOutboundInfo, err errorcode.ErrorCode) {
c.Info.Coins -= 200 if !c.UseCoins(200) { //如果花不了200,直接返回
return
}
c.Info.Texture = data.Id c.Info.Texture = data.Id
c.Info.Color = data.Color c.Info.Color = data.Color
defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) { defer space.GetSpace(c.Info.MapID).User.IterCb(func(playerID uint32, v common.PlayerI) {

View File

@@ -0,0 +1,50 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
)
// -----------------------------------------------------------
// 通用状态效果(例如 麻痹 / 中毒 / 疲惫 / 混乱 等)
// -----------------------------------------------------------
type Effect1605 struct {
node.EffectNode
Status info.EnumBattleStatus // 要施加的状态类型
}
func init() {
input.InitEffect(input.EffectType.Skill, 1605, &Effect1605{})
}
// -----------------------------------------------------------
// 技能触发时调用
// -----------------------------------------------------------
func (e *Effect1605) OnSkill() bool {
if !e.Hit() {
return true
}
// n% 触发概率(默认 SideEffectArgs[0]
chance := e.SideEffectArgs[0]
success, _, _ := e.Input.Player.Roll(chance, 100)
if !success {
return true
}
duration := int(e.Input.FightC.GetRand().Int31n(2)) // 默认随机 2~3 回合
duration++
// 获取状态效果
eff := input.Geteffect(input.EffectType.Status, int(e.SideEffectArgs[1]))
if eff == nil {
return true
}
eff.Duration(duration)
eff.SetArgs(e.Ctx().Our) //输入参数是对方
e.Ctx().Opp.AddEffect(eff)
return true
}

View File

@@ -23,12 +23,12 @@ type Effect31 struct {
node.EffectNode node.EffectNode
} }
func (e *Effect31) Damage_Mul() bool { func (e *Effect31) Damage_Mul(t *info.DamageZone) bool {
if !e.Hit() { if !e.Hit() {
return true return true
} }
if e.Ctx().DamageZone.Type == info.DamageType.Red { if t.Type == info.DamageType.Red {
n := int(e.Input.FightC.GetRand().Int31n(int32(e.SideEffectArgs[1]-e.SideEffectArgs[0]+1))) + e.SideEffectArgs[0] n := int(e.Input.FightC.GetRand().Int31n(int32(e.SideEffectArgs[1]-e.SideEffectArgs[0]+1))) + e.SideEffectArgs[0]
e.Ctx().Our.DamageZone.Damage = e.Ctx().Our.DamageZone.Damage.Mul(decimal.NewFromInt(int64(n))) e.Ctx().Our.DamageZone.Damage = e.Ctx().Our.DamageZone.Damage.Mul(decimal.NewFromInt(int64(n)))

View File

@@ -0,0 +1,37 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
)
/**
* 使用后n回合攻击击中对象要害概率增加1/16
*/
func init() {
input.InitEffect(input.EffectType.Skill, 32, &Effect32{
EffectNode: node.EffectNode{},
})
}
type Effect32 struct {
node.EffectNode
}
func (e *Effect32) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool {
if !e.Hit() {
return true
}
e.Ctx().SkillEntity.Crit += 1
return true
}
func (e *Effect32) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0])
}

View File

@@ -0,0 +1,44 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
)
/**
* 下n回合自身攻击技能必定打出致命一击
*/
func init() {
input.InitEffect(input.EffectType.Skill, 58, &Effect58{
EffectNode: node.EffectNode{},
})
}
type Effect58 struct {
node.EffectNode
can bool
}
func (e *Effect58) OnSkill() bool {
if !e.Hit() {
return true
}
e.can = true
return true
}
func (e *Effect58) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool {
if !e.Hit() {
return true
}
if !e.can {
return true
}
e.Ctx().SkillEntity.Crit = 16
return true
}

View File

@@ -1,6 +1,7 @@
package effect package effect
import ( import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info" "blazing/logic/service/fight/info"
"blazing/logic/service/fight/input" "blazing/logic/service/fight/input"
"blazing/logic/service/fight/node" "blazing/logic/service/fight/node"
@@ -24,26 +25,26 @@ type Effect7 struct {
node.EffectNode node.EffectNode
} }
func (e *Effect7) Skill_Hit_Pre() bool { func (e *Effect7) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool {
if e.Ctx().Opp.CurrentPet.Info.Hp <= e.Ctx().Our.CurrentPet.Info.Hp { if e.Ctx().Opp.CurrentPet.Info.Hp <= e.Ctx().Our.CurrentPet.Info.Hp {
e.Ctx().SkillEntity.Accuracy = 0 e.Ctx().SkillEntity.Accuracy = 0
} }
return true return true
} }
func (e *Effect7) Damage_Floor() bool { func (e *Effect7) Damage_Floor(t *info.DamageZone) bool {
if !e.Hit() { if !e.Hit() {
return true return true
} }
fmt.Println("Effect7_old", e.Ctx().DamageZone.Damage.IntPart()) fmt.Println("Effect7_old", t.Damage.IntPart())
if e.Ctx().DamageZone.Type == info.DamageType.Red { if t.Type == info.DamageType.Red {
if e.Ctx().Our.CurrentPet.Info.Hp <= e.Ctx().Opp.CurrentPet.Info.Hp { if e.Ctx().Our.CurrentPet.Info.Hp <= e.Ctx().Opp.CurrentPet.Info.Hp {
e.Ctx().DamageZone.Damage = decimal.NewFromInt(int64(e.Ctx().Opp.CurrentPet.Info.Hp - e.Ctx().Our.CurrentPet.Info.Hp)) t.Damage = decimal.NewFromInt(int64(e.Ctx().Opp.CurrentPet.Info.Hp - e.Ctx().Our.CurrentPet.Info.Hp))
} }
} }
fmt.Println("Effect7_new", e.Ctx().DamageZone.Damage.IntPart()) fmt.Println("Effect7_new", t.Damage.IntPart())
return true return true
} }

View File

@@ -0,0 +1,41 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"fmt"
"github.com/shopspring/decimal"
)
// ---- Effect776 ----
type Effect776 struct {
node.EffectNode
StatusID int
}
func (e *Effect776) Damage_Mul(t *info.DamageZone) bool {
if !e.Hit() {
return true
}
fmt.Println("Effect776_o", t.Damage)
if t.Type == info.DamageType.Red {
t.Damage = t.Damage.Mul(decimal.NewFromInt(2))
}
fmt.Println("Effect776_n", t.Damage)
return true
}
func (e *Effect776) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0])
}
// ---- 注册所有效果 ----
func init() {
input.InitEffect(input.EffectType.Skill, 776, &Effect776{})
}

View File

@@ -14,9 +14,7 @@ import (
*/ */
func init() { func init() {
input.InitEffect(input.EffectType.Skill, 8, &Effect8{ input.InitEffect(input.EffectType.Skill, 8, &Effect8{})
EffectNode: node.EffectNode{},
})
} }
@@ -25,9 +23,9 @@ type Effect8 struct {
} }
// 伤害落实前触发,限制最大伤害 // 伤害落实前触发,限制最大伤害
func (e *Effect8) Damage_Floor() bool { func (e *Effect8) Damage_Floor(t *info.DamageZone) bool {
if e.Ctx().DamageZone.Type == info.DamageType.Red { if t.Type == info.DamageType.Red {
e.Ctx().DamageZone.Damage = decimal.NewFromInt(utils.Min(e.Ctx().DamageZone.Damage.IntPart(), t.Damage = decimal.NewFromInt(utils.Min(t.Damage.IntPart(),
int64(e.Ctx().Opp.CurrentPet.Info.Hp)-1)) int64(e.Ctx().Opp.CurrentPet.Info.Hp)-1))
} }

View File

@@ -1,6 +1,7 @@
package effect package effect
import ( import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info" "blazing/logic/service/fight/info"
"blazing/logic/service/fight/input" "blazing/logic/service/fight/input"
"blazing/logic/service/fight/node" "blazing/logic/service/fight/node"
@@ -11,6 +12,7 @@ import (
type BaseSataus struct { type BaseSataus struct {
node.EffectNode node.EffectNode
Status info.EnumBattleStatus
} }
// /重写切换事件 // /重写切换事件
@@ -27,33 +29,26 @@ func (e *BaseSataus) Switch(in *input.Input, outpet, inpet *info.BattlePetEntity
return true return true
} }
// 施加一个基类effect
type EffectStatus struct {
BaseSataus
Status info.EnumBattleStatus
}
type StatusNotSkill struct { type StatusNotSkill struct {
EffectStatus BaseSataus
} }
// 不能出手 // 不能出手
func (e *StatusNotSkill) Skill_Hit_Pre() bool { func (e *StatusNotSkill) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool {
return false return false
} }
type StatusSleep struct { //睡眠不能出手 ,这个挂载到对面来实现对方攻击后解除睡眠效果 type StatusSleep struct { //睡眠不能出手 ,这个挂载到对面来实现对方攻击后解除睡眠效果
BaseSataus
StatusNotSkill StatusNotSkill
can bool can bool
} }
func (e *StatusSleep) Skill_Hit_Pre() bool { func (e *StatusSleep) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool {
e.StatusNotSkill.Skill_Hit_Pre()
e.can = true e.can = true
return false return e.StatusNotSkill.Skill_Hit_Pre(a, b)
} }
func (e *StatusSleep) Skill_Use_ex() bool { func (e *StatusSleep) Skill_Use_ex() bool {
@@ -71,12 +66,12 @@ func (e *StatusSleep) Skill_Use_ex() bool {
// 扣血类 // 扣血类
type DrainHP struct { type DrainHP struct {
EffectStatus BaseSataus
damage decimal.Decimal damage decimal.Decimal
} }
func (e *DrainHP) Skill_Hit_Pre() bool { func (e *DrainHP) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool {
e.damage = decimal.NewFromUint64(uint64(e.Ctx().Our.CurrentPet.Info.MaxHp)). e.damage = decimal.NewFromUint64(uint64(e.Ctx().Our.CurrentPet.Info.MaxHp)).
Div(decimal.NewFromInt(8)) Div(decimal.NewFromInt(8))
@@ -94,12 +89,12 @@ type DrainedHP struct {
DrainHP DrainHP
} }
func (e *DrainedHP) Skill_Hit_Pre() bool { func (e *DrainedHP) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool {
if gconv.Int(e.Input.CurrentPet.Type) == 1 { if gconv.Int(e.Input.CurrentPet.Type) == 1 {
return true return true
} }
e.DrainHP.Skill_Hit_Pre() //先调用父类扣血 e.DrainHP.Skill_Hit_Pre(a, b) //先调用父类扣血
//TODO 寄生种子 给对面回血待实现回血buff //TODO 寄生种子 给对面回血待实现回血buff
//这个回血不属于任何类型,所以不会被阻止回血 //这个回血不属于任何类型,所以不会被阻止回血

View File

@@ -123,7 +123,23 @@ func (f *FightC) copypet(t *info.BattlePetEntity) *info.BattlePetEntity {
//回合有先手方和后手方,同时有攻击方和被攻击方 //回合有先手方和后手方,同时有攻击方和被攻击方
func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
//双方首发精灵登场时,依挑战方机制:房主方先判定,挑战方后判定
//双方非首发精灵登场时,根据切换先后判定(看手速)
// 神罗、圣华登场时魂免“登场时xx”等效果
//阿枫的效果也在这里判断
f.Our.Exec(func(t input.Effect) bool { //回合开始前
//结算状态
t.Turn_Start(fattack, sattack)
return true
})
f.Opp.Exec(func(t input.Effect) bool { //回合开始前
//结算状态
t.Turn_Start(fattack, sattack)
return true
})
// 伤害值 // 伤害值
// 根据攻击方归属设置当前战斗的主/次攻击方属性 // 根据攻击方归属设置当前战斗的主/次攻击方属性
@@ -141,7 +157,6 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
f.First.ResetAttackValue() f.First.ResetAttackValue()
f.Second.ResetAttackValue() f.Second.ResetAttackValue()
if fattack != nil { if fattack != nil {
//是否miss都应该施加解析effect //是否miss都应该施加解析effect
f.First.Parseskill(f.Second, fattack) //解析到临时数据 f.First.Parseskill(f.Second, fattack) //解析到临时数据
@@ -182,18 +197,7 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
} }
} }
var attacker, defender *input.Input var attacker, defender *input.Input
f.First.Exec(func(t input.Effect) bool { //回合开始前
//结算状态
t.Turn_Start()
return true
})
f.Second.Exec(func(t input.Effect) bool { //回合开始前
//结算状态
t.Turn_Start()
return true
})
//开始回合操作 //开始回合操作
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
var oldskill *info.SkillEntity //原始技能 var oldskill *info.SkillEntity //原始技能
@@ -214,13 +218,16 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
if oldskill != nil { if oldskill != nil {
fmt.Println("开始攻击威力", oldskill.Power) fmt.Println("开始攻击威力", oldskill.Power)
} }
//是否miss都应该施加解析effect
canuseskill := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能 canuseskill := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能
//结算状态 //结算状态
//然后这里还可以处理自爆类 //然后这里还可以处理自爆类
t.Ctx().SkillEntity = currentskill t.Ctx().SkillEntity = currentskill
return t.Skill_Hit_Pre() //返回本身结算,如果false,说明不能使用技能了 return t.Skill_Hit_Pre(fattack, sattack) //返回本身结算,如果false,说明不能使用技能了
}) })
// 结算状态 // 结算状态
// 然后这里还可以处理自爆类 // 然后这里还可以处理自爆类
if canuseskill && // if canuseskill && //
@@ -260,9 +267,7 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
//技能使用后 //技能使用后
defender.Exec(func(t input.Effect) bool { defender.Exec(func(t input.Effect) bool {
t.Ctx().SkillEntity = currentskill t.Ctx().SkillEntity = currentskill
t.Ctx().DamageZone = &info.DamageZone{
Damage: attacker.DamageZone.Damage,
}
t.Skill_Use_ex() t.Skill_Use_ex()
return true return true
@@ -271,9 +276,7 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
//技能使用后 //技能使用后
attacker.Exec(func(t input.Effect) bool { //技能使用后的我方效果 attacker.Exec(func(t input.Effect) bool { //技能使用后的我方效果
t.Ctx().SkillEntity = currentskill t.Ctx().SkillEntity = currentskill
t.Ctx().DamageZone = &info.DamageZone{
Damage: attacker.DamageZone.Damage,
}
t.Skill_Useed() t.Skill_Useed()
return true return true

View File

@@ -125,8 +125,7 @@ type WeakenedS struct {
// 定义战斗状态枚举 // 定义战斗状态枚举
var PetStatus = enum.New[struct { var PetStatus = enum.New[struct {
// 麻痹 Paralysis EnumBattleStatus `enum:"0"` // 麻痹
Paralysis EnumBattleStatus `enum:"0"`
Poisoned EnumBattleStatus `enum:"1"` // 中毒 Poisoned EnumBattleStatus `enum:"1"` // 中毒
Burned EnumBattleStatus `enum:"2"` // 烧伤 Burned EnumBattleStatus `enum:"2"` // 烧伤
DrainHP EnumBattleStatus `enum:"3"` // 吸取对方的体力 DrainHP EnumBattleStatus `enum:"3"` // 吸取对方的体力

View File

@@ -5,10 +5,10 @@ import (
) )
type Ctx struct { type Ctx struct {
Our *Input //施加方 Our *Input //施加方
Opp *Input //被施加方 Opp *Input //被施加方
*info.SkillEntity //action本身 *info.SkillEntity //action本身
*info.DamageZone //伤害 // *info.DamageZone //伤害
} }

View File

@@ -180,7 +180,7 @@ func (our *Input) Exec(fn func(Effect) bool) bool {
if value.Alive() { if value.Alive() {
value.Ctx().Our = our value.Ctx().Our = our
value.Ctx().Opp = our.Opp value.Ctx().Opp = our.Opp
value.Ctx().DamageZone = &info.DamageZone{} //value.Ctx().DamageZone = &info.DamageZone{}
if !fn(value) { //存在false,但是仍然要向下执行 if !fn(value) { //存在false,但是仍然要向下执行
result = false //如果是false,说明存在阻止向下执行的effect比如免疫能力提升效果 result = false //如果是false,说明存在阻止向下执行的effect比如免疫能力提升效果
} }

View File

@@ -105,9 +105,8 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) {
var ok bool var ok bool
if our != in { if our != in {
ok = our.Opp.Exec(func(t Effect) bool { ok = our.Opp.Exec(func(t Effect) bool {
t.Ctx().DamageZone = sub
t.Damage_ADD() //红伤落实前,我方增伤 t.Damage_ADD(sub) //红伤落实前,我方增伤
return true return true
}) })
@@ -115,8 +114,8 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) {
//sub.BeforeMul = sub.Damage //sub.BeforeMul = sub.Damage
if ok { if ok {
ok = our.Opp.Exec(func(t Effect) bool { ok = our.Opp.Exec(func(t Effect) bool {
t.Ctx().DamageZone = sub
t.Damage_Mul() //红伤落实前,我方增伤 t.Damage_Mul(sub) //红伤落实前,我方增伤
return true return true
}) })
@@ -124,8 +123,8 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) {
//sub.BeforeFloor = sub.Damage //sub.BeforeFloor = sub.Damage
if ok { if ok {
ok = our.Opp.Exec(func(t Effect) bool { ok = our.Opp.Exec(func(t Effect) bool {
t.Ctx().DamageZone = sub
t.Damage_Floor() //红伤落实,内部有befer t.Damage_Floor(sub) //红伤落实,内部有befer
return true return true
}) })
@@ -135,8 +134,8 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) {
// sub.BeforeMul = sub.Damage // sub.BeforeMul = sub.Damage
if ok { if ok {
ok = our.Exec(func(t Effect) bool { ok = our.Exec(func(t Effect) bool {
t.Ctx().DamageZone = sub
t.Damage_DIV_ex() //红伤落实,内部有befer t.Damage_DIV_ex(sub) //红伤落实,内部有befer
return true return true
}) })
@@ -145,9 +144,8 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) {
//sub.BeforeSUB = sub.Damage //sub.BeforeSUB = sub.Damage
if ok { if ok {
ok = our.Exec(func(t Effect) bool { ok = our.Exec(func(t Effect) bool {
t.Ctx().DamageZone = sub
t.Damage_SUB_ex() t.Damage_SUB_ex(sub)
return true return true
}) })
@@ -157,7 +155,7 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) {
if ok && in != our { if ok && in != our {
ok = our.Opp.Exec(func(t Effect) bool { ok = our.Opp.Exec(func(t Effect) bool {
t.Damage_Lock() t.Damage_Lock(sub)
return true return true
}) })
@@ -166,7 +164,7 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) {
if ok { if ok {
our.Exec(func(t Effect) bool { our.Exec(func(t Effect) bool {
t.Damage_Lock_ex() t.Damage_Lock_ex(sub)
return true return true
}) })

View File

@@ -24,6 +24,8 @@ type Input struct {
Effects []Effect //effects 实际上全局就是effect无限回合 //effects容器 技能的 Effects []Effect //effects 实际上全局就是effect无限回合 //effects容器 技能的
EffectCache []Effect //这里是命中前执行的容器,也就是命中前执行的所有逻辑相关,理论上一个effect被激活,就应该同时将其他的effect取消激活 EffectCache []Effect //这里是命中前执行的容器,也就是命中前执行的所有逻辑相关,理论上一个effect被激活,就应该同时将其他的effect取消激活
Effect_Lost []Effect Effect_Lost []Effect
//CanUseSkill bool
//Effect_Lost []Effect
//NewEffects []Effect //NewEffects []Effect
DamageZone struct { DamageZone struct {
@@ -96,6 +98,7 @@ func (our *Input) ResetAttackValue() {
our.AttackValue.GainHp = 0 our.AttackValue.GainHp = 0
our.AttackValue.LostHp = 0 our.AttackValue.LostHp = 0
our.DamageZone.Damage = decimal.NewFromInt(0) our.DamageZone.Damage = decimal.NewFromInt(0)
//our.CanUseSkill = true
} }
// 这个每回合都会调用 // 这个每回合都会调用
@@ -145,6 +148,7 @@ func (our *Input) GetStatusBonus() float64 {
// 解析并 施加effect // 解析并 施加effect
func (our *Input) Parseskill(defender *Input, skill *action.SelectSkillAction) { func (our *Input) Parseskill(defender *Input, skill *action.SelectSkillAction) {
our.EffectCache = make([]Effect, 0) //先把上一回合数据清空,但是应该把本身延续类效果集成过来 our.EffectCache = make([]Effect, 0) //先把上一回合数据清空,但是应该把本身延续类效果集成过来
our.Effect_Lost = make([]Effect, 0) our.Effect_Lost = make([]Effect, 0)
// our.Initeffectcache() //这里说明是延续的效果,每次复制出来一个新的就好了 // our.Initeffectcache() //这里说明是延续的效果,每次复制出来一个新的就好了

View File

@@ -6,28 +6,29 @@ import (
) )
type Effect interface { type Effect interface {
Compare_Pre(fattack, sattack *action.SelectSkillAction) bool //比较前对优先级的修改
Fight_Start() bool //战斗开始 Fight_Start() bool //战斗开始
Turn_Start() //回合开始,注入特性 Turn_Start(fattack, sattack *action.SelectSkillAction) //回合开始,注入特性
Compare_Pre(fattack, sattack *action.SelectSkillAction) bool //比较前对优先级的修改
//技能命中前的返回值代表是否可以出手 ,对命中本身的修改应该是对上下文本身的修改 //技能命中前的返回值代表是否可以出手 ,对命中本身的修改应该是对上下文本身的修改
Skill_Hit_Pre() bool //对技能修改 行动开始前,注入视为等参数在这里实现 //对技能修改 行动开始前,注入视为等参数在这里实现
Skill_Hit() bool //这是是命中后的对技能的修改,比如变威力
Skill_Hit_ex() bool // 技能命中前触发//预处理受击技能 被攻击方效果,比如受击时无效技能这样 Skill_Hit_Pre(fattack, sattack *action.SelectSkillAction) bool //比较前对优先级的修改
Skill_Hit() bool //这是是命中后的对技能的修改,比如变威力
Skill_Hit_ex() bool // 技能命中前触发//预处理受击技能 被攻击方效果,比如受击时无效技能这样
Calculate_Pre() bool //视为 无视效果,相当于这里对敌方的修改 Calculate_Pre() bool //视为 无视效果,相当于这里对敌方的修改
OnSkill() bool // 触发on miss onhit OnSkill() bool // 触发on miss onhit
//Skill_Can() bool //使用技能 可以取消用技能节点 技能无效节点锁定伤害加上 //Skill_Can() bool //使用技能 可以取消用技能节点 技能无效节点锁定伤害加上
Damage_ADD() bool // 攻击前触发 ,这时候就是+区间 Damage_ADD(*info.DamageZone) bool // 攻击前触发 ,这时候就是+区间
Damage_Mul() bool // 攻击触发 Damage_Mul(*info.DamageZone) bool // 攻击触发
Damage_Floor() bool // 保底伤害 Damage_Floor(*info.DamageZone) bool // 保底伤害
Damage_DIV_ex() bool //受击前触发 这时候就是百分比减伤区间 Damage_DIV_ex(*info.DamageZone) bool //受击前触发 这时候就是百分比减伤区间
Damage_SUB_ex() bool // 受击触发 这时候就是点数减伤 Damage_SUB_ex(*info.DamageZone) bool // 受击触发 这时候就是点数减伤
Damage_Lock() bool //锁定伤害 Damage_Lock(*info.DamageZone) bool //锁定伤害
Damage_Lock_ex() bool //被动方锁定伤害 Damage_Lock_ex(*info.DamageZone) bool //被动方锁定伤害
Damage_Shield() bool // 护盾值变化时触发 Damage_Shield(*info.DamageZone) bool // 护盾值变化时触发
//Damage_Use() bool // 伤害作用 //Damage_Use() bool // 伤害作用
Skill_Use_ex() bool //技能PP减少节点 Skill_Use_ex() bool //技能PP减少节点
Skill_Useed() bool //技能PP减少节点 Skill_Useed() bool //技能PP减少节点

View File

@@ -145,6 +145,10 @@ func (f *FightC) resolveRound(p1Action, p2Action action.BattleActionI) {
switch a := b1.(type) { switch a := b1.(type) {
case *action.ActiveSwitchAction: case *action.ActiveSwitchAction:
if f.GetInputByAction(a, false).CurrentPet.Info.Hp <= 0 {
f.GetInputByAction(a, false).CurrentPet.Info.Hp = 1
}
if b2k, ok := b2.(*action.SelectSkillAction); ok { if b2k, ok := b2.(*action.SelectSkillAction); ok {
f.waittime = b2k.CD f.waittime = b2k.CD
f.enterturn(b2.(*action.SelectSkillAction), nil) f.enterturn(b2.(*action.SelectSkillAction), nil)
@@ -155,6 +159,9 @@ func (f *FightC) resolveRound(p1Action, p2Action action.BattleActionI) {
case *action.UseItemAction: case *action.UseItemAction:
f.handleItemAction(a) f.handleItemAction(a)
if f.GetInputByAction(a, false).CurrentPet.Info.Hp <= 0 {
f.GetInputByAction(a, false).CurrentPet.Info.Hp = 1
}
if b2k, ok := b2.(*action.SelectSkillAction); ok { if b2k, ok := b2.(*action.SelectSkillAction); ok {
f.waittime = b2k.CD f.waittime = b2k.CD
f.enterturn(b2.(*action.SelectSkillAction), nil) f.enterturn(b2.(*action.SelectSkillAction), nil)

View File

@@ -6,10 +6,15 @@ import (
"blazing/logic/service/fight/input" "blazing/logic/service/fight/input"
) )
func (e *EffectNode) Compare_Pre(fattack, sattack *action.SelectSkillAction) bool { func (e *EffectNode) Skill_Hit_Pre(fattack, sattack *action.SelectSkillAction) bool {
return false return true
} }
func (e *EffectNode) Turn_Start() {
func (e *EffectNode) Compare_Pre(fattack, sattack *action.SelectSkillAction) bool { //比较前对优先级的修改 {
return true
}
func (e *EffectNode) Turn_Start(fattack, sattack *action.SelectSkillAction) {
//panic("not implemented") // TODO: Implement //panic("not implemented") // TODO: Implement
} }
func (e *EffectNode) Turn_End() { func (e *EffectNode) Turn_End() {

View File

@@ -1,34 +1,36 @@
package node package node
func (e *EffectNode) Damage_ADD() bool { import "blazing/logic/service/fight/info"
func (e *EffectNode) Damage_ADD(_ *info.DamageZone) bool {
return true return true
} }
func (e *EffectNode) Damage_Mul() bool { func (e *EffectNode) Damage_Mul(_ *info.DamageZone) bool {
return true return true
} }
func (e *EffectNode) Damage_Floor() bool { func (e *EffectNode) Damage_Floor(_ *info.DamageZone) bool {
return true return true
} }
func (e *EffectNode) Damage_DIV_ex() bool { func (e *EffectNode) Damage_DIV_ex(_ *info.DamageZone) bool {
return true return true
} }
func (e *EffectNode) Damage_SUB_ex() bool { func (e *EffectNode) Damage_SUB_ex(_ *info.DamageZone) bool {
return true return true
} }
func (e *EffectNode) Damage_Lock() bool { func (e *EffectNode) Damage_Lock(_ *info.DamageZone) bool {
return true return true
} }
func (e *EffectNode) Damage_Lock_ex() bool { func (e *EffectNode) Damage_Lock_ex(_ *info.DamageZone) bool {
return true return true
} }
func (e *EffectNode) Damage_Shield() bool { func (e *EffectNode) Damage_Shield(_ *info.DamageZone) bool {
return true return true
} }

View File

@@ -12,9 +12,6 @@ func (e *EffectNode) Calculate_Pre() bool {
return true return true
} }
func (e *EffectNode) Skill_Hit_Pre() bool {
return true
}
func (e *EffectNode) Skill_Hit() bool { func (e *EffectNode) Skill_Hit() bool {
return true return true
} }

View File

@@ -75,7 +75,15 @@ func WithConn(c gnet.Conn) PlayerOption {
p.MainConn = c p.MainConn = c
} }
} }
func (p *Player) UseCoins(t uint32) bool {
if p.Info.Coins < t {
return false
}
p.Info.Coins = p.Info.Coins - t
return true
}
func (p *Player) GetAction() { func (p *Player) GetAction() {
} }

View File

@@ -3,7 +3,7 @@ server:
address: ":8080" #前台服务器地址 address: ":8080" #前台服务器地址
port: 53388 #后台服务器端口 port: 53388 #后台服务器端口
rpc: 56409 #rpc服务端口 rpc: 56409 #rpc服务端口
game: [27777, 27778] game: [27000, 27778]
openapiPath: "/api.json" openapiPath: "/api.json"
swaggerPath: "/swagger" swaggerPath: "/swagger"
clientMaxBodySize: clientMaxBodySize:

View File

@@ -55,7 +55,7 @@ func (s *UserService) PetAdd(y model.PetInfo) {
player.PlayerID = s.userid player.PlayerID = s.userid
player.Data = y player.Data = y
player.CatchTime = y.CatchTime player.CatchTime = y.CatchTime
//player.InBag = 0 player.Free = 0
_, err := m1.Insert(player) _, err := m1.Insert(player)
if err != nil { if err != nil {