Exemplo n.º 1
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;
            }
        }
Exemplo n.º 2
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;
                }
            }
        }
Exemplo n.º 3
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);
 }
Exemplo n.º 4
0
        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;
        }
Exemplo n.º 5
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);
            }
        }
Exemplo n.º 6
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);
            }
        }
Exemplo n.º 7
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);
                 }
             }
         }
     }
 }
Exemplo n.º 8
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;
            }
        }
Exemplo n.º 9
0
        public float FuelNeededToLaunchAtDist(Vector3 origin, int destination)
        {
            float tileDistance = Ext_Math.SphericalDistance(origin, Find.WorldGrid.GetTileCenter(destination));

            return(FuelNeededToLaunchAtDist(tileDistance));
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
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);
                        }
                    });
                }
            }
        }