统一处理效果45、51、55、56的属性同步与反转逻辑,优化代码结构并提高可维护性。新增通用效果结构体 `EffectPropSyncReverse` 和操作类型定义,集中管理不同属性操作行为。 fix(controller): 修复玩家离开地图逻辑错误 修正 `FRESH_LEAVE_FIGHT_LEVEL` 接口中 defer 调用为进入地图,并发送角色信息包给客户端以确保状态一致。 feat(effect): 新增天敌机制核心逻辑占位 在 `NewSel14` 效果中添加 `Turn_Start` 方法,实现若遇到天敌则害怕多回合的核心逻辑框架。 chore(config): 更新Boss配置怪物ID及血量 调整Boss ID为2的怪物配置,替换原有Monster ID并设置血量为10,用于测试或平衡调整。 refactor(fight): 优化战斗循环和精灵切换逻辑 整理战斗主循环中的血量赋值语句格式,调整精灵切换时变量顺序以避免潜在问题,并修复死亡标记逻辑。 refactor(node): 恢复BoolisFalse方法实现 取消注释 `BoolisFalse` 方法内容,恢复其正常功能以便其他模块正确判断布尔条件。 style(logic): 格式化代码空行和缩进 清理多余空行,对齐导入语句与其他代码块格式,增强整体代码可读性。 debug(effect): 增加烧伤伤害调试打印 在持续伤害效果中加入println语句,输出实际造成的真实伤害数值便于排查问题。
229 lines
6.4 KiB
Go
229 lines
6.4 KiB
Go
package effect
|
||
|
||
import (
|
||
element "blazing/common/data/Element"
|
||
"blazing/common/utils"
|
||
"blazing/logic/service/fight/action"
|
||
"blazing/logic/service/fight/info"
|
||
"blazing/logic/service/fight/input"
|
||
"blazing/logic/service/fight/node"
|
||
|
||
"github.com/alpacahq/alpacadecimal"
|
||
)
|
||
|
||
// 修正拼写错误:BaseSataus -> BaseStatus
|
||
type BaseStatus struct {
|
||
node.EffectNode
|
||
Status info.EnumPetStatus // 状态类型枚举
|
||
}
|
||
|
||
// 重写切换事件:我方单位切换时清除状态
|
||
func (e *BaseStatus) Switch(in *input.Input, _ info.AttackValue, _ *info.BattlePetEntity) bool {
|
||
// 我方单位下场时,状态失效
|
||
if in == e.Ctx().Our {
|
||
e.Alive(false)
|
||
}
|
||
return true
|
||
}
|
||
|
||
// 不能出手的基础状态(如麻痹、疲惫等)
|
||
type StatusCannotAct struct {
|
||
BaseStatus
|
||
}
|
||
|
||
// 技能命中前拦截:阻止出手
|
||
func (e *StatusCannotAct) Action_start(attacker, defender *action.SelectSkillAction) bool {
|
||
return false
|
||
}
|
||
|
||
// 睡眠状态:受击后解除
|
||
type StatusSleep struct {
|
||
StatusCannotAct
|
||
hasTriedAct bool // 标记是否尝试过行动
|
||
}
|
||
|
||
// 尝试出手时标记状态
|
||
func (e *StatusSleep) Action_start(attacker, defender *action.SelectSkillAction) bool {
|
||
e.hasTriedAct = true
|
||
return e.StatusCannotAct.Action_start(attacker, defender)
|
||
}
|
||
|
||
// 技能使用后处理:非状态类技能触发后解除睡眠
|
||
func (e *StatusSleep) Skill_Use_ex() bool {
|
||
if !e.hasTriedAct {
|
||
return true
|
||
}
|
||
// 技能实体存在且非状态类型技能,解除睡眠
|
||
if e.Ctx().SkillEntity != nil && e.Ctx().Category() != info.Category.STATUS {
|
||
e.Alive(false)
|
||
}
|
||
return true
|
||
}
|
||
|
||
// 持续伤害状态基类(中毒、冻伤、烧伤等)
|
||
type ContinuousDamage struct {
|
||
BaseStatus
|
||
}
|
||
|
||
// 技能命中前触发伤害(1/8最大生命值真实伤害)
|
||
func (e *ContinuousDamage) Action_start(attacker, defender *action.SelectSkillAction) bool {
|
||
damage := e.calculateDamage()
|
||
println(damage.IntPart(), "烧伤")
|
||
e.Ctx().Our.Damage(e.Input, &info.DamageZone{
|
||
Type: info.DamageType.True,
|
||
Damage: damage,
|
||
})
|
||
return true
|
||
}
|
||
|
||
// 计算伤害:最大生命值的1/8
|
||
func (e *ContinuousDamage) calculateDamage() alpacadecimal.Decimal {
|
||
return alpacadecimal.NewFromInt(int64(e.Ctx().Our.CurrentPet.Info.MaxHp)).
|
||
Div(alpacadecimal.NewFromInt(8))
|
||
}
|
||
|
||
type Burned struct {
|
||
ContinuousDamage //继承扣血类
|
||
}
|
||
|
||
func (e *Burned) Skill_Hit() bool {
|
||
|
||
e.Ctx().SkillEntity.Power /= 2
|
||
return true
|
||
}
|
||
|
||
// 寄生种子状态:扣血同时给对方回血
|
||
type ParasiticSeed struct {
|
||
BaseStatus
|
||
}
|
||
|
||
// 技能命中前触发寄生效果
|
||
func (e *ParasiticSeed) Action_start_ex(attacker, defender *action.SelectSkillAction) bool {
|
||
// 过滤特定类型单位(假设1是植物类型,使用枚举替代魔法数字)
|
||
|
||
damage := alpacadecimal.NewFromInt(int64(e.Ctx().Our.CurrentPet.Info.MaxHp)).
|
||
Div(alpacadecimal.NewFromInt(8))
|
||
|
||
// 对我方造成真实伤害
|
||
e.Ctx().Our.Damage(e.Input, &info.DamageZone{
|
||
Type: info.DamageType.True,
|
||
Damage: damage,
|
||
})
|
||
|
||
// 给对方回血(不受回血限制影响)
|
||
e.Ctx().Opp.Heal(e.Ctx().Our, nil, damage)
|
||
return true
|
||
}
|
||
|
||
type Flammable struct {
|
||
BaseStatus
|
||
}
|
||
|
||
func (e *Flammable) Action_start(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
|
||
if e.Ctx().SkillEntity == nil {
|
||
return true
|
||
}
|
||
e.Ctx().SkillEntity.Accuracy -= 30
|
||
|
||
return true
|
||
|
||
}
|
||
func (e *Flammable) Skill_Use_ex() bool {
|
||
if e.Ctx().SkillEntity == nil {
|
||
return true
|
||
}
|
||
|
||
if e.Ctx().SkillEntity.Type != int(element.ElementTypeFire) {
|
||
return true
|
||
}
|
||
// 获取状态效果
|
||
eff := e.Ctx().Our.InitEffect(input.EffectType.Status, int(info.PetStatus.Burned))
|
||
if eff == nil {
|
||
return true
|
||
}
|
||
|
||
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
|
||
|
||
return true
|
||
|
||
}
|
||
|
||
type Confused struct {
|
||
BaseStatus
|
||
}
|
||
|
||
func (e *Confused) Action_start(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
|
||
if e.Ctx().SkillEntity == nil {
|
||
return true
|
||
}
|
||
e.Ctx().SkillEntity.Accuracy -= 80
|
||
ok, _, _ := e.Input.Player.Roll(5, 100)
|
||
if !ok {
|
||
return true
|
||
}
|
||
|
||
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
|
||
Type: info.DamageType.Fixed,
|
||
Damage: alpacadecimal.NewFromInt(50),
|
||
})
|
||
return true
|
||
|
||
}
|
||
|
||
type Weakened struct {
|
||
BaseStatus
|
||
}
|
||
|
||
func (e *Weakened) Damage_DIV_ex(t *info.DamageZone) bool {
|
||
// 1. 定义衰弱等级对应的倍率表(索引对应等级,0级无倍率)
|
||
// 索引0: 0%(未衰弱)、1:25%、2:50%、3:100%、4:250%、5:500%
|
||
weakenedMultiples := []alpacadecimal.Decimal{
|
||
alpacadecimal.NewFromInt(0), // 0级
|
||
alpacadecimal.NewFromFloat(0.25), // 1级(25%)
|
||
alpacadecimal.NewFromFloat(0.5), // 2级(50%)
|
||
alpacadecimal.NewFromFloat(1.0), // 3级(100%)
|
||
alpacadecimal.NewFromFloat(2.5), // 4级(250%)
|
||
alpacadecimal.NewFromFloat(5.0), // 5级(500%)
|
||
}
|
||
|
||
// 2. 校验并限制衰弱等级(≤0 直接返回,≥5 按5级算)
|
||
level := e.Stack()
|
||
if level <= 0 {
|
||
return true
|
||
}
|
||
// 等级上限限制为5(避免越界)
|
||
level = utils.Min(level, 5)
|
||
|
||
// 3. 获取对应等级的倍率,计算最终伤害
|
||
multiple := weakenedMultiples[level]
|
||
// 伤害计算公式:原伤害 + 原伤害 × 倍率(等价于 原伤害 × (1+倍率))
|
||
t.Damage = t.Damage.Add(t.Damage.Mul(multiple))
|
||
|
||
return true
|
||
}
|
||
func init() {
|
||
// 注册持续伤害类状态
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.DrainedHP), &ParasiticSeed{}) // 寄生种子
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Poisoned), &ContinuousDamage{}) // 中毒
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Frozen), &ContinuousDamage{}) // 冻伤
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Burned), &Burned{}) // 烧伤
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Weakened), &Weakened{}) // 衰弱
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Confused), &Confused{}) // 混乱
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Flammable), &Flammable{}) // 易燃
|
||
// 批量注册不能行动的状态
|
||
nonActingStatuses := []info.EnumPetStatus{
|
||
info.PetStatus.Paralysis, // 麻痹
|
||
info.PetStatus.Tired, // 疲惫
|
||
info.PetStatus.Fear, // 害怕
|
||
info.PetStatus.Petrified, // 石化
|
||
}
|
||
for _, status := range nonActingStatuses {
|
||
effect := &StatusCannotAct{}
|
||
effect.Status = status
|
||
input.InitEffect(input.EffectType.Status, int(status), effect)
|
||
}
|
||
|
||
// 注册睡眠状态(使用枚举常量替代硬编码8)
|
||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Sleep), &StatusSleep{})
|
||
}
|