private bool ReceiveOne() { uint length; if ((MySteam.IsActive || MySteam.Server != null) && Peer2Peer.IsPacketAvailable(out length, Channel)) { ulong sender; var msg = GetMessage((int)length); if (Peer2Peer.ReadPacket(msg.Data, out length, out sender, Channel)) { if (m_timestampProvider != null) { msg.Timestamp = m_timestampProvider(); } msg.ReceivedTime = MyTimeSpan.FromTicks(Stopwatch.GetTimestamp()); msg.Length = (int)length; msg.UserId = sender; m_receiveQueue.Enqueue(msg); return(true); } else { m_messagePool.Return(msg); return(false); } } else { return(false); } }
public void RemoveModule(ProceduralModule module) { m_modulesToAdd.Remove(module); if (!m_modules.Remove(module)) { return; } var list = m_objectListPool.Get(); try { m_tree.GetAll(list, true); foreach (var x in list) { if (x.Module == module) { x.RaiseRemoved(); } } } finally { m_objectListPool.Return(list); } }
/// <summary> /// Determines if two grids are attached. /// </summary> /// <param name="grid0">The starting grid.</param> /// <param name="grid1">The grid to search for.</param> /// <param name="allowedConnections">The types of connections allowed between grids.</param> /// <returns>True iff the grids are attached.</returns> public static bool IsGridAttached(IMyCubeGrid grid0, IMyCubeGrid grid1, AttachmentKind allowedConnections) { Logger.DebugLog("condition: grid0 == null", Logger.severity.FATAL, condition: grid0 == null); Logger.DebugLog("condition: grid1 == null", Logger.severity.FATAL, condition: grid1 == null); if (grid0 == grid1) { return(true); } AttachedGrid attached1 = GetFor(grid0); if (attached1 == null) { return(false); } AttachedGrid attached2 = GetFor(grid1); if (attached2 == null) { return(false); } HashSet <AttachedGrid> search = s_searchSet.Get(); bool result = attached1.IsGridAttached(attached2, allowedConnections, search); search.Clear(); s_searchSet.Return(search); return(result); }
void AddTool(IMyAutomaticRifleGun rifle) { PaintGunItem item = itemPool.Get(); if (!item.Init(rifle)) { itemPool.Return(item); return; } Tools.Add(item); ToolSpawned?.Invoke(item); SetUpdateMethods(UPDATE_METHODS, true); }
/// <summary> /// Prefetches planetary voxel physics along a ray /// </summary> /// <param name="ray">ray to prefetch</param> /// <param name="force">force a new prefetch task</param> public static void PrefetchRay(ref LineD ray, bool force = false) { // Force is second so we still update the cache for forced if (!_raycastPrefetchCache.IsItemPresent(ray.GetHash(), (int)MyAPIGateway.Session.ElapsedPlayTime.TotalSeconds) || force) { var voxelHits = _voxelCache.Get(); try { MyGamePruningStructure.GetVoxelMapsOverlappingRay(ref ray, voxelHits); foreach (var e in voxelHits) { var planet = (e.Element?.RootVoxel ?? e.Element) as MyPlanet; // This needs to be done for all voxel maps. To bad we can't. planet?.PrefetchShapeOnRay(ref ray); } } finally { voxelHits.Clear(); if (_voxelCache.Count <= 1) { _voxelCache.Return(voxelHits); } } } }
public static IMyPlayer GetPlayerById(this IMyPlayerCollection collection, long id) { var list = PlayerListPool.Get(); try { list.Clear(); collection.GetPlayers(list, (x) => x.IdentityId == id); return(list.Count > 0 ? list[0] : null); } finally { list.Clear(); PlayerListPool.Return(list); } }
internal void Clean() { for (int j = 0; j < CleanUp.Count; j++) { var p = CleanUp[j]; for (int i = 0; i < p.VrPros.Count; i++) { var virtInfo = p.VrPros[i]; virtInfo.Info.Clean(Session.Tick); VirtInfoPool.Return(virtInfo.Info); } p.VrPros.Clear(); if (p.DynamicGuidance) { DynTrees.UnregisterProjectile(p); } p.PruningProxyId = -1; p.Info.Clean(Session.Tick); ProjectilePool.Push(p); ActiveProjetiles.Remove(p); } CleanUp.Clear(); }
public static void Close() { try { _threadedLineQueue.Clear(); foreach (var pair in _instances) { pair.Value.TextWriter.Flush(); pair.Value.TextWriter.Close(); pair.Value.TextWriter.Dispose(); pair.Value.Clean(); _logPool.Return(pair.Value); } _instances.Clear(); _logPool.Clean(); _logPool = null; _instances = null; _threadedLineQueue = null; _defaultInstance = null; } catch (Exception e) { } }
private static MyTuple <float?, IMyTerminalBlock> TAPI_ClosestShieldInLine(LineD line, bool onlyIfOnline) { var segment = SegmentPool.Get(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref line, segment, MyEntityQueryType.Dynamic); var ray = new RayD(line.From, line.Direction); var closest = float.MaxValue; IMyTerminalBlock closestShield = null; for (int i = 0; i < segment.Count; i++) { var ent = segment[i].Element; if (ent == null || ent.Physics != null && !ent.Physics.IsPhantom) { continue; } ShieldGridComponent c; if (Session.Instance.IdToBus.TryGetValue(ent.EntityId, out c) && c.DefenseShields != null) { if (onlyIfOnline && (!c.DefenseShields.DsState.State.Online || c.DefenseShields.DsState.State.Lowered)) { continue; } var s = c.DefenseShields; var intersectDist = CustomCollision.IntersectEllipsoid(s.DetectMatrixOutsideInv, s.DetectMatrixOutside, ray); if (!intersectDist.HasValue) { continue; } var ellipsoid = intersectDist ?? 0; if (ellipsoid > line.Length || ellipsoid > closest || CustomCollision.PointInShield(ray.Position, s.DetectMatrixOutsideInv)) { continue; } closest = ellipsoid; closestShield = s.Shield; } } segment.Clear(); SegmentPool.Return(segment); var response = new MyTuple <float?, IMyTerminalBlock>(); if (closestShield == null) { response.Item1 = null; response.Item2 = null; return(response); } response.Item1 = closest; response.Item2 = closestShield; return(response); }
public void DoWork(WorkData workData = null) { if (Action != null) { Action(); Action = null; } if (DataAction != null) { DataAction(workData); DataAction = null; } instances.Return(this); }
internal void GridEffects() { foreach (var ge in _gridEffects) { foreach (var v in ge.Value) { GetCubesForEffect(v.Value.Ai, ge.Key, v.Value.HitPos, v.Key, _tmpEffectCubes); var healthPool = v.Value.AmmoDef.Health; ComputeEffects(ge.Key, v.Value.AmmoDef, v.Value.Damage * v.Value.Hits, ref healthPool, v.Value.AttackerId, v.Value.System.WeaponIdHash, _tmpEffectCubes); _tmpEffectCubes.Clear(); GridEffectPool.Return(v.Value); } GridEffectsPool.Return(ge.Value); } _gridEffects.Clear(); }
internal void GridEffects() { foreach (var ge in _gridEffects) { foreach (var v in ge.Value) { GetCubesForEffect(v.Value.Ai, ge.Key, v.Value.HitPos, v.Key, _tmpEffectCubes); ComputeEffects(ge.Key, v.Value.AmmoDef, v.Value.Damage * v.Value.Hits, float.MaxValue, v.Value.AttackerId, _tmpEffectCubes); _tmpEffectCubes.Clear(); v.Value.Clean(); GridEffectPool.Return(v.Value); } ge.Value.Clear(); GridEffectsPool.Return(ge.Value); } _gridEffects.Clear(); }
internal void RipParticles() { for (int i = KeensBrokenParticles.Count - 1; i >= 0; i--) { var rip = KeensBrokenParticles[i]; var effect = rip.Effect; if (effect.IsEmittingStopped || effect.IsStopped || !effect.Enabled || effect.GetElapsedTime() >= effect.DurationMax) { KeensBrokenParticles.RemoveAtFast(i); RipMap.Remove(rip.Effect); KeenMessPool.Return(rip); } else if (Session.Tick != rip.LastTick) { var velSimulation = effect.WorldMatrix.Translation + (rip.Velocity * MyEngineConstants.PHYSICS_STEP_SIZE_IN_SECONDS); effect.SetTranslation(ref velSimulation); } } }
public void OnDeviceInit() { m_pool = new MyConcurrentPool<MyRenderContext>(m_poolSize, true); // Initialize all RCs m_tmpList.Clear(); int poolSize = m_pool.Count; for (int i = 0; i < poolSize; i++) { MyRenderContext rc = m_pool.Get(); m_tmpList.Add(rc); rc.Initialize(); } foreach (var rc in m_tmpList) m_pool.Return(rc); m_tmpList.Clear(); m_isDeviceInit = true; }
public void OnDeviceInit() { m_pool = new MyConcurrentPool <MyRenderContext>(MaxDeferredRCsCount, true); // Initialize all RCs m_tmpList.Clear(); int poolSize = m_pool.Count; for (int i = 0; i < poolSize; i++) { MyRenderContext rc = m_pool.Get(); m_tmpList.Add(rc); rc.Initialize(); } foreach (var rc in m_tmpList) { m_pool.Return(rc); } m_tmpList.Clear(); m_isDeviceInit = true; }
private static InterningBag <T> Intern(InterningBag <T> tmp) { while (true) { if (InternPool.TryGetValue(tmp, out var interned)) { if (Pool.Count < 1000) { Pool.Return(tmp); } return(interned); } // ReSharper disable once InvertIf if (InternPool.TryAdd(tmp, tmp)) { // Interned objects should have a minimal footprint. Array.Resize(ref tmp._backing, tmp._backingSize); return(tmp); } } }
public void FreeRC(MyRenderContext rc) { MyRenderProxy.Assert(m_isDeviceInit); m_pool.Return(rc); }
static internal void FreeRC(MyRenderContext rc) { Debug.Assert(rc.OkToRelease); m_pool.Return(rc); }
private static string[] ParseArguments(string data, int offset = 0) { var list = ArgsListPool.Get(); var builder = ArgBuilderPool.Get(); try { list.Clear(); builder.Clear(); char?currentQuote = null; var escaped = false; for (var head = offset; head < data.Length; head++) { var ch = data[head]; if (ch == '\\' && !escaped) { escaped = true; continue; } if (!escaped && (ch == '\'' || ch == '"')) { if (currentQuote.HasValue && currentQuote == ch) { currentQuote = null; } else if (!currentQuote.HasValue) { currentQuote = ch; } continue; } if (escaped) { switch (ch) { case '\\': case '\'': case '"': case ' ': break; case 't': ch = '\t'; break; case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; default: throw new ArgumentException("Invalid escape sequence: \\" + ch); } } if (!escaped && !currentQuote.HasValue && ch == ' ') { list.Add(builder.ToString()); builder.Clear(); continue; } builder.Append(ch); escaped = false; } if (currentQuote.HasValue) { throw new ArgumentException("Unclosed quote " + currentQuote.Value); } if (escaped) { throw new ArgumentException("Can't end with an escape sequence"); } list.Add(builder.ToString()); return(list.ToArray()); } finally { list.Clear(); builder.Clear(); ArgsListPool.Return(list); ArgBuilderPool.Return(builder); } }
internal void RunAvBarrels1() { for (int i = AvBarrels1.Count - 1; i >= 0; i--) { var avBarrel = AvBarrels1[i]; var weapon = avBarrel.Weapon; var muzzle = avBarrel.Muzzle; var ticksAgo = weapon.Comp.Session.Tick - avBarrel.StartTick; var bAv = weapon.System.Values.HardPoint.Graphics.Barrel1; var effect = weapon.BarrelEffects1[muzzle.MuzzleId]; var effectExists = effect != null; if (effectExists && avBarrel.EndTick == 0 && weapon.StopBarrelAvTick >= Session.Tick) { avBarrel.EndTick = (uint)bAv.Extras.MaxDuration + Session.Tick; } var info = weapon.Dummies[muzzle.MuzzleId].Info; var somethingEnded = avBarrel.EndTick != 0 && avBarrel.EndTick <= Session.Tick || !weapon.PlayTurretAv || info.Entity == null || info.Entity.MarkedForClose || weapon.Comp.Ai == null || weapon.MuzzlePart.Entity?.Parent == null || weapon.Comp.Data.Repo == null || weapon.Comp.MyCube.MarkedForClose || weapon.MuzzlePart.Entity.MarkedForClose; var effectStale = effectExists && (effect.IsEmittingStopped || effect.IsStopped || effect.GetElapsedTime() >= effect.DurationMax) || !effectExists && ticksAgo > 0; if (effectStale || somethingEnded || !weapon.Comp.IsWorking) { if (effectExists) { if (effect.Loop) { effect.Stop(bAv.Extras.Restart); } weapon.BarrelEffects1[muzzle.MuzzleId] = null; } muzzle.Av1Looping = false; muzzle.LastAv1Tick = 0; AvBarrels1.RemoveAtFast(i); AvBarrelPool.Return(avBarrel); continue; } if (weapon.Comp.Ai.VelocityUpdateTick != weapon.Comp.Session.Tick) { weapon.Comp.Ai.GridVel = weapon.Comp.Ai.MyGrid.Physics?.LinearVelocity ?? Vector3D.Zero; weapon.Comp.Ai.IsStatic = weapon.Comp.Ai.MyGrid.Physics?.IsStatic ?? false; weapon.Comp.Ai.VelocityUpdateTick = weapon.Comp.Session.Tick; } var particles = weapon.System.Values.HardPoint.Graphics.Barrel1; var renderId = info.Entity.Render.GetRenderObjectID(); var matrix = info.DummyMatrix; var pos = info.Position; matrix.Translation = info.LocalPosition + particles.Offset; if (!effectExists && ticksAgo <= 0) { if (MyParticlesManager.TryCreateParticleEffect(particles.Name, ref matrix, ref pos, renderId, out weapon.BarrelEffects1[muzzle.MuzzleId])) { effect = weapon.BarrelEffects1[muzzle.MuzzleId]; //effect.UserColorMultiplier = particles.Color; effect.UserRadiusMultiplier = particles.Extras.Scale; muzzle.Av1Looping = effect.Loop || effect.DurationMax <= 0; } } else if (particles.Extras.Restart && effectExists && effect.IsEmittingStopped) { effect.WorldMatrix = matrix; effect.Play(); } else if (effectExists) { effect.WorldMatrix = matrix; } } }
public static void DoProcessing() { while (!_closing) { try { var m = _processing.Take(); MyLog.Default.WriteLineAndConsole($"Processing message: {m.GetType().Name}"); if (m is IncomingMessage) { MessageBase i; try { var o = MyCompression.Decompress(m.CompressedData); m.CompressedData = null; _messagePool.Return((IncomingMessage)m); i = MyAPIGateway.Utilities.SerializeFromBinary <MessageBase>(o); } catch (Exception ex) { MyLog.Default.WriteLineAndConsole($"TORCH MOD: Failed to deserialize message! {ex}"); continue; } if (MyAPIGateway.Multiplayer.IsServer) { i.ProcessServer(); } else { i.ProcessClient(); } } else { var b = MyAPIGateway.Utilities.SerializeToBinary(m); m.CompressedData = MyCompression.Compress(b); MyAPIGateway.Utilities.InvokeOnGameThread(() => { switch (m.TargetType) { case MessageTarget.Single: MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, m.Target); break; case MessageTarget.Server: MyAPIGateway.Multiplayer.SendMessageToServer(NET_ID, m.CompressedData); break; case MessageTarget.AllClients: MyAPIGateway.Players.GetPlayers(_playerCache); foreach (var p in _playerCache) { if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId) { continue; } MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); } break; case MessageTarget.AllExcept: MyAPIGateway.Players.GetPlayers(_playerCache); foreach (var p in _playerCache) { if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId || m.Ignore.Contains(p.SteamUserId)) { continue; } MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); } break; default: throw new Exception(); } _playerCache.Clear(); }); } } catch (Exception ex) { MyLog.Default.WriteLineAndConsole($"TORCH MOD: Exception occurred in communication thread! {ex}"); } } MyLog.Default.WriteLineAndConsole("TORCH MOD: COMMUNICATION THREAD: EXIT SIGNAL RECEIVED!"); //exit signal received. Clean everything and GTFO _processing?.Dispose(); _processing = null; _messagePool?.Clean(); _messagePool = null; _playerCache = null; }
internal static void RelaseTimestampQuery(MyQuery q) { m_timestampQueries.Return(q); }
/// <summary> /// PreFrame must be empty in this place /// </summary> public void ReturnPreFrame(MyUpdateFrame frame) { Debug.Assert(frame.RenderInput.Count == 0); m_frameDataPool.Return(frame); }
internal void End() { if (AvBarrels1.Count > 0) { RunAvBarrels1(); } if (AvBarrels2.Count > 0) { RunAvBarrels2(); } if (HitSounds.Count > 0) { RunHitSounds(); } for (int i = AvShots.Count - 1; i >= 0; i--) { var av = AvShots[i]; var refreshed = av.LastTick == Session.Tick; var shrinkCnt = av.TracerShrinks.Count; var glowCnt = av.GlowSteps.Count; var noNextStep = glowCnt == 0 && shrinkCnt == 0 && av.Dirty; if (refreshed) { if (av.PrimeEntity != null) { _models++; if (av.OnScreen != AvShot.Screen.None) { if (!av.PrimeEntity.InScene && !av.Cloaked) { av.PrimeEntity.InScene = true; av.PrimeEntity.Render.UpdateRenderObject(true, false); } av.PrimeEntity.PositionComp.SetWorldMatrix(ref av.PrimeMatrix, null, false, false, false); } if ((av.Cloaked || av.OnScreen == AvShot.Screen.None) && av.PrimeEntity.InScene) { av.PrimeEntity.InScene = false; av.PrimeEntity.Render.RemoveRenderObjects(); } } if (av.Triggered && av.TriggerEntity != null) { if ((!av.TriggerEntity.InScene)) { av.TriggerEntity.InScene = true; av.TriggerEntity.Render.UpdateRenderObject(true, false); } av.TriggerEntity.PositionComp.SetWorldMatrix(ref av.TriggerMatrix, null, false, false, false); } if (av.HasTravelSound) { if (!av.AmmoSound) { double distSqr; Vector3D.DistanceSquared(ref av.TracerFront, ref Session.CameraPos, out distSqr); if (distSqr <= av.AmmoDef.Const.AmmoTravelSoundDistSqr) { av.AmmoSoundStart(); } } else { av.TravelEmitter.SetPosition(av.TracerFront); } } if (av.HitParticle == AvShot.ParticleState.Custom) { av.HitParticle = AvShot.ParticleState.Dirty; if (av.OnScreen != AvShot.Screen.None) { var pos = av.Hit.HitPos; var matrix = MatrixD.CreateTranslation(pos); if (MyParticlesManager.TryCreateParticleEffect(av.AmmoDef.AmmoGraphics.Particles.Hit.Name, ref matrix, ref pos, uint.MaxValue, out av.HitEffect)) { av.HitEffect.UserColorMultiplier = av.AmmoDef.AmmoGraphics.Particles.Hit.Color; var scaler = 1; av.HitEffect.UserRadiusMultiplier = av.AmmoDef.AmmoGraphics.Particles.Hit.Extras.Scale * scaler; var scale = av.AmmoDef.Const.HitParticleShrinks ? MathHelper.Clamp(MathHelper.Lerp(1, 0, av.DistanceToLine / av.AmmoDef.AmmoGraphics.Particles.Hit.Extras.MaxDistance), 0.05f, 1) : 1; av.HitEffect.UserScale = scale * scaler; var hitVel = av.Hit.HitVelocity; Vector3D.ClampToSphere(ref hitVel, (float)av.MaxSpeed); av.HitEffect.Velocity = hitVel; } } } else if (av.HitParticle == AvShot.ParticleState.Explosion) { av.HitParticle = AvShot.ParticleState.Dirty; if (ExplosionReady && av.OnScreen != AvShot.Screen.None) { if (av.DetonateFakeExp) { SUtils.CreateFakeExplosion(Session, av.AmmoDef.AreaEffect.Detonation.DetonationRadius, av.TracerFront, av.AmmoDef); } else { SUtils.CreateFakeExplosion(Session, av.AmmoDef.AreaEffect.AreaEffectRadius, av.TracerFront, av.AmmoDef); } } } } if (noNextStep) { AvShotPool.Return(av); AvShots.RemoveAtFast(i); } } }
public void ReturnParticleToPool(Particle particle) { particlePool.Return(particle); }
public void Dispose() { _pool.Return(Handle); _pool = null; Handle = null; }
internal static void RelaseDisjointQuery(MyQuery q) { m_disjointQueries.Return(q); }
public override void UpdateBeforeSimulation() { try { int logicCount = GridLogic.Count; if (logicCount == 0) { return; } if (++PlayersUpdateTick > PlayersUpdateInterval) { PlayersUpdateTick = 0; Players.Clear(); MyAPIGateway.Players.GetPlayers(Players); } // logic from MyDistributedUpdater LogicUpdateIndex = (LogicUpdateIndex + 1) % LogicUpdateInterval; for (int i = LogicUpdateIndex; i < logicCount; i += LogicUpdateInterval) { GridLogic logic = GridLogic[i]; if (logic.Grid.MarkedForClose) { RemoveLogicIndex.Add(i); continue; } logic.Update(); } if (RemoveLogicIndex.Count > 0) { try { // sort ascending + iterate in reverse is required to avoid shifting indexes as we're removing. RemoveLogicIndex.Sort(); for (int i = (RemoveLogicIndex.Count - 1); i >= 0; i--) { int index = RemoveLogicIndex[i]; GridLogic logic = GridLogic[index]; GridLogic.RemoveAtFast(index); GridLogicLookup.Remove(logic.Grid.EntityId); logic.Reset(); LogicPool.Return(logic); } } finally { RemoveLogicIndex.Clear(); } } } catch (Exception e) { Log.Error(e); } }
internal void Run() { if (Session.Tick180) { Log.LineShortDate($"(DRAWS) --------------- AvShots:[{AvShots.Count}] OnScreen:[{_onScreens}] Shrinks:[{_shrinks}] Glows:[{_glows}] Models:[{_models}] P:[{Session.Projectiles.ActiveProjetiles.Count}] P-Pool:[{Session.Projectiles.ProjectilePool.Count}] AvPool:[{AvShotPool.Count}] (AvBarrels 1:[{AvBarrels1.Count}] 2:[{AvBarrels2.Count}])", "stats"); _glows = 0; _shrinks = 0; } _onScreens = 0; _models = 0; for (int i = AvShots.Count - 1; i >= 0; i--) { var av = AvShots[i]; if (av.OnScreen != AvShot.Screen.None) { _onScreens++; } var refreshed = av.LastTick == Session.Tick; if (refreshed && av.Tracer != AvShot.TracerState.Off && av.OnScreen != AvShot.Screen.None) { var color = av.Color; var segColor = av.SegmentColor; if (av.ShotFade > 0) { var fade = MathHelper.Clamp(1f - av.ShotFade, 0.005f, 1f); color *= fade; segColor *= fade; } if (!av.AmmoDef.Const.OffsetEffect) { if (av.Tracer != AvShot.TracerState.Shrink) { if (av.AmmoDef.Const.TracerMode == AmmoConstants.Texture.Normal) { MyTransparentGeometry.AddLineBillboard(av.AmmoDef.Const.TracerTextures[0], color, av.TracerBack, av.PointDir, (float)av.VisualLength, (float)av.TracerWidth); } else if (av.AmmoDef.Const.TracerMode != AmmoConstants.Texture.Resize) { MyTransparentGeometry.AddLineBillboard(av.AmmoDef.Const.TracerTextures[av.TextureIdx], color, av.TracerBack, av.PointDir, (float)av.VisualLength, (float)av.TracerWidth); } else { var seg = av.AmmoDef.AmmoGraphics.Lines.Tracer.Segmentation; var stepPos = av.TracerBack; var segTextureCnt = av.AmmoDef.Const.SegmentTextures.Length; var gapTextureCnt = av.AmmoDef.Const.TracerTextures.Length; var segStepLen = seg.SegmentLength / segTextureCnt; var gapStepLen = seg.SegmentGap / gapTextureCnt; var gapEnabled = gapStepLen > 0; int j = 0; double travel = 0; while (travel < av.VisualLength) { var mod = j++ % 2; var gap = gapEnabled && (av.SegmentGaped && mod == 0 || !av.SegmentGaped && mod == 1); var first = travel <= 0; double width; double rawLen; Vector4 dyncColor; if (!gap) { rawLen = first ? av.SegmentLenTranserved : seg.SegmentLength; width = av.SegmentWidth; dyncColor = segColor; } else { rawLen = first ? av.SegmentLenTranserved : seg.SegmentGap; width = av.TracerWidth; dyncColor = color; } var notLast = travel + rawLen < av.VisualLength; var len = notLast ? rawLen : av.VisualLength - travel; var clampStep = !gap?MathHelperD.Clamp((int)((len / segStepLen) + 0.5) - 1, 0, segTextureCnt - 1) : MathHelperD.Clamp((int)((len / gapStepLen) + 0.5) - 1, 0, gapTextureCnt); var material = !gap ? av.AmmoDef.Const.SegmentTextures[(int)clampStep] : av.AmmoDef.Const.TracerTextures[(int)clampStep]; MyTransparentGeometry.AddLineBillboard(material, dyncColor, stepPos, av.PointDir, (float)len, (float)width); if (!notLast) { travel = av.VisualLength; } else { travel += len; } stepPos += (av.PointDir * len); } } } } else { var list = av.Offsets; for (int x = 0; x < list.Count; x++) { Vector3D fromBeam; Vector3D toBeam; if (x == 0) { fromBeam = av.OffsetMatrix.Translation; toBeam = Vector3D.Transform(list[x], av.OffsetMatrix); } else { fromBeam = Vector3D.Transform(list[x - 1], av.OffsetMatrix); toBeam = Vector3D.Transform(list[x], av.OffsetMatrix); } Vector3 dir = (toBeam - fromBeam); var length = dir.Length(); var normDir = dir / length; MyTransparentGeometry.AddLineBillboard(av.AmmoDef.Const.TracerTextures[0], color, fromBeam, normDir, length, (float)av.TracerWidth); if (Vector3D.DistanceSquared(av.OffsetMatrix.Translation, toBeam) > av.TracerLengthSqr) { break; } } list.Clear(); } } var shrinkCnt = av.TracerShrinks.Count; if (shrinkCnt > _shrinks) { _shrinks = shrinkCnt; } if (shrinkCnt > 0) { RunShrinks(av); } var glowCnt = av.GlowSteps.Count; if (glowCnt > _glows) { _glows = glowCnt; } if (av.Trail != AvShot.TrailState.Off) { var steps = av.AmmoDef.AmmoGraphics.Lines.Trail.DecayTime; var widthScaler = !av.AmmoDef.AmmoGraphics.Lines.Trail.UseColorFade; var remove = false; for (int j = glowCnt - 1; j >= 0; j--) { var glow = av.GlowSteps[j]; if (!refreshed) { glow.Line = new LineD(glow.Line.From + av.ShootVelStep, glow.Line.To + av.ShootVelStep, glow.Line.Length); } if (av.OnScreen != AvShot.Screen.None) { var reduction = (av.GlowShrinkSize * glow.Step); var width = widthScaler ? (av.AmmoDef.Const.TrailWidth - reduction) * av.TrailScaler : av.AmmoDef.Const.TrailWidth * av.TrailScaler; var color = av.AmmoDef.AmmoGraphics.Lines.Trail.Color; if (!widthScaler) { color *= MathHelper.Clamp(1f - reduction, 0.01f, 1f); } MyTransparentGeometry.AddLineBillboard(av.AmmoDef.Const.TrailTextures[0], color, glow.Line.From, glow.Line.Direction, (float)glow.Line.Length, width); } if (++glow.Step >= steps) { glow.Parent = null; glow.Step = 0; remove = true; glowCnt--; Glows.Push(glow); } } if (remove) { av.GlowSteps.Dequeue(); } } if (glowCnt == 0 && shrinkCnt == 0 && av.MarkForClose) { AvShotPool.Return(av); AvShots.RemoveAtFast(i); } } }
public void DoWork() { Action(); Action = null; instances.Return(this); }
public static void DoProcessing() { while (!_closing) { try { MessageBase m; try { m = _processing.Take(); } catch { continue; } MyLog.Default.WriteLineAndConsole($"Processing message: {m.GetType().Name}"); if (m is IncomingMessage) //process incoming messages { MessageBase i; try { var o = MyCompression.Decompress(m.CompressedData); m.CompressedData = null; _messagePool.Return((IncomingMessage)m); i = MyAPIGateway.Utilities.SerializeFromBinary <MessageBase>(o); } catch (Exception ex) { MyLog.Default.WriteLineAndConsole($"TORCH MOD: Failed to deserialize message! {ex}"); continue; } if (TorchModCore.Debug) { MyAPIGateway.Utilities.ShowMessage("Torch", $"Received message of type {i.GetType().Name}"); } if (MyAPIGateway.Multiplayer.IsServer) { i.ProcessServer(); } else { i.ProcessClient(); } } else //process outgoing messages { if (TorchModCore.Debug) { MyAPIGateway.Utilities.ShowMessage("Torch", $"Sending message of type {m.GetType().Name}"); } var b = MyAPIGateway.Utilities.SerializeToBinary(m); m.CompressedData = MyCompression.Compress(b); switch (m.TargetType) { case MessageTarget.Single: MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, m.Target); break; case MessageTarget.Server: MyAPIGateway.Multiplayer.SendMessageToServer(NET_ID, m.CompressedData); break; case MessageTarget.AllClients: MyAPIGateway.Players.GetPlayers(_playerCache); foreach (var p in _playerCache) { if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId) { continue; } MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); } break; case MessageTarget.AllExcept: MyAPIGateway.Players.GetPlayers(_playerCache); foreach (var p in _playerCache) { if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId || m.Ignore.Contains(p.SteamUserId)) { continue; } MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); } break; default: throw new Exception(); } _playerCache.Clear(); } } catch (Exception ex) { MyLog.Default.WriteLineAndConsole($"TORCH MOD: Exception occurred in communication thread! {ex}"); } } MyLog.Default.WriteLineAndConsole("TORCH MOD: INFO: Communication thread shut down successfully! THIS IS NOT AN ERROR"); //exit signal received. Clean everything and GTFO _processing?.Dispose(); _processing = null; _messagePool?.Clean(); _messagePool = null; _playerCache = null; }