public static void Postfix(StuffProperties __instance, ref bool __result) { if (__instance.parent == null) { return; } if (__instance.parent == PGIThingDefOf.PerfectlyGenericItem) { __result = false; } }
public StuffPropertiesStats(StuffProperties p) { this.commonality = p.commonality; this.allowColorGenerators = p.allowColorGenerators; this.color = new ColorStats(p.color); Util.AssignDefStat(p.constructEffect, out this.constructEffect); Util.AssignDefStat(p.appearance, out this.appearance); Util.AssignDefStat(p.soundImpactStuff, out this.soundImpactStuff); Util.AssignDefStat(p.soundMeleeHitSharp, out this.soundMeleeHitSharp); Util.AssignDefStat(p.soundMeleeHitBlunt, out this.soundMeleeHitBlunt); Util.Populate(out this.statOffsets, p.statOffsets, (v) => new FloatValueDefStat <StatDef>(v.stat, v.value)); Util.Populate(out this.statFactors, p.statFactors, (v) => new FloatValueDefStat <StatDef>(v.stat, v.value)); }
public void ApplyStats(StuffProperties to) { to.commonality = this.commonality; to.allowColorGenerators = this.allowColorGenerators; to.color = this.color.ToColor(); Util.AssignDef(this.constructEffect, out to.constructEffect); Util.AssignDef(this.appearance, out to.appearance); Util.AssignDef(this.soundImpactStuff, out to.soundImpactStuff); Util.AssignDef(this.soundMeleeHitSharp, out to.soundMeleeHitSharp); Util.AssignDef(this.soundMeleeHitBlunt, out to.soundMeleeHitBlunt); to.statOffsets?.Clear(); Util.Populate(out to.statOffsets, this.statOffsets, (v) => new StatModifier() { stat = v.Def, value = v.value }); to.statFactors?.Clear(); Util.Populate(out to.statFactors, this.statFactors, (v) => new StatModifier() { stat = v.Def, value = v.value }); }
public TerrainDef GetStuffedTerrainDef(ThingDef stuffThingDef) { if (!stuffThingDef.IsStuff) { throw new ArgumentException(stuffThingDef.defName + " is not a stuff!"); } // create new terrain TerrainDef terrain = new TerrainDef(); terrain.acceptFilth = acceptFilth; terrain.acceptTerrainSourceFilth = acceptTerrainSourceFilth; terrain.affordances = affordances.NullOrEmpty() ? new List <TerrainAffordance>() : new List <TerrainAffordance>(affordances); terrain.avoidWander = avoidWander; terrain.altitudeLayer = altitudeLayer; terrain.buildingPrerequisites = buildingPrerequisites.NullOrEmpty() ? new List <ThingDef>() : new List <ThingDef>(buildingPrerequisites); terrain.burnedDef = burnedDef; terrain.changeable = changeable; terrain.driesTo = driesTo; terrain.designationCategory = DefDatabase <DesignationCategoryDef> .GetNamed("Floors"); terrain.edgeType = edgeType; terrain.fertility = fertility; terrain.holdSnow = holdSnow; terrain.layerable = layerable; terrain.menuHidden = menuHidden; terrain.passability = passability; terrain.pathCost = pathCost; terrain.pathCostIgnoreRepeat = pathCostIgnoreRepeat; terrain.placeWorkers = placeWorkers.NullOrEmpty() ? new List <Type>() : new List <Type>(placeWorkers); terrain.placingDraggableDimensions = placingDraggableDimensions; terrain.renderPrecedence = renderPrecedence; terrain.researchPrerequisites = researchPrerequisites.NullOrEmpty() ? new List <ResearchProjectDef>() : new List <ResearchProjectDef>(researchPrerequisites); terrain.resourcesFractionWhenDeconstructed = resourcesFractionWhenDeconstructed; terrain.scatterType = scatterType; terrain.smoothedTerrain = smoothedTerrain; terrain.specialDisplayRadius = specialDisplayRadius; terrain.statBases = statBases.NullOrEmpty() ? new List <StatModifier>() : new List <StatModifier>(statBases); terrain.tags = tags.NullOrEmpty() ? new List <string>() : new List <string>(tags); terrain.takeFootprints = takeFootprints; terrain.takeSplashes = takeSplashes; terrain.terrainFilthDef = terrainFilthDef; terrain.terrainAffordanceNeeded = terrainAffordanceNeeded; terrain.texturePath = texturePath; // apply stuff elements StuffProperties stuff = stuffThingDef.stuffProps; terrain.color = stuff.color; terrain.constructEffect = stuff.constructEffect; terrain.repairEffect = stuff.constructEffect; terrain.label = "ThingMadeOfStuffLabel".Translate(stuffThingDef.LabelAsStuff, label); terrain.description = description; terrain.defName = stuffThingDef.defName + "_" + defName; terrain.costList = new List <ThingCountClass>(); if (!costList.NullOrEmpty()) { foreach (ThingCountClass cost in costList) { terrain.costList.Add(new ThingCountClass(cost.thingDef, cost.count)); } } if (stuffCost > 0) { terrain.costList.Add(new ThingCountClass(stuffThingDef, Mathf.CeilToInt(stuffCost / stuffThingDef.VolumePerUnit))); } // apply stuff offsets and factors, but apply them to a new list of statmodifiers, re-using the same list // keeps the actual statmodifier entries around as references, and leads to exponentially increasing stats // for terrains of the same base def and different stuffs if (!statsAffectedByStuff.NullOrEmpty()) { // prepare variables var stats = new List <StatModifier>(); StringBuilder text = new StringBuilder(); foreach (StatDef stat in statsAffectedByStuff) { // get base/default value float value = terrain.statBases.GetStatValueFromList(stat, stat.defaultBaseValue); text.AppendLine($"Base {stat.label} for {terrain.label}: {value}"); // apply offset float offset = stuff.statOffsets.GetStatOffsetFromList(stat); // apply factor float factor = (value >= 0 || stat.applyFactorsIfNegative) ? stuff.statFactors.GetStatFactorFromList(stat) : 1f; // lower impact of stuff beauty on floors if (stat == StatDefOf.Beauty) { offset *= 1 / 3f; factor = Mathf.Sqrt(factor); } // calculate new value float final = (value + offset) * factor; text.AppendLine($"\tstuffed: ({value} + {offset}) x {factor} = {final}"); StatUtility.SetStatValueInList(ref stats, stat, final); } #if DEBUG_IMPLIED_DEFS Log.Message($"Created {terrain.defName} from {stuffThingDef.defName}"); #if DEBUG_COSTLIST foreach (ThingCountClass count in terrain.costList) { Log.Message($"\t{count.thingDef.defName}: {count.count}"); } #endif #if DEBUG_STUFFING Log.Message(text.ToString()); #endif #endif // asign the stats, overwriting the statBases list terrain.statBases = stats; } return(terrain); }
static MyStaticConstructor() { List <ThingDef> impliedDefs = new List <ThingDef>(); StringBuilder stringBuilder = new StringBuilder("[LuluChunkWalls] Dynamic patched the following defs: "); bool first = true; float wallWork = ThingDefOf.Wall.statBases.GetStatValueFromList(StatDefOf.WorkToBuild, 135); float floorWork = TerrainDefOf.Concrete.statBases.GetStatValueFromList(StatDefOf.WorkToBuild, 100); MethodInfo newThingBlueprintDef = typeof(ThingDefGenerator_Buildings).GetMethod("NewBlueprintDef_Thing", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo newThingFrameDef = typeof(ThingDefGenerator_Buildings).GetMethod("NewFrameDef_Thing", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo newTerrainBlueprintDef = typeof(ThingDefGenerator_Buildings).GetMethod("NewBlueprintDef_Terrain", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo newTerrainFrameDef = typeof(ThingDefGenerator_Buildings).GetMethod("NewFrameDef_Terrain", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo giveShortHash = typeof(ShortHashGiver).GetMethod("GiveShortHash", BindingFlags.NonPublic | BindingFlags.Static); foreach (ThingDef thingDef in DefDatabase <ThingDef> .AllDefs) { if (thingDef.building?.isNaturalRock ?? false) { ThingDef chunkDef = thingDef.building.mineableThing; if (chunkDef?.thingCategories?.Contains(ThingCategoryDefOf.StoneChunks) ?? false) { // Ensure lists are initialized. if (thingDef.building.blueprintGraphicData == null) { thingDef.building.blueprintGraphicData = new GraphicData(); } if (thingDef.costList == null) { thingDef.costList = new List <ThingDefCountClass>(); } if (thingDef.researchPrerequisites == null) { thingDef.researchPrerequisites = new List <ResearchProjectDef>(); } if (thingDef.statBases == null) { thingDef.statBases = new List <StatModifier>(); } StuffProperties productProps = (chunkDef.butcherProducts?.Where(p => p.thingDef.IsStuff).FirstOrDefault()?.thingDef ?? ThingDefOf.BlocksGranite).stuffProps; float stuffWork = productProps.statOffsets.GetStatOffsetFromList(StatDefOf.WorkToBuild); float stuffFactor = productProps.statFactors.GetStatFactorFromList(StatDefOf.WorkToBuild); // Patch the def. thingDef.building.blueprintGraphicData.texPath = "Lulu/ChunkWalls/ChunkWalls_Blueprint_Atlas"; thingDef.constructionSkillPrerequisite = 6; thingDef.costList.Add(new ThingDefCountClass(chunkDef, 2)); thingDef.designationCategory = DesignationCategoryDefOf.Structure; thingDef.designatorDropdown = MyDefOf.LuluChunkWalls_NaturalWall; thingDef.placingDraggableDimensions = 1; thingDef.researchPrerequisites.Add(MyDefOf.Stonecutting); thingDef.statBases.Add(new StatModifier { stat = StatDefOf.WorkToBuild, value = (wallWork + stuffWork) * (stuffFactor + 3) }); // was 2430 thingDef.terrainAffordanceNeeded = TerrainAffordanceDefOf.Heavy; thingDef.uiIconPath = "Lulu/ChunkWalls/ChunkWalls_MenuIcon"; // Manually create implied defs (we're past the point where they'd be generated automatically). impliedDefs.Add((ThingDef)newThingBlueprintDef.Invoke(null, new object[] { thingDef, false, null })); impliedDefs.Add((ThingDef)newThingFrameDef.Invoke(null, new object[] { thingDef })); // Finalize graphic data. thingDef.ResolveReferences(); thingDef.PostLoad(); // Build the log string. if (first) { stringBuilder.Append(thingDef.defName); first = false; } else { stringBuilder.AppendWithComma(thingDef.defName); } TerrainDef terrainDef = thingDef.building.leaveTerrain; if (terrainDef != null) { if (terrainDef.costList == null) { terrainDef.costList = new List <ThingDefCountClass>(); } if (terrainDef.researchPrerequisites == null) { terrainDef.researchPrerequisites = new List <ResearchProjectDef>(); } if (terrainDef.statBases == null) { terrainDef.statBases = new List <StatModifier>(); } terrainDef.constructionSkillPrerequisite = 6; terrainDef.costList.Add(new ThingDefCountClass(chunkDef, 1)); terrainDef.designationCategory = MyDefOf.Floors; terrainDef.designatorDropdown = MyDefOf.LuluChunkWalls_NaturalFloor; terrainDef.researchPrerequisites.Add(MyDefOf.Stonecutting); terrainDef.statBases.Add(new StatModifier { stat = StatDefOf.WorkToBuild, value = (floorWork + stuffWork) * (stuffFactor + 3) }); // was 1500 terrainDef.terrainAffordanceNeeded = TerrainAffordanceDefOf.Heavy; impliedDefs.Add((ThingDef)newTerrainBlueprintDef.Invoke(null, new object[] { terrainDef })); impliedDefs.Add((ThingDef)newTerrainFrameDef.Invoke(null, new object[] { terrainDef })); stringBuilder.AppendWithComma(terrainDef.defName); } } } } // Add the created implied defs to the def database. foreach (ThingDef impliedDef in impliedDefs) { DefGenerator.AddImpliedDef(impliedDef); impliedDef.ResolveReferences(); giveShortHash.Invoke(null, new object[] { impliedDef, typeof(ThingDef) }); } // Regenerate the references in designation categories to make sure everything shows up to the player. DesignationCategoryDefOf.Structure.ResolveReferences(); MyDefOf.Floors.ResolveReferences(); // Report on what we've done. Log.Message(stringBuilder.ToString()); }
private static TerrainDef CopyAndStuffTerrainDef(TerrainDef terrainToCopy, ThingDef stuffThingDef) { TerrainDef terrain = new TerrainDef(); terrain.modContentPack = PocketDimensionMod.Instance.Content; // Copy properties, everything we can think of, so that the xml can still be the main source for properties terrain.affordances = terrainToCopy.affordances.NullOrEmpty() ? new List <TerrainAffordanceDef>() : new List <TerrainAffordanceDef>(terrainToCopy.affordances); terrain.avoidWander = terrainToCopy.avoidWander; terrain.altitudeLayer = terrainToCopy.altitudeLayer; terrain.artisticSkillPrerequisite = terrainToCopy.artisticSkillPrerequisite; terrain.blueprintDef = terrainToCopy.blueprintDef; terrain.buildingPrerequisites = terrainToCopy.buildingPrerequisites.NullOrEmpty() ? new List <ThingDef>() : new List <ThingDef>(terrainToCopy.buildingPrerequisites); terrain.burnedDef = terrainToCopy.burnedDef; terrain.changeable = terrainToCopy.changeable; terrain.clearBuildingArea = terrainToCopy.clearBuildingArea; terrain.constructionSkillPrerequisite = terrainToCopy.constructionSkillPrerequisite; terrain.driesTo = terrainToCopy.driesTo; terrain.destroyBuildingsOnDestroyed = terrainToCopy.destroyBuildingsOnDestroyed; terrain.destroyEffect = terrainToCopy.destroyEffect; terrain.destroyEffectWater = terrainToCopy.destroyEffectWater; terrain.destroyOnBombDamageThreshold = terrainToCopy.destroyOnBombDamageThreshold; terrain.defaultPlacingRot = terrainToCopy.defaultPlacingRot; //terrain.designationCategory = DefDatabase<DesignationCategoryDef>.GetNamed("Floors"); terrain.edgeType = terrainToCopy.edgeType; terrain.extinguishesFire = terrainToCopy.extinguishesFire; terrain.extraDeteriorationFactor = terrainToCopy.extraDeteriorationFactor; terrain.extraDraftedPerceivedPathCost = terrainToCopy.extraDraftedPerceivedPathCost; terrain.extraNonDraftedPerceivedPathCost = terrainToCopy.extraNonDraftedPerceivedPathCost; terrain.fertility = terrainToCopy.fertility; terrain.filthAcceptanceMask = terrainToCopy.filthAcceptanceMask; terrain.frameDef = terrainToCopy.frameDef; terrain.generatedFilth = terrainToCopy.generatedFilth; terrain.holdSnow = terrainToCopy.holdSnow; terrain.layerable = terrainToCopy.layerable; terrain.maxTechLevelToBuild = terrainToCopy.maxTechLevelToBuild; terrain.minTechLevelToBuild = terrainToCopy.minTechLevelToBuild; terrain.menuHidden = terrainToCopy.menuHidden; terrain.passability = terrainToCopy.passability; terrain.pathCost = terrainToCopy.pathCost; terrain.pathCostIgnoreRepeat = terrainToCopy.pathCostIgnoreRepeat; terrain.placeWorkers = terrainToCopy.placeWorkers.NullOrEmpty() ? new List <Type>() : new List <Type>(terrainToCopy.placeWorkers); terrain.placingDraggableDimensions = terrainToCopy.placingDraggableDimensions; terrain.renderPrecedence = terrainToCopy.renderPrecedence; terrain.researchPrerequisites = terrainToCopy.researchPrerequisites.NullOrEmpty() ? new List <ResearchProjectDef>() : new List <ResearchProjectDef>(terrainToCopy.researchPrerequisites); terrain.resourcesFractionWhenDeconstructed = terrainToCopy.resourcesFractionWhenDeconstructed; terrain.scatterType = terrainToCopy.scatterType; terrain.smoothedTerrain = terrainToCopy.smoothedTerrain; terrain.specialDisplayRadius = terrainToCopy.specialDisplayRadius; terrain.statBases = terrainToCopy.statBases.NullOrEmpty() ? new List <StatModifier>() : new List <StatModifier>(terrainToCopy.statBases); terrain.tags = terrainToCopy.tags.NullOrEmpty() ? new List <string>() : new List <string>(terrainToCopy.tags); terrain.takeFootprints = terrainToCopy.takeFootprints; terrain.takeSplashes = terrainToCopy.takeSplashes; terrain.terrainAffordanceNeeded = terrainToCopy.terrainAffordanceNeeded; terrain.texturePath = terrainToCopy.texturePath; terrain.tools = terrainToCopy.tools.NullOrEmpty() ? new List <Tool>() : new List <Tool>(terrainToCopy.tools); terrain.traversedThought = terrainToCopy.traversedThought; terrain.waterDepthMaterial = terrainToCopy.waterDepthMaterial; terrain.waterDepthShader = terrainToCopy.waterDepthShader; terrain.waterDepthShaderParameters = terrainToCopy.waterDepthShaderParameters.NullOrEmpty() ? new List <ShaderParameter>() : new List <ShaderParameter>(terrainToCopy.waterDepthShaderParameters); // apply stuff elements StuffProperties stuff = stuffThingDef.stuffProps; terrain.color = stuff.color; terrain.constructEffect = stuff.constructEffect; terrain.repairEffect = stuff.constructEffect; terrain.label = "ThingMadeOfStuffLabel".Translate(stuffThingDef.LabelAsStuff, terrainToCopy.label); terrain.description = terrainToCopy.description; terrain.defName = terrainToCopy.defName + "_" + stuffThingDef.defName; terrain.costList = new List <ThingDefCountClass>(); //Log.Message(String.Format("Created {0} from {1}", terrain.defName, stuffThingDef.defName)); return(terrain); }
private static void ResolveImpliedStoneChunkStuffProperties(ThingDef stoneChunk, StuffProperties referenceProps) { // For compatibility with other mods that make stone chunks a material var stuffCategories = new List <StuffCategoryDef>() { StuffCategoryDefOf.DZ_StoneChunks }; if (stoneChunk.stuffProps?.categories is List <StuffCategoryDef> oldCats) { for (int i = 0; i < oldCats.Count; i++) { var cat = oldCats[i]; if (!stuffCategories.Contains(cat)) { stuffCategories.Add(cat); } } } stoneChunk.resourceReadoutPriority = ResourceCountPriority.Middle; stoneChunk.smeltable = false; stoneChunk.stuffProps = new StuffProperties() { stuffAdjective = referenceProps.stuffAdjective, commonality = referenceProps.commonality, categories = stuffCategories, statOffsets = new List <StatModifier>(), statFactors = new List <StatModifier>(), color = referenceProps.color, constructEffect = referenceProps.constructEffect, appearance = referenceProps.appearance, soundImpactStuff = referenceProps.soundImpactStuff, soundMeleeHitSharp = referenceProps.soundMeleeHitSharp, soundMeleeHitBlunt = referenceProps.soundMeleeHitBlunt }; var chunkProps = stoneChunk.stuffProps; if (referenceProps.statOffsets != null) { for (int i = 0; i < referenceProps.statOffsets.Count; i++) { var statOffset = referenceProps.statOffsets[i]; chunkProps.statOffsets.Add(new StatModifier() { stat = statOffset.stat, value = statOffset.value }); } } if (referenceProps.statFactors != null) { for (int i = 0; i < referenceProps.statFactors.Count; i++) { var statFactor = referenceProps.statFactors[i]; chunkProps.statFactors.Add(new StatModifier() { stat = statFactor.stat, value = statFactor.value }); } } ModifyStatModifier(ref chunkProps.statFactors, StatDefOf.WorkToMake, ToStringNumberSense.Factor, factor: 1.5f); ModifyStatModifier(ref chunkProps.statFactors, StatDefOf.WorkToBuild, ToStringNumberSense.Factor, factor: 1.5f); }
public StuffPropertiesWidget(StuffProperties sp) { this.stuffProperties = sp; this.inputWidgets = new List <IInputWidget>() { new FloatInputWidget <StuffProperties>(this.stuffProperties, "Commonality", d => d.commonality, (d, v) => d.commonality = v), new ColorWidget <StuffProperties>(this.stuffProperties, "Color", d => d.color, (d, v) => d.color = v), new BoolInputWidget <StuffProperties>(this.stuffProperties, "Allow Color Generators", d => d.allowColorGenerators, (d, v) => d.allowColorGenerators = v), new DefInputWidget <StuffProperties, EffecterDef>(this.stuffProperties, "Construct Effect", 200, d => d.constructEffect, (d, v) => d.constructEffect = v, true), new DefInputWidget <StuffProperties, StuffAppearanceDef>(this.stuffProperties, "Appearance", 200, d => d.appearance, (d, v) => d.appearance = v, true), new DefInputWidget <StuffProperties, SoundDef>(this.stuffProperties, "Sound Impact", 200, d => d.soundImpactStuff, (d, v) => d.soundImpactStuff = v, true), new DefInputWidget <StuffProperties, SoundDef>(this.stuffProperties, "Sound Melee Hit Sharp", 200, d => d.soundMeleeHitSharp, (d, v) => d.soundMeleeHitSharp = v, true), new DefInputWidget <StuffProperties, SoundDef>(this.stuffProperties, "Sound Melee Hit Blunt", 200, d => d.soundMeleeHitBlunt, (d, v) => d.soundMeleeHitBlunt = v, true), }; this.statOffsetsArgs = new WindowUtil.PlusMinusArgs <StatDef>() { getDisplayName = v => v.label, allItems = DefDatabase <StatDef> .AllDefs, beingUsed = () => { List <StatDef> l = new List <StatDef>(); if (this.stuffProperties.statOffsets != null) { foreach (var v in this.stuffProperties.statOffsets) { l.Add(v.stat); } } return(l); }, onAdd = def => { StatModifier sm = new StatModifier() { stat = def, value = 0 }; this.stuffProperties.statOffsets = Util.AddTo(this.stuffProperties.statOffsets, sm); this.statOffsets = Util.AddTo(this.statOffsets, this.CreateStatModifierInput(sm)); }, onRemove = def => { this.statOffsets?.RemoveAll(v => v.Parent.stat == def); this.stuffProperties.statOffsets?.RemoveAll(v => v.stat == def); } }; this.statFactorsArgs = new WindowUtil.PlusMinusArgs <StatDef>() { getDisplayName = v => v.label, allItems = DefDatabase <StatDef> .AllDefs, beingUsed = () => { List <StatDef> l = new List <StatDef>(); if (this.stuffProperties.statFactors != null) { foreach (var v in this.stuffProperties.statFactors) { l.Add(v.stat); } } return(l); }, onAdd = def => { StatModifier sm = new StatModifier() { stat = def, value = 0 }; this.stuffProperties.statFactors = Util.AddTo(this.stuffProperties.statFactors, sm); this.statFactors = Util.AddTo(this.statFactors, this.CreateStatModifierInput(sm)); }, onRemove = def => { this.statFactors?.RemoveAll(v => v.Parent.stat == def); this.stuffProperties.statFactors?.RemoveAll(v => v.stat == def); } }; this.ResetBuffers(); }