コード例 #1
0
        public void DrawWorkerAnimated(Vector3 loc, Rot4 rot, int index, float extraRotation, bool rotatePoints = false)
        {
            Mesh       mesh       = MeshAt(rot);
            Vector3    newLoc     = loc;
            Quaternion quaternion = QuatFromRot(rot);

            if (extraRotation != 0f)
            {
                quaternion *= Quaternion.Euler(Vector3.up * extraRotation);
            }
            Vector3 offset = DrawOffset(rot);

            if (rotatePoints && extraRotation != 0)
            {
                offset = Ext_Math.RotatePoint(offset, Vector3.zero, extraRotation);
            }
            newLoc += offset;

            Material mat = SubGraphicForIndex(index).MatSingle;

            DrawMeshInt(mesh, newLoc, quaternion, mat);
            if (ShadowGraphic != null)
            {
                ShadowGraphic.DrawWorker(newLoc, rot, null, null, extraRotation);
            }
        }
コード例 #2
0
        public static IEnumerable <AirDefense> CheckNearbyObjects(AerialVehicleInFlight aerialVehicle, float speedPctPerTick)
        {
            float   halfTicksPerTileTraveled = Ext_Math.RoundTo(speedPctPerTick * 100, 0.001f);
            Vector3 start = aerialVehicle.DrawPos;

            for (int i = 0; i < aerialVehicle.flightPath.Path.Count; i++)
            {
                int     destination    = aerialVehicle.flightPath[i].tile;
                Vector3 destinationPos = Find.WorldGrid.GetTileCenter(destination);
                Vector3 position       = start;
                for (float transition = 0; transition < 1; transition += halfTicksPerTileTraveled)
                {
                    Vector3 partition = Vector3.Slerp(position, destinationPos, transition);
                    foreach (KeyValuePair <WorldObject, AirDefense> defenseCache in airDefenseCache)
                    {
                        float distance = Ext_Math.SphericalDistance(partition, defenseCache.Key.DrawPos);
                        if (distance < defenseCache.Value.MaxDistance)
                        {
                            yield return(defenseCache.Value);
                        }
                    }
                }
                start = destinationPos;
            }
        }
