//using ProtoCSStruct; //using Sog; //using System; //using System.Collections.Generic; //using System.Linq; //using static Battle.BattleHero; //namespace Battle //{ // public static class BattleBuff // { // private static BattleHero[] attackBackBuffer = new BattleHero[4]; // private static int attackBackBufferCount = 0; // public static int ProcessEffectBuff(SkillDesc.Effect effectDesc, BattleObj battle, BattleHero caster, BattleHero target, SkillDesc skillDesc, // BattleHero.Buff buff, Dictionary buffParam = null) // { // TraceLog.Trace("BattleControl.ProcessEffectBuff into caster={0} buff={1} targetType={2} masterObjId={3}" // , caster.objId, buff.ToString(), effectDesc.target, caster.masterObjId); // var _target = target; // var success = true; // //int random = battle.Random.Next(10000); // //if (effectDesc.effectRate != 0 && effectDesc.effectRate < random) // //{ // // TraceLog.Trace("BattleControl.ProcessEffectBuff noRand caster={0} buffId={1} effectType={2} effectParam={3},{4},{5},{6} effectRate={7} random={8}" // // , caster.objId, skillDesc.id, effectDesc.effectType, effectDesc.param1, effectDesc.param2, effectDesc.param3, effectDesc.param4, effectDesc.effectRate, random); // // return 0; // //} // if (effectDesc.type <= (int)EffectType.None || effectDesc.type >= (int)EffectType.Max) // { // TraceLog.Error("BattleControl.ProcessEffectBuff effectType fail caster={0} buffId={1} effectType={2} effectParam={3},{4},{5},{6}" // , caster.objId, skillDesc.id, effectDesc.type, effectDesc.Param1, effectDesc.Param2, effectDesc.Param3, effectDesc.Param4); // return 0; // } // //TraceLog.BattleTrace(battle.battleInfo.RoleA.RoleBase.Uid, battle.BattleId, 0, "buffId {0} 触发时随机数 {1}", skillDesc.id, random); // switch (effectDesc.target) // { // case (int)EffectTargetType.CasterSelf: // _target = caster; // break; // case (int)EffectTargetType.AttackTarget: // _target = BattleControl.GetAttackTarget(battle, caster); // break; // case (int)EffectTargetType.Master: // _target = BattleHeroSvc.GetAliveMasterHero(battle, caster.initSide, caster.masterObjId); // break; // case (int)EffectTargetType.DamageSource: // _target = target; // if(_target == null) _target = BattleControl.GetAttackTarget(battle, caster); // break; // case (int)EffectTargetType.EnemyAll: // return ProcessAOE(effectDesc, battle, caster, target, skillDesc, buff); // } // if (_target == null) // { // TraceLog.Trace("BattleControl.ProcessEffectBuff no target caster={0} skill={1}", caster.objId, skillDesc.id); // return 0; // } // //if (!CheckCondition(effectDesc, caster, target, _target)) // //{ // // TraceLog.Trace("BattleControl.ProcessEffectBuff CheckCondition no caster={0} _target={1} buffId={2} effectType={3} effectParam={4},{5},{6},{7}" // // , caster.objId, _target.objId, skillDesc.id, effectDesc.type, effectDesc.Param1, effectDesc.Param2, effectDesc.Param3, effectDesc.Param4); // // return 0; // //} // success = BattleBuffEffect.BuffEffectMth(battle, caster, _target, skillDesc, buff, buffParam) == 0; // TraceLog.Trace("BattleControl.ProcessEffectBuff finish caster={0} _target={1} buff={2} success={3}" // , caster.objId, _target.objId, buff.ToString(), success); // return success ? 0 : -1; // } // public static int ProcessAOE(SkillDesc.Effect effectDesc, BattleObj battle, BattleHero caster, BattleHero target, SkillDesc skillDesc, BattleHero.Buff buff) // { // var _target = target; // var success = true; // var targets = BattleHeroSvc.GetAliveEnemy(battle, caster); // if (targets == null) // return 0; // for (var k = 0; k < targets.Count; k++) // { // if (targets[k].isDead) // continue; // if (!CheckCondition(effectDesc, caster, target, targets[k])) // { // TraceLog.Trace("BattleControl.ProcessAOE CheckCondition no caster={0} _target={1} buffId={2} effectType={3} effectParam={4},{5},{6},{7}" // , caster.objId, targets[k].objId, skillDesc.id, effectDesc.type, effectDesc.Param1, effectDesc.Param2, effectDesc.Param3, effectDesc.Param4); // continue; // } // success &= BattleBuffEffect.BuffEffectMth(battle, caster, targets[k], skillDesc, buff) == 0; // TraceLog.Trace("BattleControl.ProcessAOE caster={0} _target={1} buffId={2} effectType={3} effectParam={4},{5},{6},{7} targets.Count={8} targetIdx={9} success={10}" // , caster.objId, targets[k].objId, skillDesc.id, effectDesc.type, effectDesc.Param1, effectDesc.Param2, effectDesc.Param3, effectDesc.Param4, targets.Count, k + 1, success); // if (!success) // break; // if(battle.battleInfo.BattleLog.Logs.Count > 0 && battle.battleInfo.BattleLog.Logs[battle.battleInfo.BattleLog.Logs.Count - 1].EventType == BattleEventType.Attack) // { // var resutleBit = battle.battleInfo.BattleLog.Logs[battle.battleInfo.BattleLog.Logs.Count - 1].ResultBit; // resutleBit = BitUtils.BitSet(resutleBit, (int)BattleEventBit.MulTarget); // if (k != targets.Count - 1) // { // battle.battleInfo.BattleLog.Logs[battle.battleInfo.BattleLog.Logs.Count - 1].ResultBit = resutleBit; // } // } // } // if (effectDesc.type != (int)EffectType.AttackExtraTarget) // return 0; // // todo AOE反击特殊处理 // for (var k = 0; k < attackBackBufferCount; k++) // { // success &= AttackWithOutEvent(battle, caster, _target, true) == 0; // if (attackBackBufferCount > 1 && k == attackBackBufferCount - 1) // { // var lastLog = battle.battleInfo.BattleLog.Logs[battle.battleInfo.BattleLog.Logs.Count - 1]; // lastLog.ResultBit = BitUtils.BitSet(lastLog.ResultBit, (int)BattleEventBit.MulTarget); // } // } // return 0; // } // //立即生效和攻击目标修改记录 // public static int EffectBuffNowAndLastAtkChg(SkillDesc skill, SkillDesc.Effect desc, BattleObj battle, BattleHero caster, BattleHero target, BattleHero.Buff buff) // { // var success = true; // if (desc.type == (int)EffectType.AttackTargetChg) // { // success &= ProcessEffectBuff(desc, battle, caster, target, skill, buff) == 0; // } // return success ? 0 : -1; // } // // 这里传入的target是攻击目标, 并不是真正的Effect生效目标 且target是战斗里面传出来的 如果有,阵营只会是敌方 // public static int BattleBeginAddBuff(EffectEvent battleEvent, BattleObj battle, BattleHero caster, BattleHero target = null) // { // ref var hero = ref BattleHeroSvc.GetHeroByBattleHero(battle, caster); // TraceLog.Trace("BattleBuff.BattleBeginAddBuff front caster={0}, descId={1}, battleEvent={2}, buffCount={3}, HpMax={4}, Hp={5}, showMaxHp={6}" // , caster.objId, caster.DescId, (int)battleEvent, caster.buffs.Count, caster.GetHpMax(), caster.GetHp(), hero.ShowInfo.MaxHp); // caster.AddHp(caster.GetHpMax() - caster.GetHp()); // hero.ShowInfo.MaxHp = caster.GetHpMax(); // TraceLog.Trace("BattleBuff.BattleBeginAddBuff bak caster={0}, descId={1}, battleEvent={2}, buffCount={3}, HpMax={4}, Hp={5}, showMaxHp={6}" // , caster.objId, caster.DescId, (int)battleEvent, caster.buffs.Count, caster.GetHpMax(), caster.GetHp(), hero.ShowInfo.MaxHp); // return 0; // } // private static bool CheckCondition(SkillDesc.Effect effectDesc, BattleHero caster, BattleHero attackTarget, BattleHero buffTarget) // { // //switch (effectDesc.targetCond) // //{ // // case (int)EffectConditionType.None: return true; // // case (int)EffectConditionType.HpRate: return caster.GetHp() * 10000 / caster.GetHpMax() > effectDesc.targetCondParam1; // // case (int)EffectConditionType.HpLowTarget: return caster.GetHp() < attackTarget.GetHp(); // // case (int)EffectConditionType.EnemyStun: return buffTarget.IsStun(); // // default: return false; // //} // return true; // } // public static int BuffEvent(EffectEvent battleEvent, BattleObj battle, BattleHero caster, // BattleHero target = null, Dictionary buffParam = null) // { // int round = battle.round; // if (caster.buffs.Count > 0) // { // TraceLog.Trace("BattleControl.BuffEvent start caster={0}, battleEvent={1}, buffCount={2}, round = {3}" // , caster.objId, (int)battleEvent, caster.buffs.Count, round); // EffectBuff(battleEvent, round, battle, caster, target, buffParam); // RemoveBuff(battleEvent, round, battle, caster, caster); // TraceLog.Trace("BattleControl.BuffEvent end caster={0}, battleEvent={1}, buffCount={2}, round = {3}" // , caster.objId, (int)battleEvent, caster.buffs.Count, round); // } // return 0; // } // private static int EffectBuff(EffectEvent battleEvent, int round, BattleObj battle, BattleHero caster, // BattleHero target = null, Dictionary buffParam = null) // { // for (var i = 0; i < caster.buffs.Count; i++) // { // var buff = caster.buffs[i]; // if (buff.effect == null) // continue; // EffectBuff(battleEvent, round, battle, caster, buff, target, buffParam); // } // return 0; // } // private static bool EffectBuff(EffectEvent battleEvent, int round, BattleObj battle, BattleHero caster, Buff buff, // BattleHero target = null, Dictionary buffParam = null) // { // if (buff.effect == null) // return false; // //0 不考虑回合 // //3 战斗开始 // //1 第X回合 X // //2 第X回合,每Y回合生效,持续Z回合 X, Y, Z // if (buff.effect.start == 3 && round != 0) return false; // if (buff.effect.start == 1 && round != buff.effect.startParam[0]) return false; // if (buff.effect.start == 2) // { // if (!(round >= buff.effect.startParam[0] // && (round - buff.effect.startParam[0]) % buff.effect.startParam[1] == 0 // && round <= buff.effect.startParam[0] + buff.effect.startParam[2] // )) // { // return false; // } // } // if (!CheckCanEffectWithTriggerParam(battleEvent, ref buff.triggerParam, buff.effect.trigger, buff.effect.triggerParam, // battle, caster, target, buffParam)) // { // return false; // } // if (buff.effect.maxLayer > 0 && buff.effectCount >= buff.effect.maxLayer) // { // TraceLog.Trace("BattleControl.EffectBuff over maxlayer caster={0}, buff={1}, maxLayer={2}" // , caster.objId, buff.ToString(), buff.effect.maxLayer); // return false; // } // buff.effectCount++; // var desc = SkillDescMgr.Instance.GetConfig(buff.buffid); // var success = ProcessEffectBuff(buff.effect, battle, caster, target, desc, buff, buffParam) == 0; // if (success && buff.effectCount == 1) // { // buff.effectRound = round; // } // TraceLog.Trace("BattleControl.EffectBuff caster={0}, target={1}, buff={2}, event={3} success={4}" // , caster.objId, target == null ? -1 : target.objId, buff.ToString(), battleEvent, success); // if (success) // { // if (battleEvent != EffectEvent.BuffEffect) // { // //EffectBuff(EffectEvent.BuffEffect, round, battle, caster, buff, target, buffParam); // RemoveBuff(EffectEvent.BuffEffect, round, battle, caster, target, buff); // } // } // return success; // } // // 事件发生buff次数减1,0就进行移除(预留驱散效果) // private static int RemoveBuff(EffectEvent battleEvent, int round, BattleObj battle, BattleHero caster, BattleHero target) // { // for (var i = 0; i < target.buffs.Count; i++) // { // var buff = target.buffs[i]; // if(RemoveBuff(battleEvent, round, battle, caster, target, buff)) // { // i -= 1; // } // } // return 0; // } // private static bool RemoveBuff(EffectEvent battleEvent, int round, BattleObj battle, BattleHero caster, BattleHero target, Buff buff) // { // var desc = SkillDescMgr.Instance.GetConfig(buff.buffid); // if (buff.effect == null) // return false; // //0 自身死亡 // //1 第X回合 X // //2 添加后第x回合 // //3 第一次生效后第x回合0 // if (buff.effect.final == 0 && battleEvent == EffectEvent.Die // || buff.effect.final == 1 && round == buff.effect.Param // || buff.effect.final == 2 && round == buff.addRound + buff.effect.Param // || buff.effect.final == 3 && buff.effectRound > 0 && round == buff.effectRound + buff.effect.Param // || CheckCanEffectWithTriggerParam(battleEvent, ref buff.endTriggerParam, buff.effect.finalTrigger, buff.effect.finalTriggerParam, battle, caster, target) // ) // { // TraceLog.Trace("BattleControl.RemoveBuff caster={0}, target={1}, battleEvent={2}, buff={3}" // , caster.objId, target.objId, (int)battleEvent, buff.ToString()); // if (DeleteBuff(buff, battle, caster, target)) // return true; // } // return false; // } // // 指定buff生效次数减1,0就进行删除 // private static bool DeleteBuff(BattleHero.Buff buff, BattleObj battle, BattleHero caster, BattleHero target) // { // var desc = SkillDescMgr.Instance.GetConfig(buff.buffid); // if (desc == null) // { // return false; // } // RemoveBuffAction(battle, buff.effect, buff); // // buff.needRemove = true; // target.buffs.Remove(buff); // var idx = CreateBattleLog(battle, caster.objId, target.objId, BattleEventType.RemoveBuff, 0, 0, 0, desc, buff.effect, buff.effectIdx); // if (idx == -1) // { // TraceLog.Trace("BattleControl.DeleteBuff caster={0} target={1} buffId={2} buffLevel={3} success={4}" // , caster.objId, target.objId, buff.buffid, buff.level, false); // battle.Result = CSBattleResult.Failed; // return false; // } // TraceLog.Trace("BattleControl.DeleteBuff caster={0} target={1} buff={2}" // , caster.objId, target.objId, buff.ToString()); // return true; // } // private static readonly int isSave = 1; // public static int DeadRemoveBuff(BattleObj battle, BattleHero deadOne) // { // //for (var i = deadOne.buffs.Count - 1; i > 0; i--) // //{ // // var desc = SkillDescMgr.Instance.GetConfig(deadOne.buffs[i].buffid); // // if (desc.isDeadSave != isSave) // // { // // RemoveBuffAction(deadOne, desc, deadOne.buffs[i].count); // // var idx = CreateBattleLog(battle, deadOne.objId, deadOne.objId, BattleEventType.RemoveBuff, 0, 0, 0, desc); // // if (idx == -1) // // { // // TraceLog.Trace("BattleControl.DeadRemoveBuff caster={0}, target={1}, buffId={2}, battleEvent = {3} success = {4}" // // , deadOne.objId, deadOne.objId, desc.id, (int)BattleEventType.Buff, false); // // battle.Result = CSBattleResult.Failed; // // return -1; // // } // // deadOne.buffs.Remove(deadOne.buffs[i]); // // } // //} // return 0; // } // // 战斗结束回收Hero // public static void AttackBackBufferClear() // { // for (int i = 0; i < attackBackBuffer.Length; i++) attackBackBuffer[i] = null; // attackBackBufferCount = 0; // } // // 效果的攻击不触发连击和效果为攻击的buff, 所以这里另外处理身上的buff 连击由BattleControl自己去连 // public static int AttackWithOutEvent(BattleObj battle, BattleHero caster, BattleHero target, bool isAtkBack) // { // var logIdx = BattleControl.CreateBattleLog(battle, caster.objId, target.objId, // isAtkBack ? BattleEventType.AtkBack : BattleEventType.Attack); // if (logIdx == -1) // { // TraceLog.Error("BattleControl.Attack battle {0} failed, not enough log space", battle.BattleId); // battle.battleInfo.BattleResult = CSBattleResult.Failed; // return -1; // } // TraceLog.Trace("BattleControl.Attack caster {0}-{1} target {2}-{3} isAtkBack {4}" // , caster.objId, caster.DescId, target.objId, target.DescId, isAtkBack); // var c_atk = caster.prop.GetValueNoCheck(CSPropIDType.Atk); // var t_def = target.prop.GetValueNoCheck(CSPropIDType.Def); // // 基础伤害 // var b1 = c_atk * BattleControl.GetBattleParamCfg().minDmgRate / 10000; // var b2 = c_atk - t_def; // var dmg = Math.Max(b1, b2); // // 浮动系数 // var r = battle.Random.Next(BattleControl.GetBattleParamCfg().minR, BattleControl.GetBattleParamCfg().maxR); // // 欺凌系数 // long bully = 10000; // if (BattleControl.IsBullyAtk(target)) // { // bully += caster.prop.GetValueNoCheck(CSPropIDType.Bully); // } // dmg = dmg * r / 10000 * bully / 10000; // TraceLog.Trace("BattleControl.Attack b1={0}, b2={1}, r={2} bully={3} dmg {4}", b1, b2, r, bully, dmg); // ref var _evtLog = ref BattleControl.GetBattleLog(battle, logIdx - 1); // _evtLog.ResultBit = BitUtils.BitSet(_evtLog.ResultBit, (int)BattleEventBit.MulTarget); // ref var evtLog = ref BattleControl.GetBattleLog(battle, logIdx); // evtLog.Damage = dmg; // // 暴击不能闪避 // if (BattleControl.IsCriAtk(battle, caster, target)) // { // var c_cp = caster.prop.GetValueNoCheck(CSPropIDType.CriPower); // var t_uncp = target.prop.GetValueNoCheck(CSPropIDType.UnCriPower); // // 暴击系数 // var criPower = Math.Max(10000, BattleControl.GetBattleParamCfg().baseCriPower + c_cp - t_uncp); // dmg = dmg * criPower / 10000; // TraceLog.Trace("BattleControl.Attack cri hit, criPower {0} dmg {1}", criPower, dmg); // evtLog.Damage = dmg; // evtLog.ResultBit = BitUtils.BitSet(evtLog.ResultBit, (int)BattleEventBit.Crit); // Hit(battle, caster, target, dmg, ref evtLog); // } // else // { // if (BattleControl.IsDodge(battle, caster, target)) // { // evtLog.Damage = 0; // evtLog.ResultBit = BitUtils.BitSet(evtLog.ResultBit, (int)BattleEventBit.Dodge); // } // else // { // Hit(battle, caster, target, dmg, ref evtLog); // } // } // if (!isAtkBack) // { // if (target.IsActiveState() && BattleControl.IsAtkBack(battle, target, caster)) // { // TraceLog.Trace("BattleControl.Attack target {0}-{1} attack back", target.objId, target.DescId); // evtLog.ResultBit = BitUtils.BitSet(evtLog.ResultBit, (int)BattleEventBit.BeAtkBack); // attackBackBuffer[attackBackBufferCount] = target; // attackBackBufferCount += 1; // } // } // return 0; // } // public static void Hit(BattleObj battle, BattleHero caster, BattleHero target, // long dmg, ref BattleEventLogOne evtLog) // { // TraceLog.Trace("BattleControl.Hit caster {0} target {1} dmg {2}", caster.objId, target.objId, dmg); // // 攻击命中时才会造成眩晕 // if (BattleControl.IsStunAtk(battle, caster, target)) // { // target.stunRound = target.IsActed() ? battle.round + 1 : battle.round; // TraceLog.Trace("BattleControl.Hit target {0} stun round {1}", target.objId, target.stunRound); // evtLog.ResultBit = BitUtils.BitSet(evtLog.ResultBit, (int)BattleEventBit.Stun); // BuffEvent(EffectEvent.Stun, battle, caster, target); // } // else // { // BuffEvent(EffectEvent.NotStun, battle, caster, target); // } // if (dmg <= 0) // { // return; // } // BattleControl.Hurt(battle, caster, target, dmg, ref evtLog); // BattleControl.LifeSteal(battle, caster, target, dmg, ref evtLog); // BuffEvent(EffectEvent.BeHit, battle, target, caster); // BattleControl.Dead(battle, caster, target, ref evtLog); // } // private static int CreateBattleLog(BattleObj battle, int casterId, int targetId, // BattleEventType evtType, uint resultBits, long dmg, long heal, SkillDesc skill, SkillDesc.Effect effect, int effectIdx) // { // if (effect.ShowID != 0) // { // return BattleControl.CreateBattleLog(battle, casterId, targetId, evtType, resultBits, dmg, heal, skill.id, effectIdx); // } // return 0; // } // private static void RemoveBuffAction(BattleObj battle, SkillDesc.Effect effDesc, BattleHero.Buff buff) // { // int level = buff.level; // switch ((EffectType)effDesc.type) // { // case EffectType.AddProp: // { // BattleHero target = BattleHeroSvc.GetAliveHeroByObjId(battle, buff.targetId); // if (target != null) // { // target.prop.AddValue((CSPropIDType)effDesc.Param1[level - 1], -effDesc.Param2[level - 1] * buff.effectCount); // } // } // break; // case EffectType.AttBackAtStun: // { // BattleHero target = BattleHeroSvc.GetAliveHeroByObjId(battle, buff.targetId); // if (target != null) // { // target.prop.AddValue(CSPropIDType.AtkBackAtStun, -1 * buff.effectCount); // } // } // break; // //case EffectType.AddPropByCurrent: // // double rate = (double)effDesc.Param1[level - 1] / (effDesc.Param1[level - 1] + 10000); // // double value = owner.GetProp((CSPropIDType)effDesc.Param1[level - 1]) * rate; // // owner.prop.AddValue((CSPropIDType)effDesc.Param1[level - 1], -(int)value); // // break; // //case EffectType.DamIgnore: // // owner.prop.AddValue(CSPropIDType.DamageIgnore, -effDesc.Param1[level - 1] * buff.effectCount); // // break; // case EffectType.DamUp: // { // BattleHero target = BattleHeroSvc.GetAliveHeroByObjId(battle, buff.targetId); // if (target != null) // { // target.prop.AddValue(CSPropIDType.DamageRate, -effDesc.Param1[level - 1] * buff.effectCount); // } // } // break; // case EffectType.UnHeal: // { // BattleHero target = BattleHeroSvc.GetAliveHeroByObjId(battle, buff.targetId); // if (target != null) // { // target.prop.AddValue(CSPropIDType.HealRate, -effDesc.Param1[level - 1] * buff.effectCount); // } // } // break; // } // } // private static bool CheckCanEffectWithTriggerParam(EffectEvent battleEvent, ref int triggerTimes, int trigerType, int[] trigerParam, BattleObj battle, BattleHero caster, // BattleHero target = null, Dictionary buffParam = null) // { // if ((int) battleEvent != trigerType) // { // return false; // } // switch (battleEvent) // { // case EffectEvent.HurtAfter: // { // if (target == null) // { // target = caster; // } // int rate = (int)(target.GetHp() * 10_000 / target.GetHpMax()); // if (rate <= trigerParam[0]) // { // return true; // } // } // break; // case EffectEvent.HealAfter: // { // if (target == null) // { // target = caster; // } // int rate = (int)(target.GetHp() * 10_000 / target.GetHpMax()); // if (rate >= trigerParam[0]) // { // return true; // } // } // break; // default: // //累计x次 // if (trigerParam.Length > 0 && trigerParam[0] > 0) // { // triggerTimes++; // if (triggerTimes < trigerParam[0]) // { // return false; ; // } // else // { // triggerTimes = 0;//重新清0 // } // } // return true; // } // return false; // } // } //}