Files
JJBB/Assets/Project/Script/Player/Skill/SkillCore.cs

327 lines
14 KiB
C#
Raw Permalink Normal View History

2024-08-23 15:49:34 +08:00
/********************************************************************************
* SkillCore.cs
* \Script\GameManager\SkillCore.cs
*
* 2013-11-06
* Blastom
* 2018-01-10
*
*
* SkillCore仅用于处理技能动画和特效等表现
* Obj_MainPlayer中
* - Blastom
*********************************************************************************/
using Games.AnimationModule;
using Games.GlobeDefine;
using Games.LogicObj;
using Games.Scene;
using GCGame.Table;
using UnityEngine;
namespace Games.SkillModle
{
public class SkillCore
{
// 最大技能缓存时间,超过该时间会抛弃这个技能
private const float _maxSkillCacheTime = 1f;
// SkillCore相当于Obj_Character的一个附件肯定和Obj共存亡
private readonly Obj_Character _owner;
private Vector2 _cachedFacePoint;
private Tab_SkillEx _cachedSkill;
// 模型加载前就在播放的技能 - 记录时间以判定是否超时
// 实际模型加载完成后,角色位置和面向可能有差错
private float _cachedSkillTime;
private bool _cachedSkipWindup;
private int _cachedTargetId;
// 技能是否处于播放阶段 - CurrentSkill 等参数需要缓存,因此不能用参数判断是否播放
private bool _isPlaying;
public SkillCore(Obj_Character owner)
{
_owner = owner;
}
// 当前正在使用的技能
public Tab_SkillEx CurrentSkill { get; private set; }
// 当前正在使用的技能BaseInfo
public Tab_SkillBase CurrentSkillBase { get; private set; }
// 当前技能开始时间
public float CurrentSkillTime { get; private set; }
// 是否播放技能效果 - 不作为是否能够使用技能的判定
// 其他组件无论先后顺序,都会在同一帧检测到技能释放结束
public bool IsUsingSkill
{
get
{
return _isPlaying && CurrentSkillTime + Obj_Character.SkillDuration(CurrentSkill, CurrentSkillBase) >
Time.time;
}
}
/// <summary>
/// 释放一个技能
/// </summary>
public bool UseSkill(Tab_SkillEx skillEx, Tab_SkillBase skillBase, int targetId, Vector3 facePoint,
bool skipWindup = false)
{
var result = false;
if (_isPlaying)
EndSkillByBaseId();
// 按原来逻辑,使用动画机检查技能是否应该缓存
if (_owner.AnimLogic == null || !_owner.AnimLogic.AnimPlayable())
{
_cachedSkillTime = Time.time;
_cachedSkill = skillEx;
_cachedTargetId = targetId;
_cachedFacePoint = facePoint;
_cachedSkipWindup = skipWindup;
}
else
{
result = true;
_isPlaying = true;
ClearCacheSkill();
var previousSkill = CurrentSkill;
CurrentSkill = skillEx;
CurrentSkillBase = skillBase;
CurrentSkillTime = Time.time;
// Hack普攻跳过动画的情况直接视为技能提前开始
var animSkipTime = skipWindup ? CurrentSkill.CradleTime.ToClientTime() : 0f;
CurrentSkillTime -= animSkipTime;
// 不允许移动的技能停止角色移动
if (CurrentSkillBase.IsMove < 1 || CurrentSkillBase.IsMoveBreak > 0)
_owner.StopMove();
var targetObjCharacter = Singleton<ObjManager>.GetInstance().FindObjCharacterInScene(targetId);
if (!_owner.IsBindFace())
if (targetObjCharacter == null || targetObjCharacter == _owner)
_owner.FaceTo(facePoint);
else if (targetObjCharacter.ServerID != _owner.ServerID)
_owner.FaceTo(targetObjCharacter.Position);
// 开始播放动画
// 跳过其他人释放陷阱的动画,外加强制显示播放动画的人
var playAnim = true;
if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER)
if (CurrentSkillBase.Id == (int) SKILLBASEID.HDWLID)
playAnim = false;
else
ToggleShowBySkill(true);
if (playAnim)
{
var transitionName = animSkipTime > 0 && previousSkill != null &&
previousSkill.NextSkillId == CurrentSkill.SkillExID
? AnimationLogic.GetTransitionName(previousSkill.SatrtMotionId, CurrentSkill.SatrtMotionId)
: string.Empty;
_owner.AnimLogic.Play(CurrentSkill.SatrtMotionId, transitionName);
}
//子弹播放
var bulletCount = CurrentSkill.getBulletEffectIDCount();
for (var i = 0; i < bulletCount; i++)
{
var bullectId = CurrentSkill.GetBulletEffectIDbyIndex(i);
if (bullectId > -1)
IndependentEffectManager.Instance.ShowBullet(bullectId, _owner.ServerID, targetId,
_owner.gameObject.layer, _owner.ObjType);
else
break;
}
// 显示技能名称
if (CurrentSkillBase.IsShowSkillName > 0)
DisplaySkillName(CurrentSkillBase, string.Empty);
if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER)
if (skillBase.SkillClass.ContainFlag((int) SKILLCLASS.DUTIAO))
{
//吟唱时间为当前动作的长度
var fYinChangTime = skillEx.YinChangTime.ToClientTime();
SkillProgressLogic.PlayProcess(SkillProgressLogic.ProgressModel.REVERSEDMODE, fYinChangTime,
skillBase.Name,
skillEx.SkillExID);
}
else if (skillBase.UseType.ContainFlag((int) SKILLUSETYPE.YINCHANG))
{
//吟唱时间为当前动作的长度
var fYinChangTime = skillEx.YinChangTime.ToClientTime();
SkillProgressLogic.PlayProcess(SkillProgressLogic.ProgressModel.ORDERMODEL, fYinChangTime,
skillBase.Name,
skillEx.SkillExID);
}
// 被攻击者是主角时,主角宠物试图攻击攻击者
if (targetObjCharacter != null &&
targetObjCharacter.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER)
{
var mainPlayer = targetObjCharacter.TryCastToType<Obj_MainPlayer>();
if (mainPlayer != null)
{
int threadValue;
if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER)
threadValue = 1000;
else if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_FELLOW)
threadValue = 100;
else
threadValue = 1;
mainPlayer.Controller.ThreadInfo.AddThreat(_owner, threadValue);
}
}
// 摄像机效果
CameraOpt(true);
_owner.OnSwithObjAnimState(GameDefine_Globe.OBJ_ANIMSTATE.STATE_SKILL);
// 显示技能警告
if (skillEx.WarningText > 0)
{
var warningContent = TableManager.GetStrDictionaryByID(skillEx.WarningText, 0);
var warningStart = Mathf.Max(0f, skillEx.WarningStart.ToClientTime());
var warningDuration = (skillEx.WarningDuration > 0f
? skillEx.WarningDuration
: skillEx.SkillContinueTime).ToClientTime();
CentreNoticeLogic.ShowSkillWarning(warningContent.StrDictionary, warningStart, warningDuration);
}
}
return result;
}
public void UserCacheSkill()
{
if (_cachedSkill != null)
if (_cachedSkillTime + _maxSkillCacheTime > Time.time)
{
var skillBase =
CommonUtility.TryGetTable(_cachedSkill.BaseId, a => TableManager.GetSkillBaseByID(a, 0));
if (skillBase != null)
UseSkill(_cachedSkill, skillBase, _cachedTargetId, _cachedFacePoint, _cachedSkipWindup);
else
ClearCacheSkill();
}
else
{
ClearCacheSkill();
}
}
private void ClearCacheSkill()
{
_cachedSkill = null;
}
public void UpdateSkill()
{
if (_isPlaying && !IsUsingSkill)
EndSkillByBaseId();
}
public void EndSkillByBaseId(int baseId = -1)
{
if (_isPlaying && (baseId < 0 || CurrentSkill.BaseId == baseId))
{
ClearCacheSkill();
CameraOpt(false);
_owner.EnableMovingRotation(true);
// 如果技能动画是循环动画需要切换到Idle动画
if (CurrentSkill.SatrtMotionId > -1)
{
var idleId = _owner.GetIdleAnimId();
if (_owner.AnimLogic != null)
_owner.AnimLogic.SwitchLoopToIdle(CurrentSkill.SatrtMotionId, idleId);
}
if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER ||
_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER)
{
var player = _owner as Obj_OtherPlayer;
if (null != player)
player.UpdateVisualAfterSkill();
}
//如果需要在技能结束的时候 停止对应的特效 则停止
if (CurrentSkillBase.IsNeedStopEffectId > -1)
_owner.StopEffect(CurrentSkillBase.IsNeedStopEffectId);
if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER)
ToggleShowBySkill(false);
// 处理吟唱技能进度条
else if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER)
SkillProgressLogic.StopProcess(CurrentSkill.SkillExID);
_isPlaying = false;
}
}
// 控制摄像头 createInstance
private void CameraOpt(bool isStart)
{
if (SceneLogic.CameraController != null)
{
if (CurrentSkill.CameraRockId > -1)
if (isStart)
{
var priority = _owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER ? 1 : 0;
if (CurrentSkill.CameraRockRate > Random.Range(0, 100))
SceneLogic.CameraController.StartCameraRock(CurrentSkill.CameraRockId, _owner, priority);
}
else
{
SceneLogic.CameraController.StopCameraRock(CurrentSkill.CameraRockId, _owner.ServerID);
}
//XP技能拉高摄像机视角
if (CurrentSkillBase.Id == (int) SKILLBASEID.YGSDID ||
CurrentSkillBase.SkillClass.ContainFlag((int) SKILLCLASS.XP))
SceneLogic.CameraController.FoVOverride = isStart ? 1.0f : -1.0f;
}
}
// 动画机缓存无法解决特效问题,因此还是需要强制显示
private void ToggleShowBySkill(bool isStart)
{
if (!_owner.ModelInViewPort)
if (isStart)
_owner.BecameVisible();
else
_owner.BecameInvisible();
}
private void DisplaySkillName(Tab_SkillBase skillBase, string skillName)
{
if (string.IsNullOrEmpty(skillName))
{
if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER)
_owner.ShowDamageBoard_SkillName(GameDefine_Globe.DAMAGEBOARD_TYPE.SKILL_NAME, skillBase.Name);
else if (_owner.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_NPC)
_owner.ShowDamageBoard_SkillName(GameDefine_Globe.DAMAGEBOARD_TYPE.SKILL_NAME_NPC, skillBase.Name,
false);
else if (_owner.ObjType != GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER)
_owner.ShowDamageBoard_SkillName(GameDefine_Globe.DAMAGEBOARD_TYPE.SKILL_NAME, skillBase.Name,
false);
}
else
{
_owner.ShowDamageBoard_SkillName(GameDefine_Globe.DAMAGEBOARD_TYPE.SKILL_NAME, skillName, false);
}
}
//显示技能名字
public static void ShowSkillName(int skillId, int senderId, string skillName)
{
var skillSender = Singleton<ObjManager>.GetInstance().FindObjCharacterInScene(senderId);
if (skillSender != null)
{
var skillEx = TableManager.GetSkillExByID(skillId, 0);
Tab_SkillBase skillBase = null;
if (skillEx != null)
skillBase = TableManager.GetSkillBaseByID(skillEx.BaseId, 0);
if (skillBase != null && skillSender.SkillCore != null)
skillSender.SkillCore.DisplaySkillName(skillBase, skillName);
}
}
}
}