using CoreGame; using Entitas; using GAS.Runtime; using Proto; using xFrame; namespace CoreGame.Render { public class GunFireSystem : IExecuteSystem { readonly IGroup m_Group; public GunFireSystem(Contexts contexts) { // 找到所有开火的单位, 并且没有装弹的单位。 // todo:如果空弹夹要有扣扳机声音的话,修改这里 var shot = (Matcher)Matcher.AllOf(CombatComponentsLookup.GunFire) .NoneOf(CombatComponentsLookup.Reload); m_Group = contexts.combat.GetGroup(shot); } public void Execute(float dt) { m_Group.GetEntities(Contexts.s_CacheEntities); if (Contexts.s_CacheEntities.Count == 0) return; var entities = Contexts.s_CacheEntities; for (int i = 0; i < entities.Count; i++) { var gun = entities[i]; var owner = gun.parentRecorder.ParentEntity; if (!owner.IsValid() || owner.isDead) continue; var gunData = gun.gunData; gunData.fireCdAcc -= dt; // 如果还在cd中, 则不开火 if (gunData.fireCdAcc > 0) continue; // 如果没有弹药, 则重新装弹 var prop = gun.property; var currCnt = (int)prop.GetProperty(PropertyDef.Ammo); var bulletInfinite = owner.TagCountContainer.HasTag(GTagLib.Buff_BulletInfinite); if (currCnt < 1 && bulletInfinite == false) { gunData.ReloadAmmo(owner); continue; } var tbGun = WeaponDescMgr.Instance.GetConfig(gunData.gunCfgId); var ownerPropComp = owner.property; var currFireInterval = (float)ExpressionEvaluator.CalcVal_WithProp(tbGun.FireInterval, ownerPropComp.container, 1); ownerPropComp.SetProperty(PropertyDef.CurShootInterval, currFireInterval, true); var param = new GameplayAbilityParams { element = (int)gunData.elementType }; var tryActiveShotSkill = GunSrv.TryActiveShotSkill(gunData, owner, gun, param); if (tryActiveShotSkill == false) { gunData.fireCdAcc = 0f; continue; } if (bulletInfinite == false) { prop.AddValue(PropertyDef.Ammo, -1); } BattleLogger.LogInfoByEntity(gun, "Gun Fire But Before Dispatch OnDurationShoot Event Ammo:{0}", (int)prop.GetProperty(PropertyDef.Ammo)); // 持续射击 owner.DispatchEvent(ClientEvent.OnDurationShoot, null); var totalCnt = (int)prop.GetProperty(PropertyDef.AmmoMax); currCnt = (int)prop.GetProperty(PropertyDef.Ammo); BattleLogger.LogInfoByEntity(gun, "Gun Fire And After Dispatch OnDurationShoot Event Ammo:{0}", currCnt); if (owner.isLocalPlayer) { CoreUIBridge.CoreGamePushSlotBulletChanged(gunData.slotId, currCnt, totalCnt); } GunSrv.PushAmmoBarData(owner, (float)currCnt / totalCnt, 0f, 0f, true); // 开火 gunData.fireCdAcc += currFireInterval; if (currCnt < 1 && bulletInfinite == false) { gunData.ReloadAmmo(owner); gunData.fireCdAcc = 0f; } } } } }