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.
349 lines
16 KiB
349 lines
16 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using AOT;
|
|
using GAS.Runtime;
|
|
using NavMeshPlus.Components;
|
|
using Sog;
|
|
using UnityEngine;
|
|
|
|
namespace CoreGame.Render
|
|
{
|
|
/// <summary>
|
|
/// 创建实体的服务,虽然没有英雄,怪物等概念,但实际是需要有,
|
|
/// TODO: 逻辑表现的实体ID要一直
|
|
/// </summary>
|
|
public static class EntityCreateSrv
|
|
{
|
|
public static void CreateBattleTeam()
|
|
{
|
|
// 创建英雄
|
|
var heroEntity = CreateHeroEntity(Contexts.Combat, CoreUIBridge.BattleInfoParams.heroSkinId);
|
|
heroEntity.transformProxy.SetPosition(CoreUIBridge.BattleInfoParams.playerBronPosition);
|
|
heroEntity.transformProxy.SetDirection(Vector3.right);
|
|
// heroEntity.TagAggregator.AddFixedTag(GTagLib.State_CannotBeOppoCatch);
|
|
BattleModule.s_LocalPlayerEid = heroEntity.creationIndex;
|
|
#if UNITY_EDITOR
|
|
BattleSimulateData.AttachTest(heroEntity);
|
|
#endif
|
|
}
|
|
public static CombatEntity CreateHeroEntity(CombatContext context, int heroSkinId)
|
|
{
|
|
var showCfg = RoleModelDescMgr.Instance.GetConfig(heroSkinId);
|
|
var ce = context.CreateEntity("Hero" + heroSkinId);
|
|
PropertySrv.GetHeroBasePropValue(ce);
|
|
ce.AddCommandReceiver(ce);
|
|
ce.isHero = true;
|
|
ce.AddBlackboard(CfgType.HeroCfg, heroSkinId, new[] { heroSkinId }, Array.Empty<int>(), ce.creationIndex,
|
|
false);
|
|
ce.AddFaction(Faction.Player, SelectUseType.Actor);
|
|
ce.AddTransformProxy(Vector2.zero, Vector2.right, ce);
|
|
ce.AddAudio(ce.creationIndex);
|
|
AbilitySrv.AttachActiveAbilityGroup(CommParamDescMgr.Instance.RoleDefaultSki.int_val, ce);
|
|
ce.AddAsset(new MainAssetParam()
|
|
{
|
|
path = $"{showCfg.folderPath}/{showCfg.prefabAnim}.prefab",
|
|
parentNodeName = "RenderWorld",
|
|
scaleParam = 1,
|
|
}, null);
|
|
var subAssetData = SptPool<SubAssetData>.Malloc();
|
|
subAssetData.Awake(ce.creationIndex, CoreUIBridge.BattleInfoParams.wingPath, BindPointType.Wing, null);
|
|
ce.asset.PushMainPartAsset(ref subAssetData);
|
|
// ce.blackboard.SetBornPos(ce.logicTransform.position);
|
|
Contexts.Combat.localPlayerEid = ce.creationIndex;
|
|
ce.isLocalPlayer = true;
|
|
ce.isAttractor = true;
|
|
ce.AddEquips(ce);
|
|
ce.equips.SwitchSlotNoCheck(CoreUIBridge.BattleInfoParams.equipInfo.currentGunSlot);
|
|
GunSrv.DynamicEquipGun(ce, CoreUIBridge.BattleInfoParams.equipInfo);
|
|
return ce;
|
|
}
|
|
|
|
public static CombatEntity CreateCameraEntity(CombatContext context, string prefabPath)
|
|
{
|
|
var combatEntity = context.CreateEntity("VirtualCamera");
|
|
combatEntity.AddAsset(
|
|
new MainAssetParam()
|
|
{
|
|
path = prefabPath,
|
|
parentNodeName = "RenderWorld",
|
|
scaleParam = 1,
|
|
}, null);
|
|
// combatEntity.LoadAsset();
|
|
return combatEntity;
|
|
}
|
|
|
|
public static CombatEntity CreateJumpTextEntity(CombatContext context, object initData = null)
|
|
{
|
|
var combatEntity = context.SetJumpText(new Queue<HurtData>());
|
|
combatEntity.Name = "JumpText";
|
|
return combatEntity;
|
|
}
|
|
|
|
public static CombatEntity CreateJoystickEntity(CombatContext context, object initData = null)
|
|
{
|
|
var combatEntity = context.CreateEntity("JoystickEntity");
|
|
combatEntity.AddAsset(
|
|
new MainAssetParam()
|
|
{
|
|
path = "Model/Joystick",
|
|
parentNodeName = "UICanvas/GlobalWindowManager/JoyStick",
|
|
scaleParam = 1,
|
|
}, null);
|
|
// combatEntity.LoadAsset();
|
|
return combatEntity;
|
|
}
|
|
|
|
public static CombatEntity[] CreateObstacleEntities(CombatContext context, object initData = null)
|
|
{
|
|
const int componentIndex = CombatComponentsLookup.Collider2DProxy;
|
|
var modifiers = NavMeshModifier.activeModifiers;
|
|
var gameObject = new GameObject("ObstacleEntities_Logic");
|
|
var allObstacle = context.CreateEntity("ObstacleEntities_Logic");
|
|
allObstacle.isObstacle = true;
|
|
allObstacle.AddFaction(Faction.None, SelectUseType.Obstacle, Faction.None);
|
|
var proxy = (Collider2DProxy)allObstacle.CreateComponent(componentIndex,
|
|
CombatComponentsLookup.componentTypes[componentIndex]);
|
|
allObstacle.AddComponent(componentIndex, proxy);
|
|
allObstacle.AddTransformProxy(Vector2.zero, Vector2.right, allObstacle);
|
|
(proxy).Init(gameObject, allObstacle);
|
|
AbilitySrv.GrantBaseAbility(allObstacle);
|
|
allObstacle.TagCountContainer.UpdateTagCount(GTagLib.Entity_Obstacle, 1);
|
|
|
|
var fac = allObstacle.faction;
|
|
for (var i = 0; i < modifiers.Count; i++)
|
|
{
|
|
var modifier = modifiers[i];
|
|
if (modifier.TryGetComponent<Collider2D>(out var collider2D))
|
|
{
|
|
proxy.FillColliderByInit(collider2D, fac, true);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void CreateSummonEntities(GameAbilityContext ctx, int summonId)
|
|
{
|
|
var tbSummon = SummonDescMgr.Instance.GetConfig(summonId);
|
|
var summoner = ctx.ownerEnt;
|
|
var summonerFaction = summoner.faction;
|
|
var queryParam = new QueryParam
|
|
{
|
|
faction = summonerFaction.faction,
|
|
selectUseType = SelectUseType.Summon
|
|
};
|
|
|
|
var friendSummon = Contexts.Combat.GetEntitiesWithFactionCommonBeQueryParam(queryParam);
|
|
int existAmount = 0;
|
|
foreach (var ent in friendSummon)
|
|
{
|
|
if (ent.summon.summonId == summonId)
|
|
existAmount++;
|
|
}
|
|
|
|
var summonAmount = (float)ExpressionEvaluator.CalcVal_WithCtx(tbSummon.summonAmount, ctx, 2f);
|
|
var summonAmountMax = (float)ExpressionEvaluator.CalcVal_WithCtx(tbSummon.maxAmount, ctx, 3f);
|
|
var summonCount = summonAmount + existAmount < summonAmountMax
|
|
? (int)summonAmount
|
|
: (int)summonAmountMax - existAmount;
|
|
|
|
if (summonCount == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var summonerPos = Vector2.zero ;//summoner.logicTransform.position;
|
|
var summonDistance = (float)ExpressionEvaluator.CalcVal_WithCtx(tbSummon.summonDistance, ctx, 5f);
|
|
var maxSurvivalTime = (float)ExpressionEvaluator.CalcVal_WithCtx(tbSummon.maxTime, ctx, 5f);
|
|
var survivalParam1 = (float)ExpressionEvaluator.CalcVal_WithCtx(tbSummon.survivalParam1, ctx, 10f);
|
|
var survivalType = tbSummon.survivalType;
|
|
|
|
var tbMonster = MonsterPropDescMgr.Instance.GetConfig(tbSummon.monsterID);
|
|
// var res = new CombatEntity[summonCount];
|
|
for (var i = 0; i < summonCount; i++)
|
|
{
|
|
var ce = Contexts.Combat.CreateEntity("Summon" + tbMonster.name);
|
|
|
|
ce.AddFaction(summonerFaction.faction, SelectUseType.Summon);
|
|
PropertySrv.GetMonsterPropValue(ce, tbMonster.id);
|
|
|
|
var propertyComponent = ce.property;
|
|
propertyComponent.SetLinkEid(summoner.creationIndex);
|
|
propertyComponent.SetLinkProperty(PropertyDef.Level);
|
|
|
|
if (string.IsNullOrEmpty(tbSummon.hpFixedInc) == false)
|
|
{
|
|
var totalHp = ExpressionEvaluator.CalcVal_WithCtx(tbSummon.hpFixedInc, ctx, 0);
|
|
propertyComponent.SetProperty(PropertyDef.HpFixedIncrease, totalHp, true);
|
|
propertyComponent.SetProperty(PropertyDef.CurHp, totalHp, true);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(tbSummon.atkFixedInc) == false)
|
|
{
|
|
var atk = ExpressionEvaluator.CalcVal_WithCtx(tbSummon.atkFixedInc, ctx, 0);
|
|
propertyComponent.SetProperty(PropertyDef.AtkFixedIncrease, atk, true);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(tbSummon.defFixedInc) == false)
|
|
{
|
|
var def = ExpressionEvaluator.CalcVal_WithCtx(tbSummon.defFixedInc, ctx, 0);
|
|
propertyComponent.SetProperty(PropertyDef.DefFixedIncrease, def, true);
|
|
}
|
|
|
|
var affixIds = GetMonsterRandomAffixIds(tbMonster);
|
|
ce.AddBlackboard(CfgType.MonsterCfg, tbMonster.id, Array.Empty<int>(), affixIds,
|
|
ce.creationIndex, tbMonster.NoChangeDir == 0);
|
|
ce.AddSummon(summonId, maxSurvivalTime, survivalType, survivalParam1);
|
|
if (tbSummon.dieWithSummoner != 0)
|
|
{
|
|
var lifeBindMeComponent = summoner.lifeBindMe;
|
|
if (lifeBindMeComponent == null)
|
|
{
|
|
summoner.AddLifeBindMe(summoner);
|
|
lifeBindMeComponent = summoner.lifeBindMe;
|
|
}
|
|
lifeBindMeComponent.AddChild(ce.creationIndex, i == 0);
|
|
}
|
|
ce.AddParentRecorder(CompLinkerType.Summon2C, summoner.creationIndex);
|
|
|
|
if (summonerFaction.faction == Faction.Player)
|
|
ce.isPartner = true;
|
|
else
|
|
ce.AddMonster(tbMonster.type);
|
|
|
|
AbilitySrv.AttachActiveAbilityGroup(tbMonster.skillGroup, ce);
|
|
AttachAffixTalentToEntity(ce);
|
|
for (int j = 0; j < tbMonster.AssetTags.Length; j++)
|
|
{
|
|
var gameplayTag = AbilitySrv.GetGameplayTag(tbMonster.AssetTags[j]);
|
|
ce.TagCountContainer.AddFixedTag(gameplayTag);
|
|
}
|
|
ce.AddAsset(
|
|
new MainAssetParam
|
|
{
|
|
path = tbMonster.prefab,
|
|
parentNodeName = "RenderWorld",
|
|
scaleParam = 1,
|
|
}, null);
|
|
// ce.LoadAsset();
|
|
var randomPos2D = MathHelper.OnsideUnitCircleRandom(summonDistance);
|
|
// summonerPos = summonerPos + randomPos2D;
|
|
// var vector2 = MathViewUtils.ToVector2(summonerPos);
|
|
// NavMesh.SamplePosition(fixed64Vector2, out var closestHit, 10f, NavMesh.AllAreas);
|
|
// var pos = new Vector2(closestHit.position.x, closestHit.position.y);
|
|
// ce.AddLogicTransform(summonerPos, Fixed64Vector2.one, Fixed64Vector2.right);
|
|
// ce.AddTransformProxy(summonerPos.ToVector2(), Vector2.right, ce);
|
|
ce.AddAudio(ce.creationIndex);
|
|
ce.blackboard.SetBornPos(ce.logicTransform.position, randomPos2D);
|
|
}
|
|
}
|
|
|
|
public static CombatEntity BronMonsterEntity(CombatContext context, CombatEntity parentEnt,
|
|
ref MonsterData monsterData)
|
|
{
|
|
var tbMonster = MonsterPropDescMgr.Instance.GetConfig(monsterData.unitId);
|
|
if (tbMonster == null)
|
|
return null;
|
|
|
|
var ce = context.CreateEntity("Monster" + tbMonster.name);
|
|
var affixIds = GetMonsterRandomAffixIds(tbMonster);
|
|
ce.AddBlackboard(CfgType.MonsterCfg, monsterData.unitId, Array.Empty<int>(), affixIds,
|
|
ce.creationIndex, tbMonster.NoChangeDir == 0);
|
|
|
|
// var hasHit = NavMesh.Raycast(monsterData.srcPos, monsterData.position, out var closestHit, NavMesh.AllAreas);
|
|
// // var isSucc = NavMesh.SamplePosition(monsterData.position, out var closestHit, 10f, NavMesh.AllAreas);
|
|
// if (hasHit)
|
|
// {
|
|
// var normalDir = new Vector2(closestHit.normal.x, closestHit.normal.y);
|
|
// Vector2 newPos = closestHit.position;
|
|
// monsterData.position = newPos + normalDir * monsterData.pushRadius;
|
|
// NavMesh.SamplePosition(monsterData.position, out var closestHit2, 10f, NavMesh.AllAreas);
|
|
// monsterData.position = new Vector2(closestHit2.position.x, closestHit2.position.y);
|
|
// }
|
|
ce.AddLogicTransform(monsterData.position, Fixed64Vector2.one, Fixed64Vector2.right);
|
|
ce.blackboard.SetBornPos(ce.logicTransform.position);
|
|
// if (parentEnt != null)
|
|
// ce.AddParentRecorder(CompLinkerType.Summon2C, parentEnt.creationIndex);
|
|
|
|
ce.AddEffectShowProxy(tbMonster.VFXsize * BattleConst.TenThousandReverse.AsFloat, ce);
|
|
ce.AddBorn(tbMonster.bornTime * BattleConst.TenThousandReverse.AsFloat, tbMonster.bornVFX);
|
|
return ce;
|
|
}
|
|
|
|
public static CombatEntity CreateMonsterByBorn(CombatEntity ce)
|
|
{
|
|
var blackboard = ce.blackboard;
|
|
var tbMonster = MonsterPropDescMgr.Instance.GetConfig(blackboard.unitCfgId);
|
|
ce.AddMonster(tbMonster.type);
|
|
PropertySrv.GetMonsterPropValue(ce, tbMonster.id);
|
|
// 阵营要先设置,碰撞有依赖
|
|
ce.AddFaction(Faction.Enemy, SelectUseType.Actor);
|
|
ce.AddAudio(ce.creationIndex);
|
|
AbilitySrv.AttachActiveAbilityGroup(tbMonster.skillGroup, ce);
|
|
AttachAffixTalentToEntity(ce);
|
|
|
|
if (tbMonster.type == MonsterType.Boss)
|
|
{
|
|
ce.TagCountContainer.AddFixedTag("Entity.Monster.Boss");
|
|
// 添加可再生护盾
|
|
if (tbMonster.ShieldValue > 0)
|
|
{
|
|
ce.AddRefreshableHpShield(tbMonster.ShieldType, tbMonster.ShieldValue,
|
|
tbMonster.ShieldRestore * 0.001f);
|
|
ce.AddReload(0);
|
|
}
|
|
}
|
|
|
|
ce.AddAsset(
|
|
new MainAssetParam()
|
|
{
|
|
path = tbMonster.prefab,
|
|
parentNodeName = "RenderWorld",
|
|
scaleParam = 1,
|
|
}, null);
|
|
// ce.LoadAsset();
|
|
|
|
var levelWaveEntity = Contexts.Combat.LevelWave;
|
|
levelWaveEntity.DispatchEvent(ClientEvent.LevelMonsterRage, null);
|
|
return ce;
|
|
}
|
|
|
|
public static int[] GetMonsterRandomAffixIds(MonsterPropDesc tbMonster)
|
|
{
|
|
var randomAffixes = tbMonster.randomAffixes;
|
|
if (randomAffixes == 0)
|
|
{
|
|
return Array.Empty<int>();
|
|
}
|
|
|
|
var affixesRandomGroupDesc = AffixesRandomGroupDescMgr.Instance.GetConfig(randomAffixes);
|
|
if (affixesRandomGroupDesc == null || affixesRandomGroupDesc.affixesGroup.Length == 0)
|
|
{
|
|
return Array.Empty<int>();
|
|
}
|
|
var affixesRandomGroup = affixesRandomGroupDesc.affixesGroup;
|
|
var randomIndex = RandomSrv.Range(0, affixesRandomGroup.Length);
|
|
var affixesId = affixesRandomGroup[randomIndex];
|
|
var affixes = AffixesDescMgr.Instance.GetConfig(affixesId);
|
|
var affixIds = new int[affixes.affixes.Length];
|
|
for (var i = 0; i < affixes.affixes.Length; i++)
|
|
{
|
|
var affixId = affixes.affixes[i];
|
|
affixIds[i] = affixId;
|
|
}
|
|
return affixIds;
|
|
}
|
|
|
|
public static void AttachAffixTalentToEntity(CombatEntity ce)
|
|
{
|
|
var blackboard = ce.blackboard;
|
|
if (ce.blackboard == null)
|
|
return;
|
|
for (int i = 0; i < blackboard.affixIds.Length; i++)
|
|
{
|
|
var affixId = blackboard.affixIds[i];
|
|
var affix = AffixDescMgr.Instance.GetConfig(affixId);
|
|
AbilitySrv.AttachTalent_WithGaParam(ce, affix.talentID, null, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|