public static bool PopulateSaveableUpgrades(VehicleDef def, bool hardReset = false) { try { if (hardReset) { VehicleMod.settings.upgrades.upgradeSettings.Remove(def.defName); } if (def.HasComp(typeof(CompUpgradeTree))) { if (!VehicleMod.settings.upgrades.upgradeSettings.TryGetValue(def.defName, out var currentUpgradeDict)) { VehicleMod.settings.upgrades.upgradeSettings.Add(def.defName, new Dictionary <SaveableField, SavedField <object> >()); currentUpgradeDict = VehicleMod.settings.upgrades.upgradeSettings[def.defName]; foreach (UpgradeNode node in def.GetSortedCompProperties <CompProperties_UpgradeTree>().upgrades) { IterateUpgradeNode(def, node, ref currentUpgradeDict); } //Redundancy only VehicleMod.settings.upgrades.upgradeSettings[def.defName] = currentUpgradeDict; } } } catch (Exception ex) { Log.Error($"Failed to populate upgrade settings for {def.defName}. Exception=\"{ex.Message}\"\nInnerException=\"{ex.InnerException}\""); return(false); } return(true); }
public void Initialize(VehicleDef def) { if (!cells.NullOrEmpty()) { Hitbox = cells; } else { CellRect rect = CellRect.CenteredOn(new IntVec3(0, 0, 0), def.Size.x, def.Size.z); List <IntVec3> cells = new List <IntVec3>(); if (side == VehicleComponentPosition.Body) { cells = rect.Cells.ToList(); } else if (side == VehicleComponentPosition.BodyNoOverlap) { foreach (var cell in rect.Cells.Where(c => !def.components.Where(cp => noOverlapWith.Contains(cp.hitbox.side)).Any(cp => cp.hitbox.Contains(c)))) { cells.Add(new IntVec3(cell.x, 0, cell.z)); } } else { cells = rect.GetEdgeCells(RotationFromSide(side)).ToList(); } List <IntVec2> intVec2s = new List <IntVec2>(); foreach (IntVec3 cell in cells) { intVec2s.Add(new IntVec2(cell.x, cell.z)); } Hitbox = intVec2s; } }
public static float GetCurrentWinterMovementDifficultyOffset(int tile, VehicleDef vehicleDef, int?ticksAbs = null, StringBuilder explanation = null) { if (ticksAbs == null) { ticksAbs = new int?(GenTicks.TicksAbs); } Vector2 vector = Find.WorldGrid.LongLatOf(tile); SeasonUtility.GetSeason(GenDate.YearPercent(ticksAbs.Value, vector.x), vector.y, out float num, out float num2, out float num3, out float num4, out float num5, out float num6); float num7 = num4 + num6; num7 *= Mathf.InverseLerp(MaxTempForWinterOffset, 0f, GenTemperature.GetTemperatureFromSeasonAtTile(ticksAbs.Value, tile)); if (num7 > 0.01f) { float num8 = WinterMovementDifficultyOffset * num7; if (explanation != null) { explanation.AppendLine(); explanation.Append("Winter".Translate()); if (num7 < 0.999f) { explanation.Append(" (" + num7.ToStringPercent("F0") + ")"); } explanation.Append(": "); explanation.Append(num8.ToStringWithSign("0.#")); //REDO - Add translated text for winter path cost multiplier } return(num8 * vehicleDef.properties.winterPathCostMultiplier); } return(0f); }
public virtual void ResolveReferences(VehicleDef def) { if (efficiency is null) { efficiency = new SimpleCurve() { new CurvePoint(0.25f, 0), new CurvePoint(0.35f, 0.35f), new CurvePoint(0.75f, 0.75f), new CurvePoint(0.85f, 1), new CurvePoint(1, 1) }; } if (categories is null) { categories = new List <VehicleStatCategoryDef>(); } if (compClass is null) { compClass = typeof(VehicleComponent); } if (!explosionProperties.Empty) { explosionProperties.Def = DefDatabase <DamageDef> .GetNamed(explosionProperties.damageDef); } hitbox.Initialize(def); }
public static bool PopulateSaveableFields(VehicleDef def, bool hardReset = false) { try { if (hardReset) { VehicleMod.settings.vehicles.fieldSettings.Remove(def.defName); } if (!VehicleMod.settings.vehicles.fieldSettings.TryGetValue(def.defName, out var currentDict)) { VehicleMod.settings.vehicles.fieldSettings.Add(def.defName, new Dictionary <SaveableField, SavedField <object> >()); currentDict = VehicleMod.settings.vehicles.fieldSettings[def.defName]; } IterateTypeFields(def, def.GetType(), def, ref currentDict); foreach (CompProperties props in def.comps) { IterateTypeFields(def, props.GetType(), props, ref currentDict); } //Redundancy only VehicleMod.settings.vehicles.fieldSettings[def.defName] = currentDict; } catch (Exception ex) { Log.Error($"Failed to populate field settings for <text>{def.defName}</text>.\nException=\"{ex.Message}\"\nInnerException=\"{ex.InnerException}\""); return(false); } return(true); }
/// <summary> /// Generate VehicleSkyfaller with newly generated vehicle /// </summary> /// <param name="def">test</param> /// <param name="vehicleDef"></param> /// <param name="faction"></param> public static VehicleSkyfaller MakeSkyfaller(ThingDef def, VehicleDef vehicleDef, Faction faction, bool randomizeColors = false, bool randomizeMask = false, bool cleanSlate = true) { VehicleSkyfaller skyfaller = (VehicleSkyfaller)ThingMaker.MakeThing(def); skyfaller.vehicle = VehicleSpawner.GenerateVehicle(new VehicleGenerationRequest(vehicleDef, faction, randomizeColors, randomizeMask, cleanSlate)); return(skyfaller); }
public SaveableDefPair(VehicleDef def, FieldInfo field, string uniqueKey, K key, LookMode valueLookMode) : base(def, field) { this.key = key; defName = key.defName; this.uniqueKey = uniqueKey; this.valueLookMode = valueLookMode; keyType = typeof(K); }
public void ResolvePostToSettings(VehicleDef def, ref Dictionary <SaveableField, SavedField <object> > currentDict) { FieldInfo dictField = SettingsCache.GetCachedField(typeof(StatUpgrade), nameof(values)); foreach (var statUpgrade in values) { SaveableDefPair <StatUpgradeCategoryDef> saveable = new SaveableDefPair <StatUpgradeCategoryDef>(def, dictField, string.Concat(statUpgrade.Key.defName, "_", upgradeID), statUpgrade.Key, LookMode.Value); currentDict.Add(saveable, new SavedField <object>(statUpgrade.Value)); } }
public override void DrawStatLister(VehicleDef def, Listing_Settings lister, SaveableField field, float value) { FloatRange?range = settingListerRange; if (range is null) { range = new FloatRange(-value, value); } lister.SliderLabeled(def, field, "VehicleMaxArmor".Translate(), "VehicleMaxArmorTooltip".Translate(), string.Empty, string.Empty, value + range.Value.min, value + range.Value.max, 1); }
public override void DrawStatLister(VehicleDef def, Listing_Settings lister, SaveableField field, float value) { FloatRange?range = settingListerRange; if (range is null) { range = new FloatRange(-value, value); } lister.FloatBox(def, field, "VehicleCargoCapacity".Translate(), "VehicleCargoCapacityTooltip".Translate(), string.Empty, value + range.Value.min, value + range.Value.max); }
public override IEnumerable <string> ConfigErrors(VehicleDef vehicleDef) { foreach (string error in base.ConfigErrors(vehicleDef)) { yield return(error); } if (groupKey.NullOrEmpty()) { yield return("<field>groupKey</field> must be populated for a turret of type <type>VehicleTurretAlternating</type>".ConvertRichText()); } }
public static object TryGetValue(this VehicleDef def, FieldInfo field) { if (VehicleMod.settings.vehicles.fieldSettings.TryGetValue(def.defName, out var dict)) { if (dict.TryGetValue(new SaveableField(def, field), out var result)) { return(result.Second); } } Log.Error($"Unable to retrieve {field.Name} for {def.defName} in ModSettings. Is this field posted to settings?"); return(default);
public object GetSettingsValue(VehicleDef def, SaveableField field) { try { return(settings switch { SettingsPage.Vehicles => VehicleMod.settings.vehicles.fieldSettings[def.defName][field].First, SettingsPage.Upgrades => VehicleMod.settings.upgrades.upgradeSettings[def.defName][field].First, _ => throw new NotSupportedException($"Cannot use Listing_Settings with settings set to {settings}") }); }
public static void DrawGhostVehicle(IntVec3 center, Rot8 rot, ThingDef thingDef, Graphic baseGraphic, Color ghostCol, AltitudeLayer drawAltitude, Thing thing = null) { if (thingDef is VehicleBuildDef def) { VehicleDef vehicleDef = def.thingToSpawn; if (vehicleDef.GetSortedCompProperties <CompProperties_Cannons>() is CompProperties_Cannons props) { Vector3 loc = GenThing.TrueCenter(center, rot, def.Size, drawAltitude.AltitudeFor()); vehicleDef.DrawGhostCannonTextures(loc, rot, ghostCol); } } }
public void RecalculatePerceivedMovementDifficultyAt(int tile, VehicleDef vehicleDef, int?ticksAbs = null) { if (!Find.WorldGrid.InBounds(tile)) { return; } bool flag = PassableFast(tile, vehicleDef); movementDifficulty[vehicleDef][tile] = CalculatedMovementDifficultyAt(tile, vehicleDef, ticksAbs, null); if (flag != PassableFast(tile, vehicleDef)) { WorldVehicleReachability.Instance.ClearCache(); } }
public static void SetVehicleTex(VehicleDef selectedDef) { if (selectedDef is null) { selectedVehicleTex = null; return; } var bodyGraphicData = selectedDef.graphicData; var graphicData = new GraphicDataRGB(); graphicData.CopyFrom(bodyGraphicData); graphicInt = graphicData.Graphic as Graphic_Vehicle; selectedVehicleTex = graphicInt.TexAt(Rot8.North); }
private static void RecalculateHeight(VehicleDef def, int columns = 3) { float propertySectionHeight = 5; //Buffer for bottom scrollable foreach (var saveableObject in VehicleCompFields) { if (saveableObject.Value.NullOrEmpty() || saveableObject.Value.All(f => f.TryGetAttribute <PostToSettingsAttribute>(out var settings) && settings.VehicleType != VehicleType.Undefined && settings.VehicleType != def.vehicleType)) { continue; } int rows = Mathf.CeilToInt(saveableObject.Value.Count / columns); propertySectionHeight += 50 + rows * 16; //72 } scrollableViewHeight = propertySectionHeight; }
public SaveablePair(VehicleDef def, FieldInfo field, string uniqueKey, KeyValuePair <K, V> keyValuePair, LookMode keyLookMode, LookMode valueLookMode) : base(def, field) { if (keyLookMode == LookMode.Def || valueLookMode == LookMode.Def) { Log.Warning("Cannot use LookMode.Def for SaveablePair. Would require resolving of Def post-loading. Consider using SaveableDefPair"); return; } key = keyValuePair.Key; value = keyValuePair.Value; this.uniqueKey = uniqueKey; this.keyLookMode = keyLookMode; this.valueLookMode = valueLookMode; keyType = typeof(K); valueType = typeof(V); }
public static float CalculatedMovementDifficultyAt(int tile, VehicleDef vehicleDef, int?ticksAbs = null, StringBuilder explanation = null) { Tile worldTile = Find.WorldGrid[tile]; if (explanation != null && explanation.Length > 0) { explanation.AppendLine(); } if (vehicleDef.CoastalTravel(tile)) { return(vehicleDef.properties.customBiomeCosts[BiomeDefOf.Ocean] / vehicleDef.properties.worldSpeedMultiplier); } else if (vehicleDef.vehicleType == VehicleType.Sea) { return(WorldHelper.WaterCovered(tile) ? vehicleDef.properties.customBiomeCosts[worldTile.biome] / vehicleDef.properties.worldSpeedMultiplier : ImpassableMovementDifficulty); } float biomeCost = vehicleDef.properties.customBiomeCosts.TryGetValue(worldTile.biome, WorldPathGrid.CalculatedMovementDifficultyAt(tile, false, ticksAbs, explanation)); float hillinessCost = vehicleDef.properties.customHillinessCosts.TryGetValue(worldTile.hilliness, HillinessMovementDifficultyOffset(worldTile.hilliness)); if (ImpassableCost(biomeCost) || ImpassableCost(hillinessCost)) { if (explanation != null) { explanation.Append("Impassable".Translate()); } return(ImpassableMovementDifficulty); } float finalBiomeCost = biomeCost / vehicleDef.properties.worldSpeedMultiplier; if (explanation != null) { explanation.Append(worldTile.biome.LabelCap + ": " + biomeCost.ToStringWithSign("0.#")); } float num3 = finalBiomeCost + hillinessCost; if (explanation != null && hillinessCost != 0f) { explanation.AppendLine(); explanation.Append(worldTile.hilliness.GetLabelCap() + ": " + hillinessCost.ToStringWithSign("0.#")); } return(num3 + GetCurrentWinterMovementDifficultyOffset(tile, vehicleDef, new int?(ticksAbs ?? GenTicks.TicksAbs), explanation)); }
public static PawnKindDef GenerateImpliedPawnKindDef(VehicleDef vehicleDef) { PawnKindDef kindDef = new PawnKindDef() { defName = vehicleDef.defName + "_PawnKind", label = vehicleDef.label, description = vehicleDef.description, combatPower = vehicleDef.combatPower, race = vehicleDef, lifeStages = new List <PawnKindLifeStage>() { new PawnKindLifeStage() } }; vehicleDef.VehicleKindDef = kindDef; return(kindDef); }
private void FloodFillAt(int tile, VehicleDef vehicleDef) { if (!fields.ContainsKey(vehicleDef)) { fields.Add(vehicleDef, new int[Find.WorldGrid.TilesCount]); } if (!WorldVehiclePathGrid.Instance.Passable(tile, vehicleDef)) { fields[vehicleDef][tile] = impassableFieldID; return; } Find.WorldFloodFiller.FloodFill(tile, (int x) => WorldVehiclePathGrid.Instance.Passable(x, vehicleDef), delegate(int x) { fields[vehicleDef][x] = nextFieldID; }, int.MaxValue, null); nextFieldID++; }
public Dialog_NodeSettings(VehicleDef def, UpgradeNode node, Vector2 origin) { VehicleDef = def; UpgradeNode = node; closeOnClickedOutside = true; closeOnAnyClickOutside = true; closeOnCancel = true; doCloseX = true; float width = 400; int rows = Mathf.Max(1, Mathf.FloorToInt(UpgradeNode.ListerCount / 2f)); float height = rows * 100 + 50; windowSize = new Vector2(width, height); drawLoc = origin; Lister = new Listing_Settings(SettingsPage.Upgrades); }
public VehicleGenerationRequest(VehicleDef vehicleDef, Faction faction, bool randomizeColors = false, bool randomizeMask = false, bool cleanSlate = true) { Rand.PushState(); VehicleDef = vehicleDef; Faction = faction; if (randomizeColors) { float r1 = Rand.Range(0.25f, .75f); float g1 = Rand.Range(0.25f, .75f); float b1 = Rand.Range(0.25f, .75f); ColorOne = new Color(r1, g1, b1, 1); float r2 = Rand.Range(0.25f, .75f); float g2 = Rand.Range(0.25f, .75f); float b2 = Rand.Range(0.25f, .75f); ColorTwo = new Color(r2, g2, b2, 1); float r3 = Rand.Range(0.25f, .75f); float g3 = Rand.Range(0.25f, .75f); float b3 = Rand.Range(0.25f, .75f); ColorThree = new Color(r3, g3, b3, 1); } else { ColorOne = vehicleDef.graphicData.color; ColorTwo = vehicleDef.graphicData.colorTwo; ColorThree = vehicleDef.graphicData.colorThree; } Upgrades = 0; CleanSlate = cleanSlate; if (!CleanSlate && vehicleDef.GetSortedCompProperties <CompProperties_UpgradeTree>() is CompProperties_UpgradeTree compProperties_UpgradeTree) { Upgrades = Rand.Range(0, compProperties_UpgradeTree.upgrades.Count); } RandomizeMask = randomizeMask; Rand.PopState(); }
public override void SettingsWindow(VehicleDef def, Listing_Settings listing) { FieldInfo dictField = SettingsCache.GetCachedField(typeof(StatUpgrade), nameof(values)); Rect buttonRect = listing.GetRect(16); buttonRect.x = buttonRect.width - 24; buttonRect.width = 24; buttonRect.height = 24; listing.Header(label, GameFont.Medium, TextAnchor.MiddleCenter); if (Widgets.ButtonImage(buttonRect, VehicleTex.ResetPage)) { SettingsCustomizableFields.PopulateSaveableUpgrades(def, true); } listing.Gap(); foreach (var statUpgrade in values) { SaveableDefPair <StatUpgradeCategoryDef> saveable = new SaveableDefPair <StatUpgradeCategoryDef>(def, dictField, string.Concat(statUpgrade.Key.defName, "_", upgradeID), statUpgrade.Key, LookMode.Value); statUpgrade.Key.DrawStatLister(def, listing, saveable, statUpgrade.Value); } }
public static void IterateTypeFields(VehicleDef def, Type type, object obj, ref Dictionary <SaveableField, SavedField <object> > currentDict) { if (VehicleMod.cachedFields.TryGetValue(type, out var fields)) { var dict = VehicleMod.settings.vehicles.fieldSettings[def.defName]; foreach (FieldInfo field in fields) { if (field.TryGetAttribute <PostToSettingsAttribute>(out var settings) && settings.ParentHolder) { object value = field.GetValue(obj); if (field.FieldType.IsGenericType) { MethodInfo method = field.DeclaringType.GetMethod("ResolvePostToSettings", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); if (method != null) { object[] arguments = new object[] { def, currentDict }; method.Invoke(obj, arguments); currentDict = (Dictionary <SaveableField, SavedField <object> >)arguments[1]; } else { SmashLog.Error($"Unable to generate customizable setting <field>{field.Name}</field> for <text>{def.defName}</text>. Fields of type <type>Dictionary<T></type> must implement ResolvePostToSettings method to be manually resolved."); } } else { IterateTypeFields(def, field.FieldType, value, ref currentDict); } } else { SaveableField saveField = new SaveableField(def, field); if (!dict.TryGetValue(saveField, out var _)) { dict.Add(saveField, new SavedField <object>(field.GetValue(obj))); } } }
/// <summary> /// Ensures the cellrect inhabited by <paramref name="vehicleDef"/> contains no Things that will block pathing and movement at <paramref name="cell"/>. /// </summary> /// <param name="pawn"></param> /// <param name="c"></param> public static bool CellRectStandable(this VehicleDef vehicleDef, Map map, IntVec3 cell, Rot4?rot = null) { IntVec2 dimensions = vehicleDef.Size; if (rot?.IsHorizontal ?? false) { int x = dimensions.x; dimensions.x = dimensions.z; dimensions.z = x; } foreach (IntVec3 cell2 in CellRect.CenteredOn(cell, dimensions.x, dimensions.z)) { if (vehicleDef.IsBoat() && !GenGridVehicles.Standable(cell2, map)) { return(false); } else if (!GenGrid.Standable(cell2, map)) { return(false); } } return(true); }
public static VehiclePawn SpawnVehicleRandomized(VehicleDef vehicleDef, IntVec3 cell, Map map, Faction faction, Rot4?rot = null, bool autoFill = false) { if (rot is null) { rot = Rot4.Random; } VehiclePawn vehicle = GenerateVehicle(new VehicleGenerationRequest(vehicleDef, faction, true, true)); vehicle.CompFueledTravel?.Refuel(vehicle.CompFueledTravel.FuelCapacity); GenSpawn.Spawn(vehicle, cell, map, rot.Value, WipeMode.FullRefund, false); if (autoFill) { foreach (VehicleHandler handler in vehicle.handlers.Where(h => h.role.handlingTypes.NotNullAndAny())) { Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(PawnKindDefOf.Colonist, faction)); pawn.SetFactionDirect(faction); vehicle.GiveLoadJob(pawn, handler); vehicle.Notify_Boarded(pawn); } } return(vehicle); }
public SaveableListEntry(VehicleDef def, FieldInfo field, int index) : base(def, field) { this.index = index; }
public bool PassableFast(int tile, VehicleDef vehicleDef) { return(movementDifficulty[vehicleDef][tile] < ImpassableMovementDifficulty); }
public float PerceivedMovementDifficultyAt(int tile, VehicleDef vehicleDef) { return(movementDifficulty[vehicleDef][tile]); }