コード例 #3
0
        /// <summary>
        /// Calculate VehicleTurret draw offset given <paramref name="rot"/>
        /// </summary>
        /// <param name="rot"></param>
        /// <param name="xOffset"></param>
        /// <param name="yOffset"></param>
        /// <param name="rotationOffset"></param>
        /// <param name="turretRotation"></param>
        /// <param name="attachedTo"></param>
        /// <returns></returns>
        public static Pair <float, float> ShipDrawOffset(Rot8 rot, float xOffset, float yOffset, out Pair <float, float> rotationOffset, float turretRotation = 0, VehicleTurret attachedTo = null)
        {
            rotationOffset = new Pair <float, float>(0, 0);
            if (attachedTo != null)
            {
                return(Ext_Math.RotatePointClockwise(attachedTo.turretRenderLocation.x + xOffset, attachedTo.turretRenderLocation.y + yOffset, turretRotation));
            }

            return(rot.AsInt switch
            {
                //North
                0 => new Pair <float, float>(xOffset, yOffset),
                //East
                1 => new Pair <float, float>(yOffset, -xOffset),
                //South
                2 => new Pair <float, float>(-xOffset, -yOffset),
                //West
                3 => new Pair <float, float>(-yOffset, xOffset),
                //NorthEast
                4 => Ext_Math.RotatePointClockwise(yOffset, -xOffset, 45f),
                //SouthEast
                5 => Ext_Math.RotatePointCounterClockwise(yOffset, -xOffset, 45f),
                //SouthWest
                6 => Ext_Math.RotatePointClockwise(-yOffset, xOffset, 45f),
                //NorthWest
                7 => Ext_Math.RotatePointCounterClockwise(-yOffset, xOffset, 45f),
                //Default
                _ => throw new ArgumentOutOfRangeException("VehicleRotation is not within bounds. RotationInt must be between 0 and 7 for each lateral, longitudinal, and diagonal direction.")
            });
コード例 #4
0
        public virtual bool TryExecuteEvent(AerialVehicleInFlight aerialVehicle, WorldObject shotDownBy, IntVec3?precalculatedCell = null)
        {
            try
            {
                Map crashSite;
                int ticksTillArrival = -1;
                if (Find.WorldObjects.MapParentAt(aerialVehicle.Tile) is MapParent mapParent)
                {
                    crashSite = mapParent.Map;
                }
                else
                {
                    int num = CaravanIncidentUtility.CalculateIncidentMapSize(aerialVehicle.vehicle.AllPawnsAboard, aerialVehicle.vehicle.AllPawnsAboard);
                    crashSite = GetOrGenerateMapUtility.GetOrGenerateMap(aerialVehicle.Tile, new IntVec3(num, 1, num), WorldObjectDefOfVehicles.CrashedShipSite);
                    if (shotDownBy is Settlement settlement)
                    {
                        ticksTillArrival = (crashSite.Parent as CrashSite).InitiateReinforcementsRequest(settlement);
                    }
                }
                bool validator(IntVec3 c)
                {
                    bool flag = aerialVehicle.vehicle.PawnOccupiedCells(c, Rot4.East).All(c2 => c2.Standable(crashSite) && !c.Roofed(crashSite) && !c.Fogged(crashSite) && c.InBounds(crashSite));

                    return(flag);
                }
                IntVec3 RandomCentercell()
                {
                    RCellFinder.TryFindRandomCellNearTheCenterOfTheMapWith(validator, crashSite, out IntVec3 result);
                    return(result);
                }
                IntVec3 cell = precalculatedCell ?? RandomCentercell();
                if (cell == IntVec3.Invalid)
                {
                    return(false);
                }
                AerialVehicleArrivalAction_CrashSpecificCell arrivalAction = new AerialVehicleArrivalAction_CrashSpecificCell(aerialVehicle.vehicle, crashSite.Parent, crashSite.Tile,
                                                                                                                              aerialVehicle.vehicle.CompVehicleLauncher.launchProtocol, cell, Rot4.East);
                arrivalAction.Arrived(crashSite.Tile);
                aerialVehicle.Destroy();
                string settlementLabel = shotDownBy?.Label ?? string.Empty;
                if (ticksTillArrival > 0)
                {
                    string hoursTillArrival = Ext_Math.RoundTo(ticksTillArrival / 2500f, 1).ToString();
                    SendCrashSiteLetter(shotDownBy, crashSite.Parent, CrashSiteDef.letterLabel, CrashSiteDef.letterTexts[1], CrashSiteDef.letterDef, crashSite.Parent, new NamedArgument[] { aerialVehicle.Label, settlementLabel, hoursTillArrival });
                }
                else
                {
                    SendCrashSiteLetter(shotDownBy, crashSite.Parent, CrashSiteDef.letterLabel, CrashSiteDef.letterTexts[0], CrashSiteDef.letterDef, crashSite.Parent, new NamedArgument[] { aerialVehicle.Label, settlementLabel });
                }
                return(true);
            }
            catch (Exception ex)
            {
                Log.Error($"Failed to execute incident {GetType()}. Exception=\"{ex.Message}\"");
                return(false);
            }
        }
コード例 #5
0
 /// <summary>
 /// Calculate VehicleTurret draw offset
 /// </summary>
 /// <param name="vehicle"></param>
 /// <param name="xOffset"></param>
 /// <param name="yOffset"></param>
 /// <param name="rotationOffset"></param>
 /// <param name="turretRotation"></param>
 /// <param name="attachedTo"></param>
 public static Pair <float, float> TurretDrawOffset(float angle, float xOffset, float yOffset, out Pair <float, float> rotationOffset, float turretRotation = 0, VehicleTurret attachedTo = null)
 {
     rotationOffset = new Pair <float, float>(0, 0);
     if (attachedTo != null)
     {
         return(Ext_Math.RotatePointClockwise(attachedTo.turretRenderLocation.x + xOffset, attachedTo.turretRenderLocation.y + yOffset, turretRotation));
     }
     return(Ext_Math.RotatePointClockwise(xOffset, yOffset, angle));
 }
コード例 #6
0
        public override void TargeterOnGUI()
        {
            if (IsTargeting)
            {
                if (!Mouse.IsInputBlockedNow)
                {
                    GlobalTargetInfo mouseTarget = CurrentTargetUnderMouse();

                    Vector2   mousePosition = Event.current.mousePosition;
                    Texture2D image         = mouseAttachment ?? TexCommand.Attack;
                    Rect      position      = new Rect(mousePosition.x + 8f, mousePosition.y + 8f, 32f, 32f);
                    GUI.DrawTexture(position, image);

                    CostAndDistanceCalculator(out float fuelOnPathCost, out float tileDistance);

                    Vector3 flightPathPos = originOnMap;
                    if (!FlightPath.NullOrEmpty())
                    {
                        flightPathPos = Find.WorldGrid.GetTileCenter(FlightPath.LastOrDefault().tile);
                    }
                    float finalFuelCost     = fuelOnPathCost;
                    float finalTileDistance = tileDistance;
                    if (mouseTarget.IsValid && Find.WorldGrid.GetTileCenter(mouseTarget.Tile) != flightPathPos)
                    {
                        finalFuelCost     += vehicle.CompVehicleLauncher.FuelNeededToLaunchAtDist(flightPathPos, mouseTarget.Tile);
                        finalTileDistance += Ext_Math.SphericalDistance(flightPathPos, Find.WorldGrid.GetTileCenter(mouseTarget.Tile));
                    }
                    TotalFuelCost = (float)Math.Round(finalFuelCost, 0);
                    TotalDistance = finalTileDistance;
                    string  fuelCostLabel = $"{"VehicleFuelCost".Translate()}: {TotalFuelCost}";
                    Vector2 textSize      = Text.CalcSize(fuelCostLabel);
                    Rect    labelPosition = new Rect(mousePosition.x, mousePosition.y + textSize.y + 20f, textSize.x, textSize.y);
                    float   bgWidth       = textSize.x * 1.2f;
                    var     color         = GUI.color;

                    if (extraLabelGetter != null)
                    {
                        string  text            = extraLabelGetter(mouseTarget, FlightPath, TotalFuelCost);
                        Vector2 labelGetterText = Text.CalcSize(text);
                        Rect    rect            = new Rect(position.xMax, position.y, 9999f, 100f);
                        Rect    bgRect          = new Rect(rect.x - labelGetterText.x * 0.1f, rect.y, labelGetterText.x * 1.2f, labelGetterText.y);
                        var     textColor       = GUI.color;
                        GUI.color = Color.white;
                        GUI.DrawTexture(bgRect, TexUI.GrayTextBG);
                        GUI.color = textColor;
                        GUI.Label(rect, text);
                    }
                    GUI.color = Color.white;
                    GUI.DrawTexture(new Rect(labelPosition.x - textSize.x * 0.1f, labelPosition.y, bgWidth, textSize.y), TexUI.GrayTextBG);

                    GUI.Label(labelPosition, fuelCostLabel);
                    GUI.color = color;
                }
            }
        }
コード例 #7
0
 /// <summary>
 /// Get nearest tile id to <paramref name="worldCoord"/>
 /// </summary>
 /// <param name="worldCoord"></param>
 public static int GetNearestTile(Vector3 worldCoord)
 {
     for (int tile = 0; tile < Find.WorldGrid.TilesCount; tile++)
     {
         Vector3 pos = Find.WorldGrid.GetTileCenter(tile);
         if (Ext_Math.SphericalDistance(worldCoord, pos) <= 0.75f)                 //0.25 tile length margin of error for quicker calculation
         {
             return(tile);
         }
     }
     return(-1);
 }
コード例 #8
0
ファイル: Flak.cs プロジェクト: SmashPhil/Vehicles
        public override void Initialize(WorldObject firedFrom, AerialVehicleInFlight target, Vector3 source)
        {
            this.target = target;
            Vector3 misfire = new Vector3(Rand.Range(-Spread, Spread), Rand.Range(-Spread, Spread), Rand.Range(-Spread, Spread));

            destination     = this.target.DrawPosAhead(50) - misfire;
            this.source     = source;
            this.firedFrom  = firedFrom;
            speedPctPerTick = Mathf.Max((AerialVehicleInFlight.PctPerTick / Ext_Math.SphericalDistance(this.source, destination)) * Rand.Range(40, 70), MinSpeed);
            InitializeFacing();

            explosionFrame = -1;
        }
コード例 #9
0
        public override void DrawTurret()
        {
            Vector3   offset         = new Vector3(parentTurret.def.building.turretTopOffset.x, 0f, parentTurret.def.building.turretTopOffset.y).RotatedBy(CurRotation);
            Vector3   vectorRecoiled = Ext_Math.PointFromAngle(offset, -curRecoil, CurRotation);
            float     drawSize       = parentTurret.def.building.turretTopDrawSize;
            Matrix4x4 matrix         = default;

            matrix.SetTRS(parentTurret.DrawPos + altitudeDrawLayer + Altitudes.AltIncVect + vectorRecoiled, (CurRotation + ArtworkRotation).ToQuat(), new Vector3(drawSize, 1f, drawSize));
            Graphics.DrawMesh(MeshPool.plane10, matrix, TurretGraphic?.MatAt(parentTurret.Rotation) ?? parentTurret.def.building.turretTopMat, 0);
            if (DrawLayer != null)
            {
                DrawLayer.DrawExtra(parentTurret.DrawPos + altitudeDrawLayer + Altitudes.AltIncVect + offset, CurRotation);
            }
        }
コード例 #10
0
        /// <summary>
        /// Last check when world target has been chosen
        /// </summary>
        /// <param name="target"></param>
        /// <param name="tile"></param>
        /// <param name="maxLaunchDistance"></param>
        /// <param name="launchAction"></param>
        public virtual bool ChoseWorldTarget(GlobalTargetInfo target, Vector3 pos, float fuelCost, Action <int, AerialVehicleArrivalAction, bool> launchAction)
        {
            currentMap = vehicle.Map;
            targetMap  = Find.WorldObjects.MapParentAt(target.Tile)?.Map;
            if (!target.IsValid)
            {
                Messages.Message("MessageTransportPodsDestinationIsInvalid".Translate(), MessageTypeDefOf.RejectInput, false);
                return(false);
            }
            else if (Ext_Math.SphericalDistance(pos, Find.WorldGrid.GetTileCenter(target.Tile)) > vehicle.CompVehicleLauncher.MaxLaunchDistance || fuelCost > vehicle.CompFueledTravel.Fuel)
            {
                Messages.Message("TransportPodDestinationBeyondMaximumRange".Translate(), MessageTypeDefOf.RejectInput, false);
                return(false);
            }
            IEnumerable <FloatMenuOption> source = GetFloatMenuOptionsAt(target.Tile);

            if (!source.Any())
            {
                if (!WorldVehiclePathGrid.Instance.Passable(target.Tile, vehicle.VehicleDef))
                {
                    Messages.Message("MessageTransportPodsDestinationIsInvalid".Translate(), MessageTypeDefOf.RejectInput, false);
                    return(false);
                }
                launchAction(target.Tile, null, false);
                if (landingProperties.forcedRotation.HasValue && !landing)
                {
                    vehicle.Rotation = landingProperties.forcedRotation.Value;
                }
                return(true);
            }
            else
            {
                if (source.Count() != 1)
                {
                    Find.WindowStack.Add(new FloatMenuTargeter(source.ToList()));
                    return(false);
                }
                if (!source.First().Disabled)
                {
                    source.First().action();
                    if (landingProperties.forcedRotation.HasValue && !landing)
                    {
                        vehicle.Rotation = landingProperties.forcedRotation.Value;
                    }
                    return(true);
                }
                return(false);
            }
        }
コード例 #11
0
        public void CostAndDistanceCalculator(out float fuelCost, out float distance)
        {
            fuelCost = 0;
            distance = 0;
            Vector3 start = originOnMap;

            foreach (FlightNode node in FlightPath)
            {
                int   tile         = node.tile;
                float nodeDistance = Ext_Math.SphericalDistance(start, Find.WorldGrid.GetTileCenter(tile));
                fuelCost += vehicle.CompVehicleLauncher.FuelNeededToLaunchAtDist(nodeDistance);
                distance += nodeDistance;
                start     = Find.WorldGrid.GetTileCenter(tile);
            }
        }
コード例 #12
0
 public override void WorldComponentTick()
 {
     foreach (var defense in searchingDefenses)
     {
         AerialVehicleInFlight aerialVehicleSearchingFor = defense.Key;
         for (int j = defense.Value.Count - 1; j >= 0; j--)
         {
             AirDefense airDefense        = defense.Value.ElementAt(j);
             float      distance          = Ext_Math.SphericalDistance(airDefense.parent.DrawPos, aerialVehicleSearchingFor.DrawPos);
             bool       withinMaxDistance = distance <= airDefense.MaxDistance;
             if (airDefense.CurrentTarget != aerialVehicleSearchingFor)
             {
                 airDefense.angle = (airDefense.angle + RotationRate * airDefense.searchDirection).ClampAndWrap(0, 360);
                 float angleToTarget = airDefense.parent.DrawPos.AngleToPoint(aerialVehicleSearchingFor.DrawPos);
                 if (withinMaxDistance && Mathf.Abs(angleToTarget - airDefense.angle) <= (airDefense.Arc / 2))
                 {
                     airDefense.activeTargets.Add(aerialVehicleSearchingFor);
                 }
             }
             else
             {
                 float headingToTarget   = WorldHelper.TryFindHeading(airDefense.parent.DrawPos, airDefense.CurrentTarget.DrawPos);
                 int   dirSignMultiplier = headingToTarget < airDefense.angle ? -2 : 2;
                 if (Mathf.Abs(headingToTarget - airDefense.angle) < 1 || Mathf.Abs(headingToTarget - airDefense.angle) > 359)
                 {
                     airDefense.angle = headingToTarget;
                     airDefense.Attack();
                 }
                 else
                 {
                     airDefense.angle = (airDefense.angle + RotationRate * dirSignMultiplier).ClampAndWrap(0, 360);
                 }
                 if (!withinMaxDistance)
                 {
                     airDefense.activeTargets.Remove(aerialVehicleSearchingFor);
                 }
             }
         }
     }
 }
コード例 #13
0
        public static void DrawTravelPoint(Vector3 start, Vector3 end, Material material = null)
        {
            if (material is null)
            {
                material = TexData.WorldLineMatWhite;
            }
            double distance = Ext_Math.SphericalDistance(start, end);
            int    steps    = Mathf.CeilToInt((float)(distance * 100) / 5);

            start += start.normalized * 0.05f;
            end   += end.normalized * 0.05f;
            Vector3 previous = start;

            for (int i = 1; i <= steps; i++)
            {
                float   t        = (float)i / steps;
                Vector3 midPoint = Vector3.Slerp(start, end, t);

                GenDraw.DrawWorldLineBetween(previous, midPoint, material, 0.5f);
                previous = midPoint;
            }
        }
コード例 #14
0
        public float FuelNeededToLaunchAtDist(Vector3 origin, int destination)
        {
            float tileDistance = Ext_Math.SphericalDistance(origin, Find.WorldGrid.GetTileCenter(destination));

            return(FuelNeededToLaunchAtDist(tileDistance));
        }
コード例 #15
0
        private void SetSpeed()
        {
            float tileDistance = Ext_Math.SphericalDistance(position, Find.WorldGrid.GetTileCenter(flightPath.First.tile));

            speedPctPerTick = (PctPerTick / tileDistance) * vehicle.CompVehicleLauncher.FlySpeed.Clamp(0, 5);
        }
コード例 #16
0
        public override IEnumerable <Gizmo> GetGizmos()
        {
            foreach (Gizmo gizmo in base.GetGizmos())
            {
                yield return(gizmo);
            }

            if (IsPlayerControlled)
            {
                if (vehicle.CompFueledTravel != null)
                {
                    yield return(vehicle.CompFueledTravel.FuelCountGizmo);

                    foreach (Gizmo fuelGizmo in vehicle.CompFueledTravel.DevModeGizmos())
                    {
                        yield return(fuelGizmo);
                    }
                }
                if (!vehicle.CompVehicleLauncher.inFlight && Find.WorldObjects.SettlementAt(Tile) is Settlement settlement2)
                {
                    yield return(GizmoHelper.AerialVehicleTradeCommand(this, settlement2.Faction, settlement2.TraderKind));
                }
                if (vehicle.CompVehicleLauncher.ControlInFlight || !vehicle.CompVehicleLauncher.inFlight)
                {
                    Command_Action launchCommand = new Command_Action()
                    {
                        defaultLabel = "CommandLaunchGroup".Translate(),
                        defaultDesc  = "CommandLaunchGroupDesc".Translate(),
                        icon         = VehicleTex.LaunchCommandTex,
                        alsoClickIfOtherInGroupClicked = false,
                        action = delegate()
                        {
                            LaunchTargeter.Instance.BeginTargeting(vehicle, new Func <GlobalTargetInfo, float, bool>(ChoseTargetOnMap), this, true, VehicleTex.TargeterMouseAttachment, false, null,
                                                                   (GlobalTargetInfo target, List <FlightNode> path, float fuelCost) => vehicle.CompVehicleLauncher.launchProtocol.TargetingLabelGetter(target, Tile, path, fuelCost));
                        }
                    };
                    if (vehicle.CompFueledTravel.EmptyTank)
                    {
                        launchCommand.Disable("VehicleLaunchOutOfFuel".Translate());
                    }
                    yield return(launchCommand);
                }
                if (!vehicle.CompVehicleLauncher.inFlight)
                {
                    foreach (Settlement settlement in Find.WorldObjects.ObjectsAt(flightPath.First.tile).Where(o => o is Settlement).Cast <Settlement>())
                    {
                        yield return(GizmoHelper.ShuttleTradeCommand(this, settlement));

                        if (WorldHelper.CanOfferGiftsTo(this, settlement))
                        {
                            yield return(new Command_Action
                            {
                                defaultLabel = "CommandOfferGifts".Translate(),
                                defaultDesc = "CommandOfferGiftsDesc".Translate(),
                                icon = VehicleTex.OfferGiftsCommandTex,
                                action = delegate()
                                {
                                    Pawn playerNegotiator = WorldHelper.FindBestNegotiator(vehicle, null, null);
                                    Find.WindowStack.Add(new Dialog_Trade(playerNegotiator, settlement, true));
                                }
                            });
                        }
                    }
                    Command_Settle commandSettle = new Command_Settle
                    {
                        defaultLabel = "CommandSettle".Translate(),
                        defaultDesc  = "CommandSettleDesc".Translate(),
                        icon         = SettleUtility.SettleCommandTex,
                        action       = delegate()
                        {
                            SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                            void settleHere()
                            {
                                SettlementVehicleUtility.Settle(this);
                            };
                            SettlementProximityGoodwillUtility.CheckConfirmSettle(Tile, settleHere);
                        }
                    };
                    if (!TileFinder.IsValidTileForNewSettlement(Tile, tmpSettleFailReason))
                    {
                        commandSettle.Disable(tmpSettleFailReason.ToString());
                    }
                    else if (SettleUtility.PlayerSettlementsCountLimitReached)
                    {
                        if (Prefs.MaxNumberOfPlayerSettlements > 1)
                        {
                            commandSettle.Disable("CommandSettleFailReachedMaximumNumberOfBases".Translate());
                        }
                        else
                        {
                            commandSettle.Disable("CommandSettleFailAlreadyHaveBase".Translate());
                        }
                    }
                    yield return(commandSettle);
                }
                if (Prefs.DevMode)
                {
                    yield return(new Command_Action
                    {
                        defaultLabel = "Debug: Land at Nearest Player Settlement",
                        action = delegate()
                        {
                            List <Settlement> playerSettlements = Find.WorldObjects.Settlements.Where(s => s.Faction == Faction.OfPlayer).ToList();
                            Settlement nearestSettlement = playerSettlements.MinBy(s => Ext_Math.SphericalDistance(s.DrawPos, DrawPos));

                            LaunchProtocol launchProtocol = vehicle.CompVehicleLauncher.launchProtocol;
                            Rot4 vehicleRotation = launchProtocol.landingProperties.forcedRotation ?? Rot4.Random;
                            IntVec3 cell = CellFinderExtended.RandomCenterCell(nearestSettlement.Map, (IntVec3 cell) => !MapHelper.VehicleBlockedInPosition(vehicle, Current.Game.CurrentMap, cell, vehicleRotation));
                            VehicleSkyfaller_Arriving skyfaller = (VehicleSkyfaller_Arriving)ThingMaker.MakeThing(vehicle.CompVehicleLauncher.Props.skyfallerIncoming);
                            skyfaller.vehicle = vehicle;

                            GenSpawn.Spawn(skyfaller, cell, nearestSettlement.Map, vehicleRotation);
                            Destroy();
                        }
                    });

                    yield return(new Command_Action
                    {
                        defaultLabel = "Debug: Initiate Crash Event",
                        action = delegate()
                        {
                            InitiateCrashEvent(null);
                        }
                    });
                }
            }
        }