You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

618 lines
28 KiB

using System;
using System.Collections.Generic;
using GAS.Runtime;
using Sog;
using UnityEngine;
using xFrame;
namespace CoreGame.Render
{
public static class BulletSrv
{
private static List<ElementType> s_RandomElementTypes = new List<ElementType>
{
ElementType.Fire,
ElementType.Toxic,
ElementType.Thunder
};
// 追踪弹可能需要一个目标列表
public static CombatEntity[] CreateBulletWithEntity(GameAbilityContext ctx, int bulletId)
{
return null;
}
public static CombatEntity[] CreateBulletWithPoint(GameAbilityContext casterGaCtx, int bulletId,
Fixed64 rotateAngle, bool randomElementType = false)
{
// 发射者死亡,不发射
var casterEid = casterGaCtx.ownerEnt.creationIndex;
var ownerEnt = casterGaCtx.ownerEnt;
if (ownerEnt.IsValid() == false)
return null;
if (ownerEnt.hasBullet)
casterEid = ownerEnt.bullet.casterEid;
else if(ownerEnt.hasZone)
casterEid = ownerEnt.zone.casterEid;
var caster = Contexts.Combat.GetEntity(casterEid);
if (caster.IsValid() == false)
return null;
var casterProp = caster.property.container;
var level = casterGaCtx.level;
var gaInitCfg = casterGaCtx.abilitySpec.gaInitCfg;
TraceLog.Assert(casterGaCtx.castPos.Count > 0,
$"{casterGaCtx.abilitySpec.Ability.Name} CreateBulletWithPoint castPos.Count == 0");
// 释放位置外部已经选好了,必须有
var targetPos = TargetSelectSrv.GetCastTargetPos(casterGaCtx);
var eid = casterGaCtx.castTarget.Count > 0 ? casterGaCtx.castTarget[0] : -1;
var targetEnt = Contexts.Combat.GetEntity(eid);
var tbBullet = BulletDescMgr.Instance.GetConfig(bulletId);
if (tbBullet == null)
return null;
var bulletCount = (int)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.bulletsAmount, casterProp,
level, gaInitCfg, 3f);
var existTime = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.duration, casterProp, level,
gaInitCfg, 3f);
var maxDistance = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.maxDistance, casterProp,
level, gaInitCfg, 5f);
var collisionTimes = (int)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.collisionTimes, casterProp,
level, gaInitCfg, 1f);
var collisionInterval = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.collisionInterval,
casterProp, level, gaInitCfg, 1f);
var scale = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.scale, casterProp, level,
gaInitCfg, 1f);
var bounceTimes = (int)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.bounceTimes, casterProp, level,
gaInitCfg, 1f);
var bulletEntities = new CombatEntity[bulletCount];
var speed = 0f;
Fixed64 addAngle = 0;
Fixed64 nowAngle = 0;
var distance = 0f;
var maxRandomAngle = 0f;
var randomCurvePerpendicularControl = 0f;
var randomCurveParallelControl = 0f;
if (tbBullet.shootType == ShootType.Direct || tbBullet.shootType == ShootType.Curve)
{
maxRandomAngle = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.bulletRandomAngle,
casterProp, level, gaInitCfg);
speed = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.speed, casterProp, level,
gaInitCfg, 10f); //飞行速度
var bulletAngle = tbBullet.fireAngle * BattleConst.TenThousandReverse;
if (bulletAngle > 0 && bulletCount > 1)
{
var maxCastAngle = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.fireAngleMax,
casterProp, level, gaInitCfg);
var totalAngle = (bulletCount - 1) * bulletAngle;
if (totalAngle > maxCastAngle)
{
totalAngle = maxCastAngle;
bulletAngle = maxCastAngle / (bulletCount - 1);
}
nowAngle = -totalAngle * Fixed64._0_50 + rotateAngle;
addAngle = bulletAngle;
}
else
{
nowAngle = rotateAngle;
}
if (tbBullet.shootType == ShootType.Curve)
{
randomCurvePerpendicularControl = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(
tbBullet.moveParam1, casterProp, level, gaInitCfg, -1f);
randomCurveParallelControl = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(
tbBullet.moveParam2, casterProp, level, gaInitCfg, -1f);
}
}
else if (tbBullet.shootType == ShootType.Surround)
{
speed = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.moveParam1, casterProp, level,
gaInitCfg, 180f); //角速度
distance = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.moveParam2, casterProp,
level, gaInitCfg, 2f);
addAngle = 360f / bulletCount;
if (targetEnt == null)
return null;
}
var element = ElementType.None;
var fromType = BulletFromType.None;
if (casterGaCtx.gunEid > 0)
{
var gun = Contexts.Combat.GetEntity(casterGaCtx.gunEid);
if (gun != null)
{
var gunGunData = gun.gunData;
if (gunGunData != null)
{
var gunCfg = WeaponDescMgr.Instance.GetConfig(gunGunData.gunCfgId);
element = gunGunData.elementType;
fromType = (BulletFromType)((int)gunCfg.Type << 2 + 1);
}
}
}
for (var i = 0; i < bulletCount; i++)
{
var cb = CreateBulletEntity(caster, element, fromType, tbBullet, existTime, maxDistance, collisionTimes,
collisionInterval, scale, speed, randomElementType);
// 传递技能参数
cb.AddGaCtxTransfer(casterGaCtx.abilitySpec.gaParams, casterGaCtx.abilitySpec.gaInitCfg,
casterGaCtx.level);
cb.AddLogicTransform(Fixed64Vector2.zero, Fixed64Vector2.one,Fixed64Vector2.right);
// cb.AddTransformProxy(Vector2.zero, Vector2.right, cb);
if (tbBullet.shootType == ShootType.Direct)
{
AddDirectBullet(ownerEnt, cb, targetPos, nowAngle, maxRandomAngle);
nowAngle += addAngle;
}
else if (tbBullet.shootType == ShootType.Surround)
{
AddSurroundBullet(targetEnt, cb, nowAngle, distance);
nowAngle += addAngle;
}
else if (tbBullet.shootType == ShootType.Curve)
{
// AddCurveBullet(ownerEnt, cb, targetPos, nowAngle, maxRandomAngle, tbBullet.warningPrefab,
// tbBullet.warningScale * BattleConst.TenThousandReverse, randomCurvePerpendicularControl,
// randomCurveParallelControl);
nowAngle += addAngle;
}
if (bounceTimes > 0)
{
var propertyComponent = cb.property;
propertyComponent.SetProperty(PropertyDef.BulletBounceCount, bounceTimes, true);
propertyComponent.SetProperty(PropertyDef.MaxBulletBounceCount, bounceTimes, true);
}
if (tbBullet.extraSkill > 0)
{
var context = AbilitySrv.GrantTransferAbility(cb, tbBullet.extraSkill, gaInitCfg, null, level);
if (context == null)
{
XLog.LogWarning("AttachActiveAbility failed: " + tbBullet.extraSkill);
}
}
// cb.LoadAsset();
bulletEntities[i] = cb;
}
caster.DispatchEvent(ClientEvent.OnShootBullets, bulletEntities);
return bulletEntities;
}
private static CombatEntity CreateBulletEntity(CombatEntity caster, ElementType element,
BulletFromType fromType, BulletDesc tbBullet, float existTime, float maxDistance, int collisionTimes,
float collisionInterval, float scale, float speed, bool randomElementType)
{
if (caster.IsValid() == false)
return null;
var cb = Contexts.Combat.CreateEntity();
if (randomElementType)
element = s_RandomElementTypes[RandomSrv.Range(0, s_RandomElementTypes.Count)];
var paramCount = tbBullet.colliderParam.Length;
var colliderParam1 =
paramCount > 0 ? tbBullet.colliderParam[0] * BattleConst.TenThousandReverse * scale : 0;
var colliderParam2 =
paramCount > 1 ? tbBullet.colliderParam[1] * BattleConst.TenThousandReverse * scale : 0;
if (tbBullet.skill == 0 && tbBullet.endSkill == 0)
{
XLog.LogError($"{tbBullet.bulletID} 子弹配置不对,没有技能!!!!");
}
cb.AddBullet(caster.creationIndex, element, fromType, tbBullet.bulletID, existTime, maxDistance, scale,
speed, tbBullet.colliderType, colliderParam1, colliderParam2, tbBullet.collideWith, collisionTimes,
collisionInterval, tbBullet.skill, tbBullet.endSkill, tbBullet.isTriggerHitSkillOnEnd != 0,
ListPool<HitData>.Pop());
var casterFaction = caster.faction;
cb.AddFaction(casterFaction.faction, SelectUseType.Bullet, casterFaction.opposite);
cb.AddProperty();
caster.property.TaskSnapShot(cb.property.container);
cb.property.SetProperty(PropertyDef.BulletFlyDistanceMax, maxDistance, true);
var ignore = ListPool<Type>.Pop();
ignore.Add(typeof(Animator));
var prefabPath = GetBulletPrefabPathByElementType(element, tbBullet);
cb.AddAsset(new MainAssetParam()
{
path = prefabPath,
parentNodeName = "RenderWorld",
scaleParam = scale
}, ignore);
cb.AddAudio(cb.creationIndex);
return cb;
}
/// <summary>
/// 发射直线子弹
/// </summary>
/// <param name="owner">创造者,可能是人,也可能是子弹等</param>
/// <param name="bullet">子弹实体</param>
/// <param name="target">目标实体</param>
/// <param name="nowAngle">偏转角度</param>
/// <param name="maxRandomAngle">最大随机偏转角度</param>
private static void AddDirectBullet(CombatEntity owner, CombatEntity bullet,
Fixed64Vector2 target, Fixed64 nowAngle, Fixed64 maxRandomAngle)
{
var randomAngle = maxRandomAngle * RandomSrv.Range(-1f, 1f);
GetFirePos(owner, bullet, out var pos, out var dir);
if (target != pos )
{
dir = target - pos;
dir.Normalize();
}
bullet.logicTransform.SetPosition(pos);
Fixed64 angleRadians = FixedMath.Deg2Rad * (nowAngle + randomAngle);
Fixed64 x = dir.x * FixedMath.Cos(angleRadians) - dir.y * FixedMath.Sin(angleRadians);
Fixed64 y = dir.x * FixedMath.Sin(angleRadians) + dir.y * FixedMath.Cos(angleRadians);
bullet.logicTransform.SetDirection(new Fixed64Vector2(x, y));
bullet.isDirectBullet = true;
}
/// <summary>
/// 发射环绕子弹
/// </summary>
/// <param name="targetEnt">环绕目标实体</param>
/// <param name="bullet">子弹实体</param>
/// <param name="nowAngle">角度</param>
/// <param name="distance">子弹和持有者的距离</param>
private static void AddSurroundBullet(CombatEntity targetEnt, CombatEntity bullet,
Fixed64 nowAngle, Fixed64 distance)
{
var transformProxy = bullet.logicTransform;
GetFirePos(targetEnt, bullet, out var pos, out var dir);
transformProxy.SetPosition(pos + Fixed64Vector2.right * distance);
bullet.AddSurroundBullet(targetEnt.creationIndex, distance);
bullet.surroundBullet.angle = nowAngle;
}
/// <summary>
/// 发射抛物线子弹
/// </summary>
/// <param name="owner">创造者,可能是人,也可能是子弹等</param>
/// <param name="bulletEnt">子弹实体</param>
/// <param name="targetPos">目标位置</param>
/// <param name="nowAngle">角度</param>
/// <param name="maxRandomAngle">最大随机偏转角度</param>
/// <param name="explosionRangePath">爆炸预警prefab路径</param>
/// <param name="explosionRangeScale">爆炸预警prefab大小</param>
/// <param name="randomCurvePerpendicularControl">垂直方向控制点随机参数</param>
/// <param name="randomCurveParallelControl">平行方向控制点随机参数</param>
private static void AddCurveBullet(CombatEntity owner, CombatEntity bulletEnt,
Fixed64Vector2 targetPos, Fixed64 nowAngle, Fixed64 maxRandomAngle, string explosionRangePath,
Fixed64 explosionRangeScale, Fixed64 randomCurvePerpendicularControl, Fixed64 randomCurveParallelControl)
{
Fixed64 randomAngle = maxRandomAngle * RandomSrv.Range(-1, 1);
// var start = caster.transformProxy.position;
// var dir = caster.transformProxy.direction;
GetFirePos(owner, bulletEnt, out var start, out var dir);
Fixed64 distance = 3;
if (targetPos != start)
{
dir = targetPos - start;
distance = dir.Magnitude;
}
var totalFlyTime = distance / bulletEnt.bullet.speed;
bulletEnt.logicTransform.SetDirection(Fixed64Vector2.up);
bulletEnt.logicTransform.SetPosition(start);
var angleRadians = FixedMath.Deg2Rad * (nowAngle + randomAngle);
var x = dir.x * FixedMath.Cos(angleRadians) - dir.y * FixedMath.Sin(angleRadians);
var y = dir.x * FixedMath.Sin(angleRadians) + dir.y * FixedMath.Cos(angleRadians);
var startToEnd = new Fixed64Vector2(x, y);
var end = startToEnd + start;
// Vector2 control;
// if (randomCurvePerpendicularControl > 0f)
// {
// Fixed64Vector2 parallel = startToEnd.Normalize();
// var perpendicular = new Fixed64Vector2(-parallel.y, parallel.x);
// var parallelDisRate = 0.5f;
// if (randomCurveParallelControl > 0f)
// {
// parallelDisRate = RandomSrv.Range(0, randomCurveParallelControl);
// }
// var perpendicularDis = RandomSrv.Range(-randomCurvePerpendicularControl, randomCurvePerpendicularControl);
// control = start + parallel * (distance * parallelDisRate) + perpendicular * perpendicularDis;
// }
// else
// {
// var halfPoint = (start + end) / 2f;
// control = distance * BattleConst.CurveBulletControlParam * Vector2.up + halfPoint;
// }
// var explosionRangeEid = 0;
// if (string.IsNullOrEmpty(explosionRangePath) == false && explosionRangeScale > 0)
// {
// var explosionRangeEnt = Contexts.Combat.CreateEntity("ExplosionRange_" + bulletEnt.creationIndex);
// explosionRangeEnt.AddTransformProxy(targetPos, Vector2.right, explosionRangeEnt);
// explosionRangeEnt.AddAsset(new MainAssetParam()
// {
// path = explosionRangePath,
// parentNodeName = "RenderWorld",
// scaleParam = explosionRangeScale
// }, null);
// explosionRangeEid = explosionRangeEnt.creationIndex;
// }
// bulletEnt.AddCurveBullet(start, end, control, explosionRangeEid, totalFlyTime);
}
private static void DestroyInvalidBulletFromSpec(AbilitySpec abilitySpec)
{
var ctxOwnerEnt = abilitySpec.ctx.ownerEnt;
var bullet = ctxOwnerEnt.bullet;
// var orDefault = TDRoot.Tables.Bullet.GetOrDefault(1);
if (bullet == null)
{
XLog.LogDebug("DestroyBulletFromSpec bullet == null");
return;
}
if (bullet.hasInvalidated == false)
{
XLog.LogDebug("DestroyBulletFromSpec bullet not invalidated");
return;
}
bullet.invalidatedCount--;
if (bullet.invalidatedCount <= 0)
{
DestroyBullet(ctxOwnerEnt);
}
}
public static void DestroyBullet(CombatEntity bullet)
{
bullet.isDestroyEnt = true;
}
public static void InvalidateBullet(CombatEntity bullet)
{
if (bullet.hasBullet == false)
{
XLog.LogDebug("InvalidateBullet bullet.hasBullet == false");
return;
}
bullet.asset?.HideMainAsset(); // 隐藏模型, 但不销毁
bullet.isDirectBullet = false;
bullet.RemoveSurroundBullet();
bullet.RemoveCurveBullet();
bullet.bullet.hasInvalidated = true;
}
private static string GetBulletPrefabPathByElementType(ElementType elementType, BulletDesc tbBullet)
{
var prefabPath = tbBullet.prefab;
if (elementType == ElementType.Fire && !string.IsNullOrEmpty(tbBullet.firePrefab))
prefabPath = tbBullet.firePrefab;
else if (elementType == ElementType.Toxic && !string.IsNullOrEmpty(tbBullet.toxicPrefab))
prefabPath = tbBullet.toxicPrefab;
else if (elementType == ElementType.Thunder && !string.IsNullOrEmpty(tbBullet.thunderPrefab))
prefabPath = tbBullet.thunderPrefab;
return prefabPath;
}
private static void GetFirePos(CombatEntity owner, CombatEntity bullet, out Fixed64Vector2 pos, out Fixed64Vector2 dir)
{
var tp = owner.logicTransform;
pos = tp.position;
dir = tp.forward;
// pos = tp.position;
// dir = tp.direction;
// var bulletCfgId = bullet.bullet.bulletCfgId;
// var bulletCfg = BulletDescMgr.Instance.GetConfig(bulletCfgId);
// var bindPoint = owner.bindPointProxy;
// if (bindPoint == null)
// return;
// if (bindPoint.TryGetBindPointOrDefault(bulletCfg.bornPoint, out var point))
// {
// pos = point.position;
// // dir = point.right;
// }
}
public static CombatEntity CreateBounceBullet(CombatEntity caster, GameAbilityContext middleGaCtx,
int newBulletId = 0)
{
var originEnt = middleGaCtx.ownerEnt;
if (originEnt.hasBullet == false)
{
XLog.LogDebug("CreateBounceBullet originEnt is not a bullet");
return null;
}
var originBullet = originEnt.bullet;
if (caster.IsValid() == false)
return null;
if (newBulletId == 0)
newBulletId = originBullet.bulletCfgId;
var tbBullet = BulletDescMgr.Instance.GetConfig(newBulletId);
// 释放位置外部已经选好了,必须有
var targetPos = TargetSelectSrv.GetCastTargetPos(middleGaCtx);
var bullet = Contexts.Combat.CreateEntity();
var casterProp = caster.property.container;
var level = middleGaCtx.level;
var gaInitCfg = middleGaCtx.abilitySpec.gaInitCfg;
var existTime = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.duration, casterProp, level,
gaInitCfg, 3f);
var maxDistance = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.maxDistance, casterProp,
level, gaInitCfg, 5f);
var scale = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.scale, casterProp, level,
gaInitCfg, 1f);
var speed = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.speed, casterProp, level,
gaInitCfg, 10f);
var paramCount = tbBullet.colliderParam.Length;
var colliderParam1 =
paramCount > 0 ? tbBullet.colliderParam[0] * BattleConst.TenThousandReverse * scale : 0f;
var colliderParam2 =
paramCount > 1 ? tbBullet.colliderParam[1] * BattleConst.TenThousandReverse * scale : 0f;
var collisionTimes = (int)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.collisionTimes, casterProp,
level, gaInitCfg, 1f);
var collisionInterval = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(tbBullet.collisionInterval,
casterProp, level, gaInitCfg, 1f);
if (tbBullet.skill == 0 && tbBullet.endSkill == 0)
{
XLog.LogError($"{tbBullet.bulletID} 子弹配置不对,没有技能!!!!");
}
bullet.AddBullet(originBullet.casterEid, originBullet.elementType, originBullet.bulletFromType,
tbBullet.bulletID, existTime, maxDistance, scale, speed, tbBullet.colliderType, colliderParam1,
colliderParam2, tbBullet.collideWith, collisionTimes, collisionInterval, tbBullet.skill,
tbBullet.endSkill, tbBullet.isTriggerHitSkillOnEnd != 0, ListPool<HitData>.Pop());
bullet.AddGaCtxTransfer(middleGaCtx.abilitySpec.gaParams, middleGaCtx.abilitySpec.gaInitCfg,
middleGaCtx.level);
bullet.AddFaction(caster.faction.faction, SelectUseType.Bullet, caster.faction.opposite);
bullet.AddProperty();
caster.property.TaskSnapShot(bullet.property.container);
bullet.property.SetProperty(PropertyDef.BulletFlyDistanceMax, maxDistance, true);
var ignore = ListPool<Type>.Pop();
ignore.Add(typeof(Animator));
var prefabPath = GetBulletPrefabPathByElementType(originBullet.elementType, tbBullet);
bullet.AddAsset(new MainAssetParam
{
path = prefabPath,
parentNodeName = "RenderWorld",
scaleParam = scale
}, ignore);
bullet.AddAudio(bullet.creationIndex);
bullet.AddTransformProxy(Vector2.zero, Vector2.right, bullet);
if (tbBullet.shootType == ShootType.Direct)
{
AddDirectBullet(originEnt, bullet, targetPos, 0f, 0f);
}
else if (tbBullet.shootType == ShootType.Surround)
{
XLog.LogDebug("CreateBounceBullet surround bullet not supported");
return null;
}
else if (tbBullet.shootType == ShootType.Curve)
{
var randomCurvePerpendicularControl = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(
tbBullet.moveParam1, casterProp, level, gaInitCfg, -1f);
var randomCurveParallelControl = (float)ExpressionEvaluator.CalcVal_WithPropAndGaCfg(
tbBullet.moveParam2, casterProp, level, gaInitCfg, -1f);
AddCurveBullet(originEnt, bullet, targetPos, 0f, 0f, tbBullet.warningPrefab,
tbBullet.warningScale * BattleConst.TenThousandReverse, randomCurvePerpendicularControl,
randomCurveParallelControl);
}
foreach (var filterEid in middleGaCtx.filterEids)
{
var hitData = SptPool<HitData>.Malloc();
hitData.Awake(filterEid, 0f, bullet.transformProxy.position,
bullet.transformProxy.direction);
bullet.bullet.hitDatas.Add(hitData);
}
return bullet;
}
public static bool CanCast(GameAbilityContext ctx, string canCastExpr, float defval = 1f)
{
if (string.IsNullOrEmpty(canCastExpr))
{
return true;
}
var casterEid = ctx.ownerEnt.creationIndex;
var ownerEnt = ctx.ownerEnt;
if (ownerEnt.IsValid() == false)
return false;
if (ownerEnt.hasBullet)
casterEid = ownerEnt.bullet.casterEid;
var caster = Contexts.Combat.GetEntity(casterEid);
if (caster.IsValid() == false)
return false;
var casterProp = caster.property.container;
var level = ctx.level;
var gaInitCfg = ctx.abilitySpec.gaInitCfg;
var castRate =
ExpressionEvaluator.CalcVal_WithPropAndGaCfg(canCastExpr, casterProp, level, gaInitCfg, defval);
if (RandomSrv.Range(0f, 1f) > castRate)
{
return false;
}
return true;
}
public static void BulletSkillCast(CombatEntity bulletEnt, int targetEid, Fixed64Vector2 targetPos, int abilityId)
{
if (!bulletEnt.hasBullet || bulletEnt.isDestroyEnt)
return;
var bullet = bulletEnt.bullet;
var gaCtxTransfer = bulletEnt.gaCtxTransfer;
// 不给他不行,发射者死亡的话,子弹也要有伤害
var context = AbilitySrv.GrantTransferAbility(bulletEnt, abilityId, gaCtxTransfer.gaInitCfg, null,
gaCtxTransfer.level);
if (context == null)
{
XLog.LogDebug("AttachActiveAbility failed: " + abilityId);
return;
}
if (targetEid != 0)
{
var targetEnt = Contexts.Combat.GetEntity(targetEid);
// 子弹释放的目标, 具体作用对象由子弹技能的 catchTarget 来决定
if (targetEnt.isObstacle)
{
context.castPos.Add(bulletEnt.logicTransform.position);
}
else
{
context.castTarget.Add(targetEnt.creationIndex);
context.castPos.Add(targetEnt.logicTransform.position);
}
}
else
{
// context.castPos.Add(targetPos);
}
ref var gaParam = ref gaCtxTransfer.gaParams;
gaParam.SetParam1Int(targetEid);
BulletTryRegisterEndAbility(bullet, context);
context.dropAbilityWhenEnd = true; //TDRoot.Tables.Skill[abilityId].DropAbillity;
context.AddHitDataByRefs(bullet.hitDatas);
// XLog.LogDebug("bullet skill cast: " + abilityId + " " + context.abilitySpec.Ability.Name + " " + entity);
context.asc.TryActivateAbility_WithSeqAndParam(context.gaSeq, gaParam);
// 是否是枪械发出的子弹
int bulletFirstType = (int)bullet.bulletFromType & 0b11;
if (bulletFirstType == 1)
{
}
}
private static void BulletTryRegisterEndAbility(BulletComponent bullet, GameAbilityContext context)
{
if (bullet.hasInvalidated)
{
bullet.invalidatedCount++;
context.abilitySpec.RegisterEndAbility(DestroyInvalidBulletFromSpec);
}
}
}
}