Files
JJBB/Assets/Project/Script/Player/Impact/Impact_Chaos.cs
2024-08-23 15:49:34 +08:00

217 lines
8.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using Games.AI_Logic;
using Games.Events;
using Games.GlobeDefine;
using Games.LogicObj;
using Games.SkillModle;
using GCGame.Table;
using Module.Log;
using UnityEngine;
using System.Linq;
using Games.ImpactModle;
using Random = UnityEngine.Random;
/// <summary>
/// 混乱表现逻辑
/// Effect.txt 表格扩展参数说明
/// Param1 EffectParam.txt中id值 身体材质相关配置
/// Param2 粒子特效ID
/// Param3 粒子特效ID
/// Param4 粒子特效ID
/// EffectParam.txt 表格扩展参数说明
/// Param1 : 等待状态持续时间(/千分秒)
/// Param2 : 最大索敌距离(/Unity单位
/// Param3 : 连续攻击最小次数
/// Param4 : 连续攻击最大次数
/// </summary>
public class Impact_Chaos : ImpactEffectBase
{
public override EffectLogic.EffectType ImpactEffectType
{
get { return EffectLogic.EffectType.TYPE_CHAOS; }
}
// 试图接近目标时,更新周期
private float _walkUpdateInterval = 0.2f;
// 优先搜索距离
private float _searchDistanceSqr0;
// 次要搜索距离
private float _searchDistanceSqr1;
// 执行行动间隔时间
// 下次执行行动的时间
private float _nextActionTime;
private Obj_MainPlayer _mainPlayer;
// 最小连续攻击次数
private int _comboMin;
// 最大连续攻击次数
private int _comboMax;
// 当前锁定目标
private Obj_Character _target;
// 当前已经执行的Combo数目
private int _currentExecuteCombo;
// 当前试图执行的Combo数目
private int _currentCombo;
public override void StartEffect()
{
base.StartEffect();
_mainPlayer = objCharacter as Obj_MainPlayer;
if (_mainPlayer != null)
{
var paramid = Data.GetParamValuebyIndex(0);
var effectparam = TableManager.GetEffectParamByID(paramid, 0);
if (effectparam == null)
_mainPlayer = null;
else
{
// 如果出现错误,将无法正常运行
if (float.TryParse(effectparam.GetParamValuebyIndex(0), out _searchDistanceSqr0) &&
float.TryParse(effectparam.GetParamValuebyIndex(1), out _searchDistanceSqr1) &&
int.TryParse(effectparam.GetParamValuebyIndex(2), out _comboMin) &&
int.TryParse(effectparam.GetParamValuebyIndex(3), out _comboMax))
{
_searchDistanceSqr0 = _searchDistanceSqr0.ToSquare();
_searchDistanceSqr1 = _searchDistanceSqr1.ToSquare();
}
else
{
_mainPlayer = null;
LogModule.ErrorLog(string.Format("特效参数{0}数据无法被Impact_Chaos读取", effectparam.EffectParamID));
}
}
if (_mainPlayer != null)
{
_mainPlayer.AddDisableState(((int)Games.ImpactModle.DISABLESTATE.Chaos).ToFlag());
for (var i = 1; i < 4; i++)
{
paramid = Data.GetParamValuebyIndex(i);
if (paramid > -1)
_mainPlayer.PlayEffect(paramid);
}
}
}
}
protected override void UpdateInherited()
{
if (_mainPlayer != null)
{
if (Time.time > _nextActionTime && GameManager.gameManager.PlayerDataPool.AllowSimpleInput)
{
_nextActionTime = Time.time + _walkUpdateInterval;
if (_target == null || !ValidTarget(_target))
{
_target = SearchTarget();
_currentCombo = 0;
_currentExecuteCombo = 0;
}
if (_target != null)
{
if (_currentCombo == 0)
_currentCombo = Random.Range(_comboMin, _comboMax + 1);
var moveToTarget = true;
// 当前允许使用普攻时,试图使用普攻
// 特殊处理,不打断自动连续技能
if (_mainPlayer.SkillAllowSimpleAttack
&& _mainPlayer.IsDisableState(DISABLESTATE.Disable_Select)
&& (!_mainPlayer.IsPredictSkill || !_mainPlayer.PredictSkillBase.SkillClass.ContainFlag((int)SKILLCLASS.AUTOREPEAT))
&& (!_mainPlayer.IsUsingSkill || !_mainPlayer.SkillCore.CurrentSkillBase.SkillClass.ContainFlag((int)SKILLCLASS.AUTOREPEAT)))
{
var attackSkill = _mainPlayer.GetNextSimpleAttack();
if (attackSkill != null
&& _mainPlayer.CheckSkillCastable(attackSkill.SkillBaseTable, attackSkill.SkillExTable, attackSkill.IsCooldownFinish(), false) == SkillCastableCheckResult.Success
&& _mainPlayer.ValidSkillRangeOnTarget(attackSkill.ComboExTableFinal,
attackSkill.ComboBaseTable, _target, rangeReduce: Obj_MainPlayer.skillCastOverwalk))
{
moveToTarget = false;
if (_mainPlayer.ProcessSkill(attackSkill, _target, Vector2.zero))
_currentExecuteCombo++;
// 执行1-4次普攻后休息并强制切换目标
if (_currentExecuteCombo >= _currentCombo)
{
_target = SearchTarget(_target.ServerID);
_currentCombo = 0;
_currentExecuteCombo = 0;
}
}
}
// 无法攻击时,试图向目标移动
if (moveToTarget && (_mainPlayer.Position - _target.Position).RemoveY().sqrMagnitude > AI_PlayerCombat.minCloseInDistance.ToSquare())
{
_mainPlayer.MainPlayMoveToTarget(_target,
new Obj_MainPlayer.MoveToTargetTillDistance(AI_PlayerCombat.minCloseInDistance),
isMoveOrder: false);
}
}
}
}
}
/// <summary>
/// 混乱专用的目标检测方式
/// </summary>
private bool ValidTarget(Obj_Character target)
{
var result = false;
if (!target.IsDie() && !target.isInvisible && !target.IsDisableState(DISABLESTATE.Disable_BeSelect) && target.ObjType != GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER)
{
if (target.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER)
{
if (_mainPlayer.ValidPkProtection(target, false))
result = true;
}
else if (target.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_NPC)
{
if (Reputation.CanAttack(target))
result = true;
}
}
return result;
}
// 注:特殊扫描方式 - 仅搜索敌对NPC和任意阵营OtherPlayer忽略其他类型目标
// 尽量忽略上一次攻击的目标
private Obj_Character SearchTarget(int excludeId = -1)
{
var targets = (from keyValue in Singleton<ObjManager>.GetInstance().ObjPools
let character = keyValue.Value as Obj_Character
where character != null && ValidTarget(character)
select character).ToArray();
var result = GetRandomTargetInRange(targets, _searchDistanceSqr0, excludeId);
if (result == null)
result = GetRandomTargetInRange(targets, _searchDistanceSqr1, excludeId);
return result;
}
private Obj_Character GetRandomTargetInRange(Obj_Character[] characters, float rangeSqr, int excludeId = -1)
{
Obj_Character excludeTarget = null;
var targetList = new List<Obj_Character>();
for (var i = 0; i < characters.Length; i++)
{
if ((characters[i].Position - _mainPlayer.Position).RemoveY().sqrMagnitude < rangeSqr)
{
if (characters[i].ServerID == excludeId)
excludeTarget = characters[i];
else
targetList.Add(characters[i]);
}
}
// 尽量不选择excludeTarget
var result = targetList.Count > 0 ? targetList[Random.Range(0, targetList.Count)] : excludeTarget;
return result;
}
public override void StopEffect()
{
base.StopEffect();
if (_mainPlayer != null)
{
_mainPlayer.DelDisableState(((int)Games.ImpactModle.DISABLESTATE.Chaos).ToFlag());
_mainPlayer = null;
}
}
}