private void LoadDummies() { m_flames.Clear(); foreach (var d in this.Model.Dummies.OrderBy(s => s.Key)) { if (d.Key.StartsWith("thruster_flame", StringComparison.InvariantCultureIgnoreCase)) { var f = new FlameInfo(); f.Direction = Vector3.Normalize(d.Value.Matrix.Forward); f.Position = d.Value.Matrix.Translation; f.Radius = Math.Max(d.Value.Matrix.Scale.X, d.Value.Matrix.Scale.Y) * 0.5f; m_flames.Add(f); } } }
private void DamageGrid(FlameInfo flameInfo, LineD l, MyCubeGrid grid) { HkSphereShape sph = new HkSphereShape(flameInfo.Radius * BlockDefinition.FlameDamageLengthScale); var transform = MatrixD.CreateWorld(l.From, Vector3.Forward, Vector3.Up); var hit = MyPhysics.CastShapeReturnPoint(l.To, sph, ref transform, (int)MyPhysics.CollisionLayers.DefaultCollisionLayer, 0.05f); sph.Base.RemoveReference(); if (hit.HasValue) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); MyPhysics.CastRay(hit.Value - l.Direction * 0.1f, hit.Value + l.Direction * 0.1f, m_gridRayCastLst, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); if (m_gridRayCastLst.Count == 0 || m_gridRayCastLst[0].HkHitInfo.GetHitEntity() != grid) //If you found something other than the targeted grid do nothing { m_gridRayCastLst.Clear(); return; } Vector3D offsetHit = hit.Value + l.Direction * 0.1; m_gridRayCastLst.Clear(); var block = grid.GetCubeBlock(grid.WorldToGridInteger(offsetHit)); //if (block != this.SlimBlock) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); var invWorld = grid.PositionComp.WorldMatrixNormalizedInv; var gridPos = Vector3D.Transform(offsetHit, invWorld); var gridDir = Vector3D.TransformNormal(l.Direction, invWorld); if (block != null) { //We dont want to damage thruster itself //We dont want smallship thruster to damage heavy armors because of landing if (block.FatBlock != this && (CubeGrid.GridSizeEnum == MyCubeSize.Large || block.BlockDefinition.DeformationRatio > 0.25)) { block.DoDamage(30 * BlockDefinition.FlameDamage, MyDamageType.Environment, attackerId: EntityId); } } if (block == null || block.FatBlock != this) { var areaPlanar = 0.5f * flameInfo.Radius * CubeGrid.GridSize; var areaVertical = 0.5f * CubeGrid.GridSize; grid.Physics.ApplyDeformation(BlockDefinition.FlameDamage, areaPlanar, areaVertical, gridPos, gridDir, MyDamageType.Environment, CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.1f : 0, attackerId: EntityId); } } } }
public LineD GetDamageCapsuleLine(FlameInfo info) { var world = Matrix.CreateFromDir(Vector3.TransformNormal(info.Direction, WorldMatrix)); var halfLenght = ThrustLengthRand * info.Radius / 2; halfLenght *= m_thrustDefinition.FlameDamageLengthScale; var position = Vector3D.Transform(info.Position, WorldMatrix); if (halfLenght > info.Radius) { return(new LineD(position - world.Forward * (info.Radius), position + world.Forward * (2 * halfLenght - info.Radius))); } else { var l = new LineD(position + world.Forward * halfLenght, position + world.Forward * halfLenght); l.Direction = world.Forward; return(l); } }
private void DamageGrid(FlameInfo flameInfo, LineD l, MyCubeGrid grid) { HkSphereShape sph = new HkSphereShape(flameInfo.Radius * m_thrustDefinition.FlameDamageLengthScale); var transform = MatrixD.CreateWorld(l.From, Vector3.Forward, Vector3.Up); var hit = MyPhysics.CastShapeReturnPoint(l.To, sph, ref transform, (int)MyPhysics.DefaultCollisionLayer, 0.05f); sph.Base.RemoveReference(); if (hit.HasValue) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); MyPhysics.CastRay(hit.Value - l.Direction * 0.1f, hit.Value + l.Direction * 0.1f, m_gridRayCastLst, MyPhysics.ObjectDetectionCollisionLayer); if ((m_gridRayCastLst.Count == 0 || m_gridRayCastLst[0].HkHitInfo.Body.GetEntity() != grid) && grid == CubeGrid) { m_gridRayCastLst.Clear(); return; } m_gridRayCastLst.Clear(); var block = grid.GetCubeBlock(grid.WorldToGridInteger(hit.Value)); //if (block != this.SlimBlock) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); var invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); var gridPos = Vector3D.Transform(hit.Value, invWorld); var gridDir = Vector3D.TransformNormal(l.Direction, invWorld); if (block != null) { if (block.FatBlock != this && (CubeGrid.GridSizeEnum == MyCubeSize.Large || block.BlockDefinition.DeformationRatio > 0.25)) { block.DoDamage(30 * m_thrustDefinition.FlameDamage, MyDamageType.Environment, attackerId: EntityId); } } var areaPlanar = 0.5f * flameInfo.Radius * CubeGrid.GridSize; var areaVertical = 0.5f * CubeGrid.GridSize; grid.Physics.ApplyDeformation(m_thrustDefinition.FlameDamage, areaPlanar, areaVertical, gridPos, gridDir, MyDamageType.Environment, CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.1f : 0, attackerId: EntityId); } } }
public LineD GetDamageCapsuleLine(FlameInfo info) { var world = Matrix.CreateFromDir(Vector3.TransformNormal(info.Direction, WorldMatrix)); var halfLenght = ThrustLengthRand * info.Radius / 2; halfLenght *= BlockDefinition.FlameDamageLengthScale; var position = Vector3D.Transform(info.Position, WorldMatrix); if (halfLenght > info.Radius) return new LineD(position - world.Forward * (info.Radius), position + world.Forward * (2 * halfLenght - info.Radius)); else { var l = new LineD(position + world.Forward * halfLenght, position + world.Forward * halfLenght); l.Direction = world.Forward; return l; } }
private void DamageGrid(FlameInfo flameInfo, LineD l, MyCubeGrid grid) { HkSphereShape sph = new HkSphereShape(flameInfo.Radius * BlockDefinition.FlameDamageLengthScale); var transform = MatrixD.CreateWorld(l.From, Vector3.Forward, Vector3.Up); var hit = MyPhysics.CastShapeReturnPoint(l.To, sph, ref transform, (int)MyPhysics.DefaultCollisionLayer, 0.05f); sph.Base.RemoveReference(); if (hit.HasValue) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); MyPhysics.CastRay(hit.Value - l.Direction * 0.1f, hit.Value + l.Direction * 0.1f, m_gridRayCastLst, MyPhysics.ObjectDetectionCollisionLayer); if ((m_gridRayCastLst.Count == 0 || m_gridRayCastLst[0].HkHitInfo.GetHitEntity() != grid) && grid == CubeGrid) { m_gridRayCastLst.Clear(); return; } m_gridRayCastLst.Clear(); var block = grid.GetCubeBlock(grid.WorldToGridInteger(hit.Value)); //if (block != this.SlimBlock) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); var invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); var gridPos = Vector3D.Transform(hit.Value, invWorld); var gridDir = Vector3D.TransformNormal(l.Direction, invWorld); if (block != null) if (block.FatBlock != this && (CubeGrid.GridSizeEnum == MyCubeSize.Large || block.BlockDefinition.DeformationRatio > 0.25)) { block.DoDamage(30 * BlockDefinition.FlameDamage, MyDamageType.Environment, attackerId: EntityId); } var areaPlanar = 0.5f * flameInfo.Radius * CubeGrid.GridSize; var areaVertical = 0.5f * CubeGrid.GridSize; grid.Physics.ApplyDeformation(BlockDefinition.FlameDamage, areaPlanar, areaVertical, gridPos, gridDir, MyDamageType.Environment, CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.1f : 0, attackerId: EntityId); } } }
// 火焰上升效果 public void AddFlame(string signName, GameObject back, float width, Vector2 initPos) { FlameInfo info = new FlameInfo(back, width, initPos); _flameSet[signName] = info; }
public bool Draw() { if (thrust.MarkedForClose || thrust.Closed) { return(false); // remove from list } MatrixD cm = MyAPIGateway.Session.Camera.WorldMatrix; if (thrust.IsWorking && Vector3D.DistanceSquared(cm.Translation, thrust.WorldMatrix.Translation) <= maxViewDistSq) { if (firstFunctional) { firstFunctional = false; GetFlameInfo(); // needed here because it relies on getting dummies from the main model } float ClosedMultiplier = 1f; if (Reverser != null) { if (Reverser.MarkedForClose || Reverser.Closed) { Reverser = null; } else { ClosedMultiplier = 1 - Reverser.ReflectedThrust; } } bool paused = MyParticlesManager.Paused; Sandbox.Definitions.MyThrustDefinition def = thrust.BlockDefinition; float amount = Math.Min(thrust.CurrentStrength * 2, 1); if (!paused) { float lengthTarget = Math.Max(amount, 0.25f) * length * 3f * MyUtils.GetRandomFloat(0.9f, 1.1f) * ClosedMultiplier; thrustLerpLength = lengthTarget; // MathHelper.Lerp(thrustLerpLength, lengthTarget, 0.3f); float thickTarget = thickness * MyUtils.GetRandomFloat(0.9f, 1.1f); thrustLerpThick = thickTarget; // MathHelper.Lerp(thrustLerpThick, thickTarget, 0.2f); thurstLerpColor = MathHelper.Lerp(thurstLerpColor, amount, 0.25f); } //var trailColor = Vector4.Lerp(new Vector4(1f, 0.3f, 0f, 1f) * 0.25f, new Vector4(0.5f, 0.6f, 1f, 1f) * 0.75f, thurstLerpColor); Vector4 trailColor = Vector4.Lerp(new Vector4(0.5f, 0.6f, 1f, 1f) * 0.25f, new Vector4(1f, 0.3f, 0f, 1f), thurstLerpColor); Vector4 insideColor = trailColor; // Vector4.Lerp(new Vector4(1f, 0.3f, 0f, 1f) * 0.5f, new Vector4(1f, 1f, 0.9f, 1f), thurstLerpColor); Vector4 lightColor = insideColor; // Vector4.Lerp(new Vector4(1f, 0.3f, 0f, 1f), new Vector4(1f, 0.5f, 0.25f, 1f), thurstLerpColor); MatrixD m = thrust.WorldMatrix; float gridScale = thrust.CubeGrid.GridScale; MyStringId material = ThrustReversersMod.Instance.THRUST_MATERIAL; for (int i = 0; i < flames.Count; ++i) { FlameInfo flame = flames[i]; Vector3D direction = Vector3D.TransformNormal((Vector3D)flame.Direction, m); Vector3D position = Vector3D.Transform((Vector3D)flame.LocalFrom, m); Vector3D trailPos = position + (direction * trailOffset); Vector3 dirToCam = Vector3.Normalize(cm.Translation - position); float dot = Vector3.Dot(dirToCam, direction); float trailAlpha = 0.5f; float pointsAlpha = 2f; const float TRAIL_ANGLE_LIMIT = 0.95f; const float POINTS_ANGLE_START = 0.9f; const float POINTS_ANGLE_END = 0.35f; if (dot > TRAIL_ANGLE_LIMIT) { trailAlpha *= 1 - ((dot - TRAIL_ANGLE_LIMIT) / (1 - TRAIL_ANGLE_LIMIT)); } if (dot < POINTS_ANGLE_END) { pointsAlpha = 0; } else if (dot < POINTS_ANGLE_START) { pointsAlpha *= (dot - POINTS_ANGLE_END) / (POINTS_ANGLE_START - POINTS_ANGLE_END); } if (trailAlpha > 0) { MyTransparentGeometry.AddLineBillboard(material, trailColor * trailAlpha, trailPos, direction, thrustLerpLength, JET_FLAME_SCALE_MUL * thrustLerpThick, blendType: BLEND_TYPE); } if (pointsAlpha > 0) { MyTransparentGeometry.AddBillboardOriented(ThrustReversersMod.Instance.POINT_MATERIAL, trailColor * pointsAlpha, position + (direction * pointOffset), m.Left, m.Up, (thickness * pointScaleMul), blendType: BLEND_TYPE); } float coneHeightFinal = coneHeight * (paused ? 1 : MyUtils.GetRandomFloat(0.9f, 1.1f)); MatrixD coneMatrix = MatrixD.CreateWorld(position + (direction * (coneOffset + coneHeightFinal)), -direction, m.Up); Color coneColor = new Color(insideColor); DrawTransparentCone(ref coneMatrix, coneRadius, coneHeightFinal, ref coneColor, 16, ThrustReversersMod.Instance.CONE_MATERIAL, blendType: BLEND_TYPE); } // TODO reflected flames //if(ClosedMultiplier < 1 && amount > 0) //{ // float reflectedTrailOffset = -0.25f; // float reflectedTrailHeight = 1.5f; // // var door = (MyAdvancedDoor)Reverser.Entity; // // foreach(var part in door.Subparts.Values) // { // var pm = part.WorldMatrix; // // MyTransparentGeometry.AddBillboardOriented(ThrustReversersMod.Instance.THRUST_MATERIAL, trailColor * (1 - ClosedMultiplier), pm.Translation + (pm.Forward * reflectedTrailOffset) + pm.Up * (reflectedTrailHeight * 0.5), pm.Left, pm.Down, 0.5f, reflectedTrailHeight); // } //} light.LightOn = true; light.Position = m.Translation + (m.Forward * lightOffset); light.Color = lightColor; light.Intensity = 100 * Math.Max(trailColor.W * 2, 0.5f); light.Falloff = 3f; light.Range = thrustLerpThick * 2f; light.UpdateLight(); lightJet.LightOn = true; lightJet.Position = m.Translation + (m.Forward * lightJetOffset); lightJet.Color = trailColor; lightJet.Falloff = 1f; lightJet.Range = thrustLerpLength * 0.75f; lightJet.Intensity = 10 * trailColor.W; lightJet.UpdateLight(); } else { if (light.LightOn) { light.LightOn = false; light.UpdateLight(); } if (lightJet.LightOn) { lightJet.LightOn = false; lightJet.UpdateLight(); } } return(true); // keep in list }