392 lines
16 KiB
C#
392 lines
16 KiB
C#
using System.Collections.Generic;
|
|
using cfg.SkillCfg;
|
|
using Gameplay.Area;
|
|
using Gameplay.Character.Skill;
|
|
using Gameplay.Common;
|
|
using Gameplay.Effect;
|
|
using Gameplay.Level;
|
|
using Gameplay.Pool;
|
|
using Gameplay.Skill;
|
|
using Gameplay.Unit;
|
|
using Gameplay.Vehicle.Impl;
|
|
using PhxhSDK;
|
|
using UnityEngine;
|
|
using Constants = Framework.Constants;
|
|
namespace Gameplay.Character.Helper
|
|
{
|
|
public static class CharacterSkillHelper
|
|
{
|
|
|
|
/// <summary>
|
|
/// 随机选择指定个数目标
|
|
/// 当数量不满足时,返回全部目标
|
|
/// </summary>
|
|
/// <param name="allTargets"></param>
|
|
/// <param name="count"></param>
|
|
/// <returns></returns>
|
|
private static List<GameUnit> _RandomSelectTargets(List<GameUnit> allTargets,
|
|
int count)
|
|
{
|
|
if (allTargets.Count <= count)
|
|
{
|
|
return allTargets;
|
|
}
|
|
var result = PhxhSDK.Utils.GetRandomElementFromList(allTargets, count);
|
|
return result;
|
|
}
|
|
|
|
private static List<GameUnit> _RandomSelectNoFullHpTargets(List<GameUnit> allTargets,
|
|
int count)
|
|
{
|
|
if (allTargets.Count <= count)
|
|
{
|
|
return allTargets;
|
|
}
|
|
|
|
var noFullHpTargets = new List<GameUnit>();
|
|
var fullHpTargets = new List<GameUnit>();
|
|
foreach (var target in allTargets)
|
|
{
|
|
if (target.aliveData.currentHp < target.aliveData.maxHp)
|
|
{
|
|
noFullHpTargets.Add(target);
|
|
}
|
|
else
|
|
{
|
|
fullHpTargets.Add(target);
|
|
}
|
|
}
|
|
if (noFullHpTargets.Count >= count)
|
|
{
|
|
return _RandomSelectTargets(noFullHpTargets, count);
|
|
}
|
|
|
|
var remainCount = count - noFullHpTargets.Count;
|
|
if (fullHpTargets.Count >= remainCount)
|
|
{
|
|
var remainTargets = _RandomSelectTargets(fullHpTargets, remainCount);
|
|
noFullHpTargets.AddRange(remainTargets);
|
|
return noFullHpTargets;
|
|
}
|
|
|
|
// 理论上不会走到这里
|
|
return allTargets;
|
|
}
|
|
|
|
public static List<GameUnit> RandomSelectTargets(List<GameUnit> allTargets,
|
|
int count,
|
|
ETargetPrefer preferType)
|
|
{
|
|
switch (preferType)
|
|
{
|
|
case ETargetPrefer.None:
|
|
return _RandomSelectTargets(allTargets, count);
|
|
case ETargetPrefer.PreferNoFullHp:
|
|
return _RandomSelectNoFullHpTargets(allTargets, count);
|
|
default:
|
|
DebugUtil.LogError("暂未处理的目标优先类型: {0}", preferType);
|
|
return new List<GameUnit>();
|
|
}
|
|
}
|
|
|
|
public static void PlayEffect(CharacterSkillAction skillAction)
|
|
{
|
|
var owner = skillAction.skill.GetOwner();
|
|
switch (skillAction.actionData.subId)
|
|
{
|
|
case ESkillEffectPosType.SelfLocal:
|
|
_PlayLocalEffect(skillAction);
|
|
break;
|
|
case ESkillEffectPosType.TargetLocal:
|
|
_PlayTargetEffect(skillAction);
|
|
break;
|
|
case ESkillEffectPosType.WeaponFire:
|
|
_PlayWeaponFireEffect(skillAction);
|
|
break;
|
|
case ESkillEffectPosType.WeaponFireFly2Target:
|
|
{
|
|
Vector3 startPos = owner.Node.GameObject.transform.position;
|
|
if (owner is Character c)
|
|
{
|
|
var weapon = c.weapon;
|
|
startPos = weapon.fireTrans.position;
|
|
} else if (owner is NormalVehicle v)
|
|
{
|
|
var weapon = v.battery;
|
|
startPos = weapon.fireTrans.position;
|
|
}
|
|
_PlayStartPosFly2TargetEffect(skillAction, startPos);
|
|
}
|
|
break;
|
|
case ESkillEffectPosType.LeftHand2Target:
|
|
{
|
|
Vector3 startPos = owner.Node.GameObject.transform.position;
|
|
if (owner is Character c)
|
|
{
|
|
if (c.leftHandTrans != null)
|
|
{
|
|
startPos = c.leftHandTrans.position;
|
|
}
|
|
}
|
|
_PlayStartPosFly2TargetEffect(skillAction, startPos);
|
|
}
|
|
break;
|
|
case ESkillEffectPosType.RightHand2Target:
|
|
{
|
|
Vector3 startPos = owner.Node.GameObject.transform.position;
|
|
if (owner is Character c)
|
|
{
|
|
if (c.rightHandTrans != null)
|
|
{
|
|
startPos = c.rightHandTrans.position;
|
|
}
|
|
}
|
|
_PlayStartPosFly2TargetEffect(skillAction, startPos);
|
|
}
|
|
break;
|
|
default:
|
|
DebugUtil.LogError("无效的effectPlayType:{0}", skillAction.actionData.subId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static void _PlayLocalEffect(CharacterSkillAction skillAction)
|
|
{
|
|
var actionData = skillAction.actionData;
|
|
var effectId = actionData.id;
|
|
if (effectId > 0)
|
|
{
|
|
var skill = skillAction.skill;
|
|
var owner = skill.GetOwner();
|
|
var trans = owner.Node.GameObject.transform;
|
|
var effectData = EffectManager.instance.PlayEffectById(effectId, trans.position, trans.rotation, trans);
|
|
effectData.owner = owner;
|
|
if (owner.statusData.needSkillPaused)
|
|
{
|
|
SkillManager.instance.screenEffect.AttachObj(effectData.rootObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void _PlayWeaponFireEffect(CharacterSkillAction skillAction)
|
|
{
|
|
var actionData = skillAction.actionData;
|
|
var skill = skillAction.skill;
|
|
var effectId = actionData.id;
|
|
if (effectId <= 0) return;
|
|
var owner = skill.GetOwner();
|
|
if (owner is Character c)
|
|
{
|
|
var trans = owner.Node.GameObject.transform;
|
|
var weapon = c.weapon;
|
|
var effectData = EffectManager.instance.PlayEffectById(effectId, weapon.fireTrans.position, trans.rotation, weapon.fireTrans);
|
|
effectData.owner = owner;
|
|
if (owner.statusData.needSkillPaused)
|
|
{
|
|
SkillManager.instance.screenEffect.AttachObj(effectData.rootObj);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private static void _PlayTargetEffect(CharacterSkillAction skillAction)
|
|
{
|
|
var actionData = skillAction.actionData;
|
|
var skill = skillAction.skill;
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
var effectId = actionData.id;
|
|
if (effectId > 0)
|
|
{
|
|
// 获取area的cellIndexs
|
|
var owner = skill.GetOwner();
|
|
var skillHandle = skill.GetSkillHandle();
|
|
var releaseCellIndex = owner.controlData.skillCellIndex;
|
|
var configData = skillHandle.runtimeData.configData;
|
|
var areaId = configData.InfluenceAreaId;
|
|
skillAction.preSelectCellIndexs = AreaManager.instance.GetCellIndexs(releaseCellIndex, areaId);
|
|
|
|
for (var i = 0; i < skillAction.preSelectCellIndexs.Count; ++i)
|
|
{
|
|
var cellIndex = skillAction.preSelectCellIndexs[i];
|
|
var worldPos = map.TGSCellIndex2WorldPosition(cellIndex);
|
|
var effectData = EffectManager.instance.PlayEffectById(effectId, worldPos, Quaternion.identity);
|
|
|
|
effectData.owner = owner;
|
|
if (owner.statusData.needSkillPaused)
|
|
{
|
|
SkillManager.instance.screenEffect.AttachObj(effectData.rootObj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void _PlayStartPosFly2TargetEffect(CharacterSkillAction skillAction,
|
|
Vector3 startPos)
|
|
{
|
|
var actionData = skillAction.actionData;
|
|
var skill = skillAction.skill;
|
|
var effectId = actionData.id;
|
|
if (effectId <= 0) return;
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
// 获取area的cellIndexs
|
|
var owner = skill.GetOwner();
|
|
var releaseCellIndex = owner.controlData.skillCellIndex;
|
|
|
|
var trans = owner.Node.GameObject.transform;
|
|
|
|
var targetCellIndex = releaseCellIndex;
|
|
var targetPos = map.TGSCellIndex2WorldPosition(targetCellIndex);
|
|
|
|
var effectData = EffectManager.instance.PlayEffectById(effectId, startPos, trans.rotation);
|
|
if (DebugUtil.LogEnable)
|
|
DebugUtil.Log("startPos:{0}, targetPos:{1}, targetIndex:{2}", startPos, targetPos, targetCellIndex);
|
|
switch (actionData.intParam1)
|
|
{
|
|
case 0:
|
|
// 直线
|
|
var flyLogicLine = ObjPoolManager.instance.Get<BulletFlyLogic>();
|
|
flyLogicLine.Ctor(startPos, targetPos, actionData.floatParam1);
|
|
effectData.AddLogic(flyLogicLine);
|
|
break;
|
|
case 1:
|
|
// 抛物线
|
|
var flyLogicBessel = ObjPoolManager.instance.Get<BulletBesselFlyLogic>();
|
|
var midPosFixY = actionData.floatParam2;
|
|
var midposProgress = actionData.floatParam3;
|
|
var midPos = Vector3.Lerp(startPos, targetPos, midposProgress);
|
|
midPos.y += midPosFixY;
|
|
flyLogicBessel.Ctor(startPos, targetPos, midPos, actionData.floatParam1);
|
|
effectData.AddLogic(flyLogicBessel);
|
|
break;
|
|
}
|
|
|
|
effectData.owner = owner;
|
|
if (owner.statusData.needSkillPaused)
|
|
{
|
|
SkillManager.instance.screenEffect.AttachObj(effectData.rootObj);
|
|
}
|
|
|
|
}
|
|
|
|
public static void RotateToTargetEnemy(GameUnit owner,
|
|
GameUnit enemy)
|
|
{
|
|
var targetCellIndex = enemy.transData.cellIndex;
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
var targetPos = map.TGSCellIndex2WorldPosition(targetCellIndex);
|
|
var selfPos = owner.transData.pos;
|
|
var toTarget = targetPos - selfPos;
|
|
toTarget.y = 0;
|
|
var angle = Vector3.SignedAngle(Vector3.forward, toTarget, Vector3.up);
|
|
owner.transData.yaw = angle;
|
|
}
|
|
|
|
public static bool CheckNeedAddEmitCount(int skillActionType)
|
|
{
|
|
return skillActionType == ESkillActionType.EMIT_BULLET ||
|
|
skillActionType == ESkillActionType.EMIT_BULLET_SELECT ||
|
|
skillActionType == ESkillActionType.EMIT_BULLET_TO_SELF ||
|
|
skillActionType == ESkillActionType.EMIT_BULLET_TO_ATTACK_AREA
|
|
|| skillActionType == ESkillActionType.SPECIAL_EMIT_BULLET_1;
|
|
}
|
|
|
|
public static bool CheckNeedRebindId(int skillActionType)
|
|
{
|
|
return skillActionType == ESkillActionType.CREATE_SUMMON ||
|
|
skillActionType == ESkillActionType.MARK_UP_VEHICLE;
|
|
}
|
|
|
|
public static void RotateToTargetCell(GameUnit owner)
|
|
{
|
|
var targetCellIndex = owner.controlData.skillCellIndex;
|
|
if (targetCellIndex == owner.transData.cellIndex)
|
|
{
|
|
// 同一个格子,不做处理
|
|
return;
|
|
}
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
var targetPos = map.TGSCellIndex2WorldPosition(targetCellIndex);
|
|
var selfPos = owner.transData.pos;
|
|
var toTarget = targetPos - selfPos;
|
|
toTarget.y = 0;
|
|
var angle = Vector3.SignedAngle(Vector3.forward, toTarget, Vector3.up);
|
|
owner.transData.yaw = angle;
|
|
}
|
|
|
|
public static GameObject CreateSkillGroundHighLight(List<int> cellIndexs)
|
|
{
|
|
var fakeObj = new GameObject("SkillGroundHighLight");
|
|
for (int i = 0; i < cellIndexs.Count; i++)
|
|
{
|
|
var cellIndex = cellIndexs[i];
|
|
var worldPos = LevelManager.Instance.CurrentLevel.Map.TGSCellIndex2WorldPosition(cellIndex);
|
|
var sampleObj = AssetManager.Instance.GetPreLoadResult<GameObject>(PathDefine.SkillArea.SKILL_GORUND_HIGH_LIGHT);
|
|
var go = Object.Instantiate(sampleObj, worldPos, Quaternion.identity, fakeObj.transform);
|
|
go.SetLayerEx(LayerDefine.Skill);
|
|
}
|
|
return fakeObj;
|
|
}
|
|
|
|
public static CharacterSkillAction CreateAction(SkillLogicActionData actionData)
|
|
{
|
|
CharacterSkillAction action;
|
|
switch (actionData.actionType)
|
|
{
|
|
case ESkillActionType.PLAY_AUDIO:
|
|
action = new CSA_PlayAudio();
|
|
break;
|
|
case ESkillActionType.EMIT_BULLET:
|
|
action = new CSA_EmitBullet();
|
|
break;
|
|
case ESkillActionType.EMIT_BULLET_SELECT:
|
|
action = new CSA_EmitBulletSelect();
|
|
break;
|
|
case ESkillActionType.EMIT_BULLET_TO_SELF:
|
|
action = new CSA_EmitBulletToSelf();
|
|
break;
|
|
case ESkillActionType.EMIT_BULLET_TO_ATTACK_AREA:
|
|
action = new CSA_EmitBulletToAttackAread();
|
|
break;
|
|
case ESkillActionType.SPECIAL_EMIT_BULLET_1:
|
|
action = new CSA_SpecialEmitBullet01();
|
|
break;
|
|
case ESkillActionType.CREATE_SUMMON:
|
|
action = new CSA_CreateSummon();
|
|
break;
|
|
case ESkillActionType.SKILL_END:
|
|
action = new CSA_SkillEnd();
|
|
break;
|
|
case ESkillActionType.PAUSE_END:
|
|
action = new CSA_PauseEnd();
|
|
break;
|
|
case ESkillActionType.HIDE_WEAPON:
|
|
action = new CSA_HideWeapon();
|
|
break;
|
|
case ESkillActionType.SHOW_WEAPON:
|
|
action = new CSA_ShowWeapon();
|
|
break;
|
|
case ESkillActionType.PLAY_EFFECT:
|
|
action = new CSA_PlayEffect();
|
|
break;
|
|
case ESkillActionType.CHANGE_POS:
|
|
action = new CSA_ChangePos();
|
|
break;
|
|
case ESkillActionType.HIDE_RENDER:
|
|
action = new CSA_HideRender();
|
|
break;
|
|
case ESkillActionType.SHOW_RENDER:
|
|
action = new CSA_ShowRender();
|
|
break;
|
|
case ESkillActionType.MARK_UP_VEHICLE:
|
|
action = new CSA_MarkUpVehicle();
|
|
break;
|
|
default:
|
|
DebugUtil.LogError("暂未处理的actionType:" + actionData.actionType);
|
|
return null;
|
|
}
|
|
return action;
|
|
}
|
|
|
|
}
|
|
}
|