public virtual void OnEnable() { X = (StatPreset)target; if (X.Stats == null) { X.Stats = StatUtility.BaseCharacterStats(); } StatAsset = serializedObject.FindProperty("Stats"); }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.Space(); if (GUILayout.Button("Reset")) { X.Stats = StatUtility.BaseCharacterStats(); } EStatEditorTools.DrawStatGroup(StatAsset); EditorGUILayout.Space(); serializedObject.ApplyModifiedProperties(); }
static void MakeDefs() { if (!loaded) { TerrainDef rich = DefDatabase <TerrainDef> .GetNamed("SoilRich", true); rich.driesTo = DefDatabase <TerrainDef> .GetNamed("Soil", true); List <TerrainDef> deflist = new List <TerrainDef>(); foreach (TerrainDef olddef in DefDatabase <TerrainDef> .AllDefs.Where(def => def.changeable && !def.layerable)) { deflist.Add(olddef); } foreach (TerrainDef olddef in deflist) { TerrainDef newdef = new TerrainDef(); newdef.defName = olddef.defName + "_Scorched"; newdef.label = "scorched " + olddef.label; newdef.acceptFilth = olddef.acceptFilth; newdef.acceptTerrainSourceFilth = olddef.acceptTerrainSourceFilth; newdef.affordances = olddef.affordances; newdef.avoidWander = olddef.avoidWander; newdef.changeable = olddef.changeable; newdef.color = olddef.color; newdef.description = olddef.description; newdef.driesTo = olddef.driesTo; newdef.edgeType = olddef.edgeType; newdef.fertility = 0; newdef.graphic = olddef.graphic; newdef.holdSnow = olddef.holdSnow; newdef.layerable = olddef.layerable; newdef.passability = olddef.passability; newdef.pathCost = olddef.pathCost + 2; newdef.renderPrecedence = olddef.renderPrecedence; newdef.scatterType = olddef.scatterType; newdef.smoothedTerrain = olddef.smoothedTerrain; newdef.statBases = olddef.statBases; StatUtility.SetStatValueInList(ref newdef.statBases, StatDefOf.Beauty, -5); newdef.takeFootprints = olddef.takeFootprints; newdef.terrainFilthDef = olddef.terrainFilthDef; newdef.texturePath = olddef.texturePath; newdef.uiIcon = olddef.uiIcon; newdef.uiIconPath = olddef.uiIconPath; newdef.ResolveReferences(); newdef.PostLoad(); DefDatabase <TerrainDef> .Add(newdef); } loaded = true; } }
//检查是否能被控制 public bool canBeControled(Pawn becontroler) { if (becontroler.kindDef.defName.EqualsIgnoreCase("ra2_yuriyuri")) { return(false); } float result = StatUtility.GetStatValueFromList(becontroler.def.statBases, StatDefOf.PsychicSensitivity, 1.0f); if (result == 0) { return(false); } return(true); }
/// <summary> /// Calculates the extra yield for a given task and pawn. /// </summary> /// <param name="stat">The stat to check</param> /// <param name="req">The pawn we are checking the stat on</param> /// <returns>The extra yield</returns> private static float CuteboldCalculateExtraPercent(StatDef stat, StatRequest req, bool useMultiplier = true) { Pawn pawn = req.Pawn ?? (req.Thing is Pawn ? (Pawn)req.Thing : null); if (stat == null || req == null || pawn?.def != Cutebold_Assemblies.AlienRaceDef) { return(0f); } if (stat == StatDefOf.PlantHarvestYield) { useMultiplier = false; } float rawPercent = stat.Worker.GetValueUnfinalized(req, false); float pawnBasePercent = StatUtility.GetStatValueFromList(req.StatBases, stat, 1f); float defaultMaxPercent = stat.maxValue; float adaptationMultiplier = MiningMultiplier(pawn, useMultiplier); float extraPercent = (rawPercent < defaultMaxPercent) ? 0f : (rawPercent - defaultMaxPercent) * adaptationMultiplier; return((extraPercent > 0f) ? extraPercent : 0f); }
private static float SurvivalToolScore(Thing toolThing, List <StatDef> workRelevantStats) { SurvivalTool tool = toolThing as SurvivalTool; if (tool == null) { return(0f); } float optimality = 0f; foreach (StatDef stat in workRelevantStats) { optimality += StatUtility.GetStatValueFromList(tool.WorkStatFactors.ToList(), stat, 0f); } if (tool.def.useHitPoints) { float lifespanRemaining = tool.GetStatValue(ST_StatDefOf.ToolEstimatedLifespan, true) * ((float)tool.HitPoints * tool.MaxHitPoints); optimality *= LifespanDaysToOptimalityMultiplierCurve.Evaluate(lifespanRemaining); } return(optimality); }
public static void applyChanges() { Dictionary<string, List<float>> psycastStats = MorePsycasts_Mod.settings.psycastStats; foreach (string key in psycastStats.Keys) { StatUtility.SetStatValueInList(ref DefDatabase<AbilityDef>.GetNamed(key).statBases, StatDefOf.Ability_EntropyGain, psycastStats[key][0]); StatUtility.SetStatValueInList(ref DefDatabase<AbilityDef>.GetNamed(key).statBases, StatDefOf.Ability_PsyfocusCost, psycastStats[key][1]); StatUtility.SetStatValueInList(ref DefDatabase<AbilityDef>.GetNamed(key).statBases, StatDefOf.Ability_Duration, psycastStats[key][2]); } exchange(ref MorePsycasts_Mod.settings.debuff_hunger, ref HediffDefOf.MorePsycasts_PsychicInducedHunger.stages[0].hungerRateFactorOffset); exchange(ref MorePsycasts_Mod.settings.debuff_rest, ref HediffDefOf.MorePsycasts_PsychicInducedHunger.stages[0].restFallFactorOffset); exchange(ref MorePsycasts_Mod.settings.debuff_pain, ref HediffDefOf.MorePsycasts_PsychicInducedHunger.stages[0].painOffset); exchange(ref MorePsycasts_Mod.settings.stabilizing_touch_bleed_factor, ref HediffDefOf.MorePsycasts_StabilizingTouch.stages[0].totalBleedFactor); exchange(ref MorePsycasts_Mod.settings.healing_touch_natural_healing_factor, ref HediffDefOf.MorePsycasts_AcceleratedHealing.stages[0].naturalHealingFactor); if (MorePsycasts_Mod.settings.healing_touch_immunity_gain_speed_factor is null) MorePsycasts_Mod.settings.healing_touch_immunity_gain_speed_factor = HediffDefOf.MorePsycasts_AcceleratedHealing.stages[0].statFactors.GetStatFactorFromList(StatDefOf.ImmunityGainSpeedFactor); else StatUtility.SetStatValueInList(ref HediffDefOf.MorePsycasts_AcceleratedHealing.stages[0].statFactors, StatDefOf.ImmunityGainSpeedFactor, (float)MorePsycasts_Mod.settings.healing_touch_immunity_gain_speed_factor); if (MorePsycasts_Mod.settings.psychic_ressurection_severity_per_day is null) MorePsycasts_Mod.settings.psychic_ressurection_severity_per_day = -((HediffCompProperties_SeverityPerDay)HediffDefOf.MorePsycasts_PsychicRessurection.comps[0]).severityPerDay; else ((HediffCompProperties_SeverityPerDay)HediffDefOf.MorePsycasts_PsychicRessurection.comps[0]).severityPerDay = -(float)MorePsycasts_Mod.settings.psychic_ressurection_severity_per_day; }
// This is a janky mess and a half, but works! protected override Job TryGiveJob(Pawn pawn) { if (SurvivalToolsSettings.toolOptimization) { Pawn_SurvivalToolAssignmentTracker assignmentTracker = pawn.TryGetComp <Pawn_SurvivalToolAssignmentTracker>(); // Pawn can't use tools, lacks a tool assignment tracker or it isn't yet time to re-optimise tools if (!pawn.CanUseSurvivalTools() || assignmentTracker == null || Find.TickManager.TicksGame < assignmentTracker.nextSurvivalToolOptimizeTick) { return(null); } // Check if current tool assignment allows for each tool, auto-removing those that aren't allowed. SurvivalToolAssignment curAssignment = assignmentTracker.CurrentSurvivalToolAssignment; List <Thing> heldTools = pawn.GetHeldSurvivalTools().ToList(); foreach (Thing tool in heldTools) { if ((!curAssignment.filter.Allows(tool) || !pawn.NeedsSurvivalTool((SurvivalTool)tool)) && assignmentTracker.forcedHandler.AllowedToAutomaticallyDrop(tool)) { return(pawn.DequipAndTryStoreSurvivalTool(tool)); } } // Look for better alternative tools to what the colonist currently has, based on what stats are relevant to the work types the colonist is assigned to List <Thing> heldUsableTools = heldTools.Where(t => heldTools.IndexOf(t).IsUnderSurvivalToolCarryLimitFor(pawn)).ToList(); List <Thing> mapTools = pawn.MapHeld.listerThings.AllThings.Where(t => t is SurvivalTool).ToList(); List <StatDef> workRelevantStats = pawn.AssignedToolRelevantWorkGiversStatDefs(); Thing curTool = null; Thing newTool = null; float optimality = 0f; foreach (StatDef stat in workRelevantStats) { curTool = pawn.GetBestSurvivalTool(stat); optimality = SurvivalToolScore(curTool, workRelevantStats); foreach (Thing potentialToolThing in mapTools) { SurvivalTool potentialTool = (SurvivalTool)potentialToolThing; if (StatUtility.StatListContains(potentialTool.WorkStatFactors.ToList(), stat) && curAssignment.filter.Allows(potentialTool) && potentialTool.BetterThanWorkingToollessFor(stat) && pawn.CanUseSurvivalTool(potentialTool.def) && potentialTool.IsInAnyStorage() && !potentialTool.IsForbidden(pawn) && !potentialTool.IsBurning()) { float potentialOptimality = SurvivalToolScore(potentialTool, workRelevantStats); float delta = potentialOptimality - optimality; if (delta > 0f && pawn.CanReserveAndReach(potentialTool, PathEndMode.OnCell, pawn.NormalMaxDanger())) { newTool = potentialTool; optimality = potentialOptimality; } } } if (newTool != null) { break; } } // Return a job based on whether or not a better tool was located // Failure if (newTool == null) { SetNextOptimizeTick(pawn); return(null); } // Success int heldToolOffset = 0; if (curTool != null && assignmentTracker.forcedHandler.AllowedToAutomaticallyDrop(curTool)) { pawn.jobs.jobQueue.EnqueueFirst(pawn.DequipAndTryStoreSurvivalTool(curTool, false)); heldToolOffset = -1; } if (pawn.CanCarryAnyMoreSurvivalTools(heldToolOffset)) { Job pickupJob = new Job(JobDefOf.TakeInventory, newTool) { count = 1 }; return(pickupJob); } // Final failure state SetNextOptimizeTick(pawn); } return(null); }
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); }
// This is a janky mess and a half, but works! protected override Job TryGiveJob(Pawn pawn) { Pawn_SurvivalToolAssignmentTracker assignmentTracker = pawn.TryGetComp <Pawn_SurvivalToolAssignmentTracker>(); // Pawn can't use tools, lacks a tool assignment tracker or it isn't yet time to re-optimise tools if (!pawn.CanUseSurvivalTools() || assignmentTracker == null || Find.TickManager.TicksGame < assignmentTracker.nextSurvivalToolOptimizeTick) { return(null); } if (SurvivalToolsSettings.toolAutoDropExcess) { assignmentTracker.CheckToolsInUse(); // Check if current tool assignment allows for each tool, auto-removing those that aren't allowed. SurvivalToolAssignment curAssignment = assignmentTracker.CurrentSurvivalToolAssignment; List <SurvivalTool> heldTools = pawn.GetHeldSurvivalTools(); foreach (SurvivalTool tool in heldTools) { if ((!curAssignment.filter.Allows(tool) || !pawn.NeedsSurvivalTool(tool) || !tool.InUse) && !tool.Forced && StoreUtility.TryFindBestBetterStoreCellFor(tool, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(tool), pawn.Faction, out IntVec3 c)) { return(pawn.DequipAndTryStoreSurvivalTool(tool, true, c)); } } } if (SurvivalToolsSettings.toolOptimization) { SurvivalToolAssignment curAssignment = assignmentTracker.CurrentSurvivalToolAssignment; List <StatDef> workRelevantStats = pawn.AssignedToolRelevantWorkGiversStatDefs(); List <Thing> mapTools = pawn.MapHeld.listerThings.AllThings.Where(t => t is SurvivalTool).ToList(); SurvivalTool curTool = null; SurvivalTool newTool = null; float optimality = 0f; foreach (StatDef stat in workRelevantStats) { curTool = pawn.GetBestSurvivalTool(stat); optimality = SurvivalToolScore(curTool, workRelevantStats); foreach (SurvivalTool potentialTool in mapTools) { if (StatUtility.StatListContains(potentialTool.WorkStatFactors.ToList(), stat) && curAssignment.filter.Allows(potentialTool) && potentialTool.BetterThanWorkingToollessFor(stat) && pawn.CanUseSurvivalTool(potentialTool.def) && potentialTool.IsInAnyStorage() && !potentialTool.IsForbidden(pawn) && !potentialTool.IsBurning()) { float potentialOptimality = SurvivalToolScore(potentialTool, workRelevantStats); float delta = potentialOptimality - optimality; if (delta > 0f && pawn.CanReserveAndReach(potentialTool, PathEndMode.OnCell, pawn.NormalMaxDanger())) { newTool = potentialTool; optimality = potentialOptimality; } } } if (newTool != null) { break; } } // Return a job based on whether or not a better tool was located // Failure if (newTool == null) { SetNextOptimizeTick(pawn); return(null); } // Success int heldToolOffset = 0; if (curTool != null && !curTool.Forced) { pawn.jobs.jobQueue.EnqueueFirst(pawn.DequipAndTryStoreSurvivalTool(curTool, false)); heldToolOffset = -1; } if (pawn.CanCarryAnyMoreSurvivalTools(heldToolOffset)) { Job pickupJob = new Job(JobDefOf.TakeInventory, newTool) { count = 1 }; return(pickupJob); } } // Final failure state SetNextOptimizeTick(pawn); return(null); }
//Enumerator to process the existing ThingDefs public static IEnumerable <ThingDef> ImpliedThingDefs() { int i = 0; foreach (ThingDef rock in from def in DefDatabase <ThingDef> .AllDefs.ToList <ThingDef>() where def.building != null && def.building.isNaturalRock && !def.building.isResourceRock && !def.defName.Contains("Engraved") select def) { //Building a new ThingDef from the root up! ThingDef engraved = new ThingDef(); //BuildingNaturalBase engraved.category = ThingCategory.Building; engraved.selectable = true; engraved.drawerType = DrawerType.MapMeshOnly; engraved.filthLeaving = RimWorld.ThingDefOf.Filth_RubbleRock; engraved.scatterableOnMapGen = false; //RockBase engraved.thingClass = typeof(Mineable); //engraved.graphicData.texPath = "WallsEngraved"; //Overwritten engraved.graphicData = new GraphicData(); engraved.graphicData.graphicClass = typeof(Graphic_Random); engraved.graphicData.linkType = LinkDrawerType.CornerFiller; engraved.graphicData.linkFlags = LinkFlags.MapEdge | LinkFlags.Rock; engraved.altitudeLayer = AltitudeLayer.Building; engraved.passability = Traversability.Impassable; engraved.blockWind = true; engraved.castEdgeShadows = true; engraved.fillPercent = 1; engraved.coversFloor = true; engraved.neverMultiSelect = true; engraved.rotatable = false; //engraved.saveCompressible = true; //Overwritten engraved.holdsRoof = true; engraved.staticSunShadowHeight = 1.0F; engraved.blockLight = true; engraved.mineable = true; //StatUtility.SetStatValueInList(ref engraved.statBases, StatDefOf.Flammability, 0F); //Overwritten engraved.building = new BuildingProperties(); engraved.building.isInert = true; //engraved.building.isNaturalRock = true; //Overwritten //engraved.building.canBuildNonEdificesUnder = false; //Overwritten //engraved.building.deconstructible = false; //Private variable... //UglyRockBase StatUtility.SetStatValueInList(ref engraved.statBases, StatDefOf.Flammability, 0F); //StatUtility.SetStatValueInList(ref engraved.statBases, StatDefOf.Beauty, -2F); //Overwritten engraved.building.mineableYieldWasteable = false; //StoneBase //engraved.defName = "Engraved" + rock.defName; //Overwritten //engraved.label = "engraved " + rock.label; //Overwritten //engraved.description = "EngravedStoneDesc".Translate(); //Overwritten engraved.graphicData.color = rock.graphicData.color; StatUtility.SetStatValueInList(ref engraved.statBases, StatDefOf.MaxHitPoints, rock.GetStatValueAbstract(StatDefOf.MaxHitPoints)); engraved.building.mineableThing = rock.building.mineableThing; engraved.building.mineableDropChance = rock.building.mineableDropChance; //engraved.building.smoothedThing = rock.building.smoothedThing; //Can't have multiple things smooth to the same thing. //SmoothedStoneBase engraved.defName = "Engraved" + rock.defName; engraved.label = "EngravedStoneLabel".Translate(new object[] { rock.label }); engraved.description = "EngravedStoneDesc".Translate(new object[] { rock.label }); engraved.graphicData.texPath = "WallsEngraved"; StatUtility.SetStatValueInList(ref engraved.statBases, StatDefOf.Beauty, 1F); StatUtility.SetStatValueInList(ref engraved.statBases, StatDefOf.MarketValue, 18F); engraved.building.isNaturalRock = false; //Unfortunately this needs to remain true to prevent smoothed walls from defaulting to deconstructible. engraved.building.canBuildNonEdificesUnder = true; engraved.saveCompressible = false; //Art StatUtility.SetStatValueInList(ref engraved.statBases, StatDefOf.WorkToBuild, 2260F); engraved.comps = new List <CompProperties>(); engraved.comps.Add(new CompProperties(typeof(CompQuality))); engraved.comps.Add(new CompProperties_Art { nameMaker = RimWorld.RulePackDefOf.NamerArtSculpture, descriptionMaker = RulePackDefOf.ArtDescription_EngravedWall, canBeEnjoyedAsArt = true }); engraved.inspectorTabs = new List <Type>(); engraved.inspectorTabs.Add(typeof(ITab_Art)); engraved.modContentPack = thisPack; Log.Message($"Created {engraved.defName} from {rock.defName}"); yield return(engraved); i++; } yield break; }
internal static bool _ShouldShowFor(this StatWorker obj, BuildableDef eDef) { // Need some reflection to access the internals StatDef _stat = typeof(StatWorker).GetField("stat", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj) as StatDef; if ( (!_stat.showIfUndefined) && (!StatUtility.StatListContains(eDef.statBases, _stat)) ) { return(false); } ThingDef thingDef = eDef as ThingDef; if ( (thingDef != null) && (thingDef.category == ThingCategory.Pawn) && ( (!_stat.showOnPawns) || ( (!_stat.showOnHumanlikes) && (thingDef.race.Humanlike) ) || ( (!_stat.showOnAnimals) && (thingDef.race.Animal) ) || ( (!_stat.showOnMechanoids) && (thingDef.race.IsMechanoid) ) ) ) { return(false); } if ( (_stat.category == StatCategoryDefOf.BasicsPawn) || (_stat.category == StatCategoryDefOf.PawnCombat) ) { if (thingDef != null) { return(thingDef.category == ThingCategory.Pawn); } return(false); } if ( (_stat.category == StatCategoryDefOf.PawnMisc) || (_stat.category == StatCategoryDefOf.PawnSocial) || (_stat.category == StatCategoryDefOf.PawnWork) ) { if ( (thingDef != null) && (thingDef.category == ThingCategory.Pawn) ) { return(thingDef.race.Humanlike); } return(false); } if (_stat.category == StatCategoryDefOf.Building) { if (thingDef == null) { return(false); } if (_stat == StatDefOf.DoorOpenSpeed) { return ((thingDef.thingClass == typeof(Building_Door)) || (thingDef.thingClass.IsSubclassOf(typeof(Building_Door)))); } return(thingDef.category == ThingCategory.Building); } if (_stat.category == StatCategoryDefOf.Apparel) { if (thingDef == null) { return(false); } if (!thingDef.IsApparel) { return(thingDef.category == ThingCategory.Pawn); } return(true); } if (_stat.category == StatCategoryDefOf.Weapon) { if (thingDef == null) { return(false); } if (!thingDef.IsMeleeWeapon) { return(thingDef.IsRangedWeapon); } return(true); } if (_stat.category == StatCategoryDefOf.BasicsNonPawn) { if (thingDef != null) { return(thingDef.category != ThingCategory.Pawn); } return(true); } if (_stat.category.displayAllByDefault) { return(true); } object[] objArray = new object[4]; string str1 = "Unhandled case: "; StatDef statDef = _stat; string str2 = ", "; BuildableDef buildableDef = eDef; objArray[0] = (object)str1; objArray[1] = (object)statDef; objArray[2] = (object)str2; objArray[3] = (object)buildableDef; Verse.Log.Error(string.Concat(objArray)); return(false); }
public static IEnumerable <ThingDef> ImpliedThingDefs() { var i = 0; Log.Message("[KK]Generating pawn"); //generating Foreach foreach (var metal in from def in DefDatabase <ThingDef> .AllDefs.ToList() where def.stuffProps != null && def.stuffProps.categories.Contains(StuffCategoryDefOf.Metallic) select def) { //referencing Template var thingAnimal = KK_DefOf.Megascarab; var bug = new ThingDef { shortHash = (ushort)(thingAnimal.shortHash + i + 1) }; //aux floats var marketValue = metal.statBases.GetStatFactorFromList(StatDefOf.MarketValue); var meleeWeapon_CooldownMultiplier = metal.stuffProps.statFactors.GetStatFactorFromList(StatDefOf.MeleeWeapon_CooldownMultiplier); var sharpDamageMultiplier = metal.statBases.GetStatFactorFromList(StatDefOf.SharpDamageMultiplier); var bluntDamageMultiplier = metal.statBases.GetStatFactorFromList(StatDefOf.BluntDamageMultiplier); //Defining ThingDef //BasePawn bug.thingClass = typeof(Pawn); bug.category = ThingCategory.Pawn; bug.selectable = true; bug.tickerType = TickerType.Normal; bug.altitudeLayer = AltitudeLayer.Pawn; bug.useHitPoints = false; bug.hasTooltip = true; bug.soundImpactDefault = DefDatabase <SoundDef> .GetNamed("BulletImpact_Flesh"); StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.Mass, 70); bug.inspectorTabs = new List <Type> { typeof(ITab_Pawn_Health), typeof(ITab_Pawn_Needs), typeof(ITab_Pawn_Character), typeof(ITab_Pawn_Training), typeof(ITab_Pawn_Gear), typeof(ITab_Pawn_Guest), typeof(ITab_Pawn_Prisoner), typeof(ITab_Pawn_Social), typeof(ITab_Pawn_Log) }; bug.comps = new List <CompProperties> { new CompProperties(typeof(CompAttachBase)) }; bug.drawGUIOverlay = true; //AnimalThingBase bug.race = thingAnimal.race; StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.Flammability, 1); StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.LeatherAmount, 0); bug.race.thinkTreeMain = KK_DefOf.Animal; bug.race.thinkTreeConstant = KK_DefOf.AnimalConstant; bug.race.hasGenders = false; bug.race.manhunterOnDamageChance = 0.2f; bug.race.manhunterOnTameFailChance = 0.018f; bug.race.hediffGiverSets = thingAnimal.race.hediffGiverSets; bug.recipes = thingAnimal.recipes; //AnimalThingBase StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.ToxicSensitivity, 0); bug.race.foodType = thingAnimal.race.foodType; //BugBase StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.ComfyTemperatureMin, -20); bug.race.body = KK_DefOf.BeetleLike; bug.race.useMeatFrom = KK_DefOf.Megaspider; bug.race.wildness = 0.95f; bug.race.soundMeleeHitPawn = SoundDefOf.Pawn_Melee_Punch_HitPawn; bug.race.soundMeleeHitBuilding = SoundDefOf.Pawn_Melee_Punch_HitBuilding; bug.race.soundMeleeMiss = SoundDefOf.Pawn_Melee_Punch_Miss; bug.tradeTags = new List <string> { "StandardAnimal", "AddedBug" }; int amount() { if (metal.smallVolume) { return(150); } return(15); } bug.defName = "Bug_" + metal.defName; bug.label = metal.label + " scarab"; bug.description = "Scarab containing considerable amounts of " + metal.label + ". Quite valuable and the metal can be extracted from it's corpse."; bug.butcherProducts = new List <ThingDefCountClass> { new ThingDefCountClass(metal, amount()) }; StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.ArmorRating_Blunt, 0.3f); StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.ArmorRating_Sharp, 0.5f); StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.MarketValue, marketValue * 100f); StatUtility.SetStatValueInList(ref bug.statBases, StatDefOf.MoveSpeed, (float)Math.Round(4.7f / meleeWeapon_CooldownMultiplier, 3)); bug.race.baseBodySize = 0.4f; bug.race.baseHungerRate = 0.2f; bug.race.baseHealthScale = 0.8f; bug.race.lifeExpectancy = 10; bug.tools = new List <Tool> { new Tool { capacities = new List <ToolCapacityDef> { KK_DefOf.Bite }, power = 7 * sharpDamageMultiplier, cooldownTime = 2.5f * meleeWeapon_CooldownMultiplier, linkedBodyPartsGroup = KK_DefOf.Mouth }, new Tool { label = "head", capacities = new List <ToolCapacityDef> { KK_DefOf.Blunt }, power = 4 * bluntDamageMultiplier, cooldownTime = 1.65f * meleeWeapon_CooldownMultiplier, linkedBodyPartsGroup = KK_DefOf.HeadAttackTool, chanceFactor = 0.2f } }; bug.race.lifeStageAges = new List <LifeStageAge> { new LifeStageAge { def = KK_DefOf.EusocialInsectLarva, minAge = 0 }, new LifeStageAge { def = KK_DefOf.EusocialInsectJuvenile, minAge = 0.03f }, new LifeStageAge { def = KK_DefOf.EusocialInsectAdult, minAge = 0.4f, soundWounded = KK_DefOf.Pawn_Megascarab_Wounded, soundDeath = KK_DefOf.Pawn_Megascarab_Death, soundCall = KK_DefOf.Pawn_Megascarab_Call, soundAngry = KK_DefOf.Pawn_Megascarab_Angry } }; yield return(bug); i++; } }