Files
JJBB/Assets/Project/Script/Player/Impact/Impact_Chaos.cs

217 lines
8.7 KiB
C#
Raw Permalink Normal View History

2024-08-23 15:49:34 +08:00
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;
}
}
}