diff --git a/About/About.xml b/About/About.xml index a113fca..7d1a228 100644 --- a/About/About.xml +++ b/About/About.xml @@ -2,6 +2,7 @@ Community Framework ISOREX, Turnovus, and community contributors. + 1.4.0
  • 1.2
  • 1.3
  • diff --git a/About/Manifest.xml b/About/Manifest.xml index e1630c1..883300d 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@ CommunityFramework - 1.3.0 + 1.4.0
  • Harmony
  • diff --git a/Common/Assemblies/communityframework.dll b/Common/Assemblies/communityframework.dll index 6f2776e..115a00c 100644 Binary files a/Common/Assemblies/communityframework.dll and b/Common/Assemblies/communityframework.dll differ diff --git a/Common/Assemblies/communityframework.xml b/Common/Assemblies/communityframework.xml new file mode 100644 index 0000000..5f01fb8 --- /dev/null +++ b/Common/Assemblies/communityframework.xml @@ -0,0 +1,2703 @@ + + + + communityframework + + + + + Sets the parent hediff's severity based on worn apparel. + + + If wornSeverity is unset, uses the hediff's initial severity. + If apparelDefs is unset, checks if any worn apparel have a matching + . + + + + + Pre-cast reference to this comp's + . + + + + + The severity to apply to the parent Hediff if any of the + required apparel items are worn. Equal to + Props.wornSeverity, or the parent Hediff's + initialSeverity if the former is null. + + + + + Run each time the comp is ticked. Checks the affected Pawn's + apparel and updates the parent Hediff's severity whenever + Props.tickInterval ticks have passed. + + + Unused in this override. + + + + + Used internally to determine if a given apparel item should set the + parent Hediff's severity to WornSeverity. + + + The item to check. + + + true if the apparel item's Def is in + Props.apparelDefs, or if Props.apperalDefs is empty + and the apparel item causes the parent Hediff when worn. + + + + + Cached tick offset, calculated from the affected pawn's + HashOffset. + + + Based on + + + + + Used internally to determine if the current game tick is a "cheap" + tick. + + + Based on + + + + + Stores the affected pawn's HashOffset whenever this comp is + initialized. + + + Based on + + + + + CompProperties for . + + + + + Severity applied when an item from apparelDefs is actively + equipped. If null, then the parent Hediff's + initialSeverity is used. + + + + + Severity applied when no items from apparelDefs are actively + equipped. + + + + + A list of ThingDefs, ideally apparel items. The parent + Hediff's severity will be set to wornSeverity if the + affected Pawn is wearing any of these. + + + + + The affected Pawn's apparel will be checked at an interval + of this many ticks. + + + + + No-arg constructor, automatically sets the compClass to + + + + + + The functional component of + When applied to an apparel item, it can play a sound whenever the item + is put on or taken off. + + + + + Pre-cast reference to this comp's respective CompProperties. + + + + + Runs after the parent Thing is put on by a Pawn. + Plays the SoundDef stored in Props.wornSound. + + The Pawn putting on the item. + + + + Runs after the parent Thing is taken off of a Pawn. + Plays the SoundDef stored in Props.removedSound. + + The Pawn that the item was removed from. + + + + + The properties that control a respective + When applied to an apparel item, it can play a sound whenever the item + is put on or taken off. + + + + + The sound to play after the item is put on. + + + + + The sound to play after the item is taken off. + + + + + Default constructor, sets compClass to + ThingComp_OnWearSound. + + + + + Override of method used to report errors made by modders using this + ThingComp. This will inform the modder if they have applied + the ThingComp to something other than an apparel item. + + The ThingDef of the item that the + ThingComp was applied to. + A full list of config errors. + + + + Automatically repairs a specified hitpoint-based (non-pawn) item. + Example implementation of + and designed for use with . + + + + + Pre-cast reference to this class's + . + + + + + This method is run whenever the ThingComp is ticked. If the + current in-game tick is a "cheap" tick, then the comp's parent + ThingWithComps will regenerate a single hitpoint. + + + + + This method returns text that is displayed whenever this comp's + parent ThingWithComps is selected in-game. It will display + the number of ticks between each hitpoint gained, but only if + developer mode is turned on. + + + + + + CompProperties for use with . + Allows specifying the tick interval in XML, and auto-assigns the + appropriate class. + + + + + The number of ticks between each hitpoint repaired. + + + + + No-arg contructor. Sets compClass to + + + + + + This method will return a list of configuration errors, notifying + modders that they have set up this CompProperties + incorrectly in their XML. Will print errors if the parent + ThingWithComps uses a TickerType other than + Normal. + + + The ThingDef of this comp's parent ThingWithComps. + + + An IEnumerable of error messages. + + + + + Minifies or destroys the parent Thing if it wouldn't be allowed + to be placed at its current location. Must be used with one or more + PlaceWorkers. + + + + + Pre-cast reference to this comp's CompProperties_Validator. + + + + + Called every tick. Every props.tickInterval ticks, this + method will check if its parent is allowed to be where it is + according to its place workers, and will minify or destroy it if + not. + + + + + This method is used to display information on the in-game status + panel. If the game is running in developer mode, this method will + give the number of place workers, and the ToString of the + first 3 place workers found. + + + + + + CompProperties for use with . + Allows specifying the tick interval in XML, auto-assigns the + appropriate class, and disables the comp if misconfigured. + + + + + The number of in-game ticks that pass before each time the + PlaceWorker validation check is run. A lower number will run + the check more frequently, but can cause slowdown if the parent + ThingWithComps has computationally-expensive + PlaceWorkers. For reference, at 1x speed, there are 60 ticks + in a single second. + + + + + Whether the validator should run its checks in-game. True by + default, unless it's misconfigured, in which case checks will not + run. + + + + + No-arg constructor , sets the value of compClass to the type + of CompValidator. + + + + + Returns an IEnumerable of strings, each describing an error + that the XML modder made while setting up this comp properties. In + this case, it will return strings if the parent + ThingWithComps does not have any PlaceWorkers set, or + if its ticker type is not Normal. + + Not used in this override. + Strings containing any errors caused by bad XML. + + + + A ThingComp which implements tick distribution to reduce lag + spikes and microstuttering when a large number of instances exist. + + + Only really necessary for comps which are expected to be on large + numbers of Things, for example stuffed buildings. + + + + + Method used to determine if the current in-game tick is a targeted + "cheap" tick. + + + The number of ticks between each method call. + + + true if the current tick is a "cheap" tick, false for + any other tick. + + + + + Method run whenever the parent ThingWithComps is spawned in. + Sets the hash offset to match the parent's thingIDNumber, so + that seperate instances of the same parent ThingWithComps + won't all run their methods at the exact same tick. Since + hashOffset is cached, this allows the comp to run faster + than if it were to call .hashOffset() every tick. + + + Unused in this context. + + + + + The properties that determine the behavior of + HediffComp_CraftedQualityOffset. + + + + + Represents an individual stage of the quality offset effect, with + the minimum quality required for it to occur. + + + + + The minimum severity for this stage to occur. + + + + + The quality offset applied at this stage. + + + + + The list of Stages, each stage having its own offset and + minimum severity. + + + + + The chance, represented as a decimal percent, that the offset will + be applied to the crafted item. + + + + + Constructor that automatically attaches the required CompClass to + these properties. + + + + + A hediff comp that allows Hediffs to increase or decrease the + value of items crafted by the Pawn that the Hediff is + applied to, at random. + + + + + Pre-cast reference to the relevant + CompProperties_CraftedQualityOffset. + + + + + The current number of quality levels that the quality of the + completed item should be increased or decreased by, calculated from + the parent Hediff's severity. + + + + + The chance, represented as a decimal percent, that the offset will + be applied to the crafted item. + + + + + Used to display additional information on the parent + Hediff's in-game tooltip. + + + + + Interface to be implented by a HediffComp. Contains methods that + are run whenever the affected Pawn has a hediff applied to it. + + + Powered by + + + + + Method run whenever the affected Pawn has a new + Hediff applied to it. + + The Hediff that was just added. + + + + The HediffProperties used to provide instructions for + HediffComp_MultiplyOtherHediffDuration. The compClass + must be manually set to either + HediffComp_MultiplyOtherHediffDuration or + HediffComp_MultiplyOtherHediffSeverity. + + + + + A list of HediffDefs. If a sibling Hediff is added + with one of these Defs, then it will have its + HediffComp_Disappears.ticksToDisappear multiplied by + multiplier. + + + + + The value that affected Hediffs will have their durations + multiplied by. + + + + + If true, then the comp will affect newly-added + Hediffs. Does not affect conditions that are already + present. + + + + + If true, then the comp will affect Hediffs that were + already present when the parent condition was applied. Does not + affect other conditions that were added after the parent. + + + + + When a sibling Hediff is applied, this comp with multiply the + sibling's HediffComp_Disappears.ticksToDisappear by a set + amount. Can be used to artificially increase or decrease the lengths of + certain Hediffs. + + + + + Pre-cast reference to this comp's corresponding properties, + HediffCompProperties_MultiplyOtherHediff. + + + + + Run when another Hediff is added to the parent's + Pawn. Multiplies the other Hediff's duration by a set + amount, if the other Hediff's Def is in + Props.affectedHediffs, and if Props.affectsNewHediffs + is true. + + The Hediff being added. + + + + Run when the parent is applied to a + . If Props.affectsExistingHediff is + true, then this override will go through each health + condition already present on the target Pawn, and, if the + condition's is in + Props.affectedHediffs, its duration will be multiplied by + Props.multiplier. + + + The that caused the parent condition to be + applied. Unused here. + + + + + Internal helper method used to adjust the duration of other + s where applicable. This method ensures that + the targeted health condition is not the comp's parent condition, + and that the condition's is contained in + Props.affectedHediff before taking effect, as well as + ensring that it has the required + , so doing those comparisons + externally is unnecessary. + + + The to possibly adjust. + + + + + When a sibling Hediff is applied, this comp with multiply the + sibling's Severity by a set amount. Can be used to artificially + increase or decrease the magnitude or duration of certain + Hediffs. + + + + + Pre-cast reference to this comp's corresponding properties, + HediffCompProperties_MultiplyOtherHediff. + + + + + Run when another Hediff is added to the parent's + Pawn. Multiplies the other Hediff's severity by a set + amount, if the other Hediff's Def is in + Props.affectedHediffs, and if Props.affectsNewHediffs + is true. + + The Hediff being added. + + + + Run when the parent is applied to a + . If Props.affectsExistingHediff is + true, then this override will go through each health + condition already present on the target Pawn, and, if the + condition's is in + Props.affectedHediffs, its severity will be multiplied by + Props.multiplier. + + + The that caused the parent condition to be + applied. Unused here. + + + + + Internal helper method used to adjust the severity of other + s where applicable. This method ensures that + the targeted health condition is not the comp's parent condition, + and that the condition's is contained in + Props.affectedHediff before taking effect, so doing those + comparisons externally is unnecessary. + + + The to possibly adjust. + + + + + The base HediffProperties used to provide instructions for + HediffComp_PainFromSeverity + + + + + If this is set to true, then the Pawn's current pain + will be divided by their maximum pain shock threshold. If + false, it will always be the exact value. + + + + + Boilerplate constructor, sets the comp's class to + HediffComp_SeverityFromPain. + + + + + A HediffComp that directly sets the parent + Hediff.Severity to match the Pawn's current pain level. + + + + + Pre-cast reference to this comp's corresponding properties, + HediffCompProperties_SeverityFromPain. + + + + + An internal function used to calculate the intended severity + setting, accounting for Props.usePainThreshold. + + The intended severity setting. + + + + Called per-tick, updates the parent's severity level to the + intended amount. + + + Used by HediffComps to adjust the parent's severity + incrementally, unused in this case. + + + + + Used to display additional information in the parent's in-game + tooltip. In this case, it displays the pawn's current pain level. + + + + + The properties that determine the behavior of + HediffComp_SeverityFromSkill. + + + + + A list of skills that will affect the severity of the parent + Hediff. + + + + + The intended maximum severity, reached when the pawn acquires level + 20 in all relevant skills. + + + + + If the average of relevant skills is below this value, then the + parent Hediff's severity will always be 0. + + + + + Constructor that automatically attaches the required CompClass to + these properties. + + + + + A HediffComp that adjusts its parent's severity by the skill + levels of the pawn it is applied to. Most likely incompatible with + any other severity-adjusting HediffComps. + + + + + Pre-cast reference to the comp's properties. + + + + + The average of parent.pawn's relevant skills, as defined in + Props.skills. + + + + + Returns a string containing a multi-line, bulleted list of skills + that affect severity. + + + + + Used to display additional information on the parent + Hediff's in-game tooltip. + + + + + This method is called every tick, and directly sets the parent + Hediff's current severity to the appropriate value based + on the pawn's current set of skills. + + Normally, this would be used to + increase or decrease the parent Hediff's severity through + smaller increments. Here, it does nothing. + + + + A base class for s, used to define custom behaviors that + affect the maximum amount of energy that a sibling can + store. + + + + + Augments the amount of energy that can be stored by a + attached to any with the parent . + + + The whose that + is being adjusted for. + + + The vanilla value of from comp. + + The new amount of additional energy that the battery can accept. + + + + Any will never be able to recharge if its parent has this + extension in its . + + + + + + + + A that provides more customization options for any + attached to s that use the extension's + parent . + + + + + If true, batteries with this extension will not lose 5W of energy per day, as is + hardcoded in vanilla. + + + + + If true, then the battery will start with a full charge when it is crafted, + built, or otherwise initially created. + + + + + If true, batteries with this extension will not lose power during the short + circuit event, and will not contribute to the size of the short circuit explosion. + + + + + + + + After a with the parent is initially + created, this method will fully charge it if is a battery and if + is true + + + + + + A that provides more customization options for + s that define electrical objects. + + + + + If true, this can be a culprit of short circuits, like + vanilla power conduits. + + + + + A that, when applied to a building's + , can allow that building to conditionally block + the placement of other buildings. + + + + + Determines whether or not another building is blocked by the + presence of this building in the same tile. + + + This method does know which building stage the parent building is + in (blueprint, frame, or finished). For the other building, it can + be assumed that it always a blueprint. + + + The , most likely a + , of the building that the player is trying + to place over the parent building. + + + The building stage of the existing building, meaning the one that + has this extension attached to it. + It is not recommended to use this parameter without good reason, as + changing the acceptance of overlapping buildings based on building + phase can be very inconsistent. However, the ability exists, should + you need it. + + + true, if the placement is blocked, and the new building is + not allowed to be blaced over the existing one. false + if the building is not directly blocked, and is allowed to be + placed as long as all other external conditions for building + placement are met. + + + + + A that will prevent impassable structures + like walls, vents, and coolers from being manually placed on top of + whatever building has the extension, even if it would normally be + possible for such overlap to happen otherwise (i.e. with conduits and + floor coverings). + + + + + + + + cache containing the framework's XML + s for easy reference in C# assemblies. + + + + + The additional mass that this creature can carry when part of a + caravan. + + + + + A collection of patches that alter the behaviors of batteries, allowing for more control + over custom batteries. + + + + + Checks if the battery is allowed to discharge by . + + + The of the battery being checked. + + + true if the battery's does not have a + , or if its + is false. true otherwise. + + + + + This patch modifies the amount of additional energy that a battery can accept. + + + + + Checks the battery's for any extension that derives + , then adjusts the return value of the method + accordingly. + + + The being checked. + + + The amount of additional energy that the battery will accept. + + + + + This patch alters whether or not a battery self-discharges the hardcoded amount of 5W + per day. + + + + + Injects a condition into that checks if the + parent's contains a , + then checks if is true. If the + battery has been configured never to discharge, then it will skip over the + instructions for self-discharge. + + The instructions given to the transpiler. + used for creating labels + A patched list of instructions + + + + This patch prevents batteries from showing the "self-discharging" line on the + inspection pane if the battery has been configured not to self-discharge. + + + + + Injects a condition into that + checks if the parent's contains a + , then checks if + is true. If the battery has + been configured never to discharge, then it will skip over the instructions to + include the string "Self-discharging: 5W". + + The instructions given to the transpiler. + + + + Adds patches that will run before and after any recipe is complete. + Each patch will check the recipe for a + extension, and will run the relevant method from each + found. + + + + + A collection of patches that affect the short circuit incident. + + + + + This patch modifies the behaviors of batteries with + during a short circuit. + + + + + + + + + + + + This patch allows custom buildings to act as short circuit sources, like vanilla + conduits. + + + + + Helper method for adding custom short circuit sources to the list of conduits found + inside of the incident worker for the short circuit incident. + + The original list of conduits. + The map that the short circuit is occuring on. + + A copy of list with additional short-circuitable buildings in map. + + + + + A collection of patches that run additional methods after a thing is made. + + + + + This patch modifies the player's ability to place blueprints over other + s that occupy any of the same cells as the + blueprint. + + + + + This patch modifies the player's ability to place blueprints over + other s that occupy any of the same cells as the + blueprint. + + + + + After all of the vanilla checks have passed successfully, this + postfix checks that any additional conditions added by the + framework have also been met. + + + Initially stores the result of the original method. If this + value is true, but the new conditions defined by the + framework are not met, then it will be changed to false. + + + The of the building that the player is + attempting to place. + + + The that the game is checking if + newDef can be placed on top of. + + + + + Abstract base class containing methods to run upon completing certain + recipes. + + + + + Method to run when a recipe is completed, but before the products + of the recipe are created. + + The def of the recipe done. + The pawn doing the recipe + + A list of things consumed by the recipe + + + The IBillGiver of whatever produced the recipe bill + + The style precepts of the worker + + The style to be applied, independent of ideoligious precepts. + + + Index of the desired graphic override. + + + + + Method to run when a recipe is completed, after the products are + created and post-processed. + + + Any Things returned by this method will be post-processed + automatically. This means that CompQuality, CompArt, + ideo styles, and minification will be taken care of for you. + + + A list of finalized things produced by the recipe. + + The def of the recipe done. + The pawn doing the recipe + + A list of things consumed by the recipe + + + The IBillGiver of whatever produced the recipe bill + + The style precepts of the worker + + The style to be applied, independent of ideoligious precepts. + + + Index of the desired graphic override. + + + Any additional Things to be added to recipe products. + + + + + A base for making recipes that randomize the style of crafted + products. + + + + + If true, then any ideological styles that the crafter has will override the + randomly-assigned style, assuming that any such style exists for the crafted product. + + + + + A percent chance that the crafted product will have its default appearence, instead of + being given one randomly. + + + + + A list of styles to be chosen from when randomly applying a style to the product of a + given recipe. + + + The recipe being performed. + + + A list of styles that may be randomly applied to the products of recipe + + + + + + + + An that gives a recipe's products a random style from a + predefined list. + + + + + A list of styles to be chosen from randomly. + + + + + + + + An that gives a recipe's products a random style the product's + own list of randomly-selected styles. + + + + + + + + that ensures that the parent + is not places on the same cell as any other + that has a + of . + + + + + Ensures that the parent is not places on the + same cell as any other that has a + . + + + The using the + + + The location that the building is being placed at. + + + The rotation that the building is being placed at. + + + The that the building is being placed in. + + Unused. + Unused. + + false if any impassible building exists in any cell occupied + by the blueprint being placed. true if no impassible + building exists, meaning that placement is permitted. + + + + + Static helper class, contains helpful methods to apply to buildings. + + + + + The vanilla SoundDef played when a building is + minified/uninstalled. Stored here as a public member for + consistency. + + + + + Minifies a Thing on the spot if its ThingDef says + that it can be minified, and destroys it if not. + + The Thing to minify/destroy. + + The destroy mode to pass to thing.Destroy. It's not + recommended to set this unless you have a good reason to do so. + + + + + Checks whether the building is a wall, namely that it holds a roof, + blocks light, and covers the floor. + + The building to check. + + Whether the building is a wall by the above criteria. + + + + + Returns whether an identical Thing exists in the specified + cell, namely that its Def matches and it's facing in the + same direction. + + + The BuildableDef a PlaceWorker is trying to place. + + The cell it's trying to be placed in. + + The rotation of the current thing which is attempting to be placed. + + The map it's trying to be placed in. + + True, if the same building exists in the same spot with the + same rotation. + + + + + If the given defines an incomplete + building (a blueprint or building frame), then this method will + give the of the finished building. + + + The to be evaluated. + + + The construction stage that this + defines. + + + The of the building when it is fully + constructed. If the building is already fully constructed, then + the method will return the same reference as the building + parameter. + + + + + An enumerator that contains all of the stages of building + construction, including finished and unfinished stages. + + + + + The building has been planned out by the player, but + construction has not yet begun, and no resources have been + delivered. + + + + + Colonists have begun working on this building. This represents + any time between the first resource being delivered, and all of + the required work being completed. + + + + + The building is fully completed. It requires no additional + resources or work, and is behaving exactly as is defined in its + . + + + + + A static helper utility for handling the health of Pawns. + + + + + Represents a side-effect that can be applied upon regeneration, + including the Hediff to apply, the frequency at which it + occurs, how its severity should be calculated, and whether it + should be applied to the target part or whole body. + + + + + The Hediff that this side-effect will apply. + + + + + The chance as a decimal percent that this side-effect will be + applied upon successful regeneration. + + + + + Range for the Hediff's random starting severity. + + + + /// + If true, the Hediff's severity will be multiplied + by the cured Hediff's severity. If it is an injury, it + will be multiplied by the Hediff's severity as a percent + of the base health. + + + + + If true, the Hediff will be applied to the whole + body, instead of the cured part. + + + + + Tries to cure chronic Hediffs, and applies side-effects + randomly if defined. + + + The Pawn that will have hediffs added/removed + + + The Hediff that is causing regeneration, used to notify the + player, and to ensure that Hediffs cannot cure themselves. + + + List of chronic HediffDefs to ignore. Leave null to ignore + none. + + + List containing the only chronic HediffDefss that + will be healed. Leave null to accept all chronic HediffDefs. + + + A List of RegenSideEffects to randomly apply after + successful regeneration. + + + If false, injuries that are destroyed parts will be ignored. + + + Dictates whether Hediffs that use the Hediff_Injury + class should automatically be treated as whitelisted, blacklisted, + or neither. + + + + + Returns a list of all Hediffs applied to a Pawn that + meet a specified list of criteria. + + + The Pawn whose Hediffs are being checked + + + List of chronic HediffDefs to ignore. Leave null to ignore + none. + + List containing the only chronic HediffDefss that will be + healed. Leave null to accept all HediffDefs. + + + If false, injuries that are destroyed parts will be ignored. + + + Dictates whether Hediffs that use the Hediff_Injury + class should automatically be treated as whitelisted, blacklisted, + or neither. + + + An IEnumerable containing all of the Hediffs that + meet the specified criteria. + + + + + Returns a list of permanent Hediffs applied to a Pawn + that meet a specified list of criteria. + + + The Pawn whose Hediffs are being checked + + + List of chronic HediffDefs to ignore. Leave null to ignore + none. + + List containing the only chronic HediffDefss that will be + healed. Leave null to accept all HediffDefs. + + + If false, injuries that are destroyed parts will be ignored. + + + Dictates whether Hediffs that use the Hediff_Injury + class should automatically be treated as whitelisted, blacklisted, + or neither. + + + An IEnumerable containing all of the Permanent + Hediffs that meet the specified criteria. + + + + + Used to check if a Hediff is inherited from + Hediff_Injury or from Hediff_MissingPart. Useful for + treating injuries and missing parts equally. + + + The Hediff to check. + + If true, missing parts will not + be counted as an injury if any ancestor has any ancestor with + "added parts", i.e. bionics. + + true, if the specified Hediff is some form of injury + or missing part. + + + + + Recursively restores each part of a given limb. + + + The Pawn who owns the part. + + + The BodyPartRecord of the part to restore. + + + If true, the player will not be warned about possible errors + caused by unsafely restoring parts during HealthTick. + + + + + Recursively restores each part of a given limb. + + + The Pawn who owns the part. + + + The BodyPartRecord of the part to restore. + + + + + Used to initiate a recursive restoration of a specified part. When + done, it marks the Pawn's health records to be re-cached. + + + The Pawn who owns the part. + + + The BodyPartRecord of the part to restore. + + + + + Used to safely cure Hediffs during HealthTick using + HediffComp_ShouldRemove, so as not to cause index array + exceptions due to a shrinking Hediff list. If the + Hediff does not have HediffComps, it won't be + possible to cure it the safe way, so a warning will be provided to + the player. + + + The Hediff to be cured. + + + If true, the player will not be warned about possible errors + caused by unsafely restoring parts during HealthTick. + + + true if a warning was issued to the player, false + otherwise. + + + + + Used to safely cure Hediffs during HealthTick using + HediffComp_ShouldRemove, so as not to cause index array + exceptions due to a shrinking Hediff list. If the + Hediff does not have HediffComps, it won't be + possible to cure it the safe way, so a warning will be provided to + the player. + + + The Hediff to be cured. + + + + + Method for determining if a given Hediff matches a given + whitelist, blacklist, or both. + + + Bear in mind that, while it is + possible to use both types of lists, doing so will lead to + unexpected behavior. If an automatic injury list is used, however, + you can override it by adding specific injuries to the opposite + list. + + + The Hediff to check against the lists. + + + A List of Hediffs that will only be accepted. + + + A List of Hediffs that will never be accepted. + + + The automatic injury listing mode, if any. + + + true if the Hediff fits into the specified lists, + false otherwise. + + + + + Calculates the amount of pain that a given Pawn is + experiencing right now, with or without health-induced multipliers. + + + The Pawn whose pain is being checked + + + If true, the final value will account for Hediffs + that multiply the Pawn's total pain level. Set to + false for the "raw" value. + + + If this value is true, and the given Pawn is not made + of flesh (for example, if it is a mechanoid), then this method will + always return 0 because robots have no feelings. + + A float representing the current amount of pain that the + given Pawn should be in. Does not include a maximum value. + + + + + InjuryRegenListMode is used to dictate whether a + ThingComp or HediffComp that uses + CommunityHealthUtility should automatically treat + HediffDefs with the Hediff_Injury class as + whitelisted or blacklisted, or if they should be treated normally + (None). + + + + + Injuries should be treated as any other Hediff. + + + + + Injuries should never be accepted, unless explicitly + whitelisted. + + + + + Injuries should always be accepted, unless explicitly + blacklisted. + + + + + The base HediffProperties used to provide instructions for + HediffComp_HealPermanentWoundsConfigurable + + + + + A List of Hediffs that cannot be cured. Should be + left blank if a whitelist is in use. + + + + + A List of Hediffs. If this list is used, then only + the Hediffs it contains will be used. Should be left blank + if a whitelist is in use. It is generally recommended to blacklist + Hediffs that can be caused by side-effects so that they + aren't automatically cured. + + + + + A List of RegenSideEffects that will be applied to + the Pawn whenever a Hediff is removed. + + + + + If true, parts that are fully destroyed will still have + their Hediffs cured. + + + + + Determines whether all Hediffs of the Hediff_Injury + class should automatically be treated as whitelisted or + blacklisted, if at all. + + + + + Shortest and longest times between regeneration attempts. Values + are multiplied by RegenIntervalTicks. Default is based on + the values for Luciferium. + + + + + Number of ticks to multiply regenInterval by. Usually a distinct + period of time, represented in ticks. For reference, one day is + 60000 ticks long. + + + + + The number of times that the regeneration method will be invoked + while the parent Hediff is applied. If the value us -1, + regeneration will be repeated indefinately. + + + + + If true, the parent Hediff will be removed when + usesBeforeExhaustion reaches 0. + + + + + Boilerplate constructor, sets compClass to + HediffComp_HealPermanentWoundsConfigurable + + + + + The HediffComp responsible for managing regeneration, based on + the member values defined in + HediffCompProperties_HealPermanentWoundsConfigurable + + + + + Ticks before the next regeneration attempt is executed + + + + + The number of additional times that TryHealPermanentWound will be + invoked. -1 means infinite uses. + + + + + Getter used to directly access this comp's + HediffCompProperties_HealPermanentWoundsConfigurable so that + a cast isn't required every time it is referenced. + + + + + Internal helper method, resets the cooldown interval + + + + + Method run after the internal timer runs out, simply invokes + CommunityHealthUtility.TryHealRandomPermanentWoundFor + using values defined by + HediffCompProperties_HealPermanentWoundsConfigurable. + + + + + Run when this HediffComp (and by extention its parent + Hediff) is created. Sets up the internal timer for the first + time and sets the intended number of uses. + + + + + Runs every tick, decreases the internal timer by 1. If the timer + reaches 0, TryHealPermanentWound is invoked, the timer is + reset, and the remaining uses is decreased by 1 if necessary. If + the number of reamining uses is 0 and + removeParentOnExhaustion is true, then the parent + Hediff will be removed. + + + Parameter from the base method, currently unused. + + + + + override of the saving/loading method, used to store the + current number of ticks remaining in the timer, and the current + number of uses remaining. + + + + + override of the method used to display additional debug + information in the health pane. + + + A string containing the values of member variables for + debugging purposes. + + + + + override of method used to determine if a + HediffComp's parent should be removed when available. Parent + will be removed if remaining uses are exhausted and + removeParentOnExhaustion is true, or if the base + method returns true. + + + + + override of method called when an identical Hediff + is applied to the same part. Re-applying the regeneration + Hediff will add to the remaining number of uses, unless + the current number of uses in infinite. + + + + + + A HediffComp that allows Hediffs to be removed during the + HealthTick without causing errors. + + + Powered by . + + + + + Informs developers if a Hediff is supposed to be removed. If + this text is visible on an active Hediff, something is + wrong. + + + Updated debug string. + + + + + This method is used to determine if a HediffComp's parent + Hediff should be removed when it is safe to do so. It is run + by HediffWithComps.ShouldRemove. Some Hediffs, + like Hediff_MissingPart, override this method and must be + patched. + + + + + A DefModExtension that allows for a trait to randomly cause + diseases from a pre-defined list, regardless of the biome that the + pawn is currently situated in. + + + + + Internal helper class, represents the collection of + hediff-causing incidents that can be applied by each degree of the + affected trait. + + + + + The mean time, in days before a hediff-causing incident occurs. + + + + + A dictionary consisting of hediff-causing incidents as keys, + and their randomness weight as values. + + + + + The required trait degree for this incident pool to be used. + + + + + Method that is called when + Pawn_HealthTracker.HealthTick decides that it is time + for a disease-causing incident to occur, based on + mtbDiseaseDays. + + The pawn targeted by the incident. + + + + Contains all of the TraitMtbDiseasePools specified for each + trait degree. + + + + + Allows modder to add comps to any items created with a certain Stuff + using the CompsToAddWhenStuff ModExtension. + + + + + Patches to be inactive if the + parent Thing has a CompRefuelable which is unfueled, but + only if the parent building's ThingDef has + and facilityRequiresFuel + is true. + + + + + Loads included Harmony patches only if they're enabled in the mod settings. + + + + + Harmony patch applied to the Verse.Hediff_MissingPart class, + intended to provide functionality to HediffComp_ShouldRemove, + even though Hediff_MissingComp overrides the method normally + used to detect it. + + + + + By default, Hediff_MissingPart.ShouldRemove is + hard-coded to always return false. This patch causes it + to return true if its comps contains + HediffComp_ShouldRemove. A specific reference to + HediffComp_ShouldRemove is used so that we don't break + the behavior of other comps that are applied to missing parts. + + + Now, since we already know that the base method returns a + constant value, we don't *need* to incorporate its return + value. However, other modders may change this method, and we + need to account for that. + + + The original return value of + Hediff_MissingPart.ShouldRemove. + + + The Hediff_MissingPart instance. + + + + + Prevents missing parts from trying to generate a new label if + they're about to be removed anyways. This fixes a + NullReferenceException caused by setting the hediff's + part to null, but only if we've also added + to it. + + + The Hediff_MissingPart instance. + + + false if the hediff is supposed to be removed, + true otherwise + + + + + Allows modders to use the + DefModExtension to create plants which grow faster in poorer + soil. + + + Generally mod-compatible and performant because of how it caches + MaxNaturalFertility, but probably contributes to longer start-up + times. + + + + + Caches MaxNaturalFertility on startup by getting the most fertile natural terrain. + + + Where "natural" is defined as "generated by a BiomeDef". + + + + + Patches applied to Pawn_HealthTracker.HealthTick, allowing us to + read and write a pawn's health on a per-tick basis. + + + + + Postfix applied to Pawn_HealthTracker.HealthTick, + allowing additional code to be run after the base method. + + The specific instance of + Pawn_HealthTracker currently being ticked. + The pawn that this + Pawn_HealthTracker belongs to. + + + + This patches the method CostToMoveIntoCell from the Pawn_PathFollower class so when a hediff has the related comp, it can move unrestricted through any terrain. + + + + + This patches the method ShouldHaveNeed so it checks if a pawn has the IgnoreNeed DefModExtension. + If this DefModExtension contains the need in its list, ignore it. + + + + + DefModExtension for use with + . Needs listed here will be ignored + by pawns with this DefModExtension. + + + + + A list of s to be ignored by the pawn. + + + + + DefModExtension which flags the parent plant ThingDef as + using negative fertility. Specifies minimum and maximum fertility + values within which the final fertility is clamped. + + + See for implementation details. + + + + + The lowest possible perceived fertility value. This is how quickly + the plant will grow when planted on the most fertile natural soil + available. + + + + + The highest possible perceived fertility value. This is how quikcly + the plant will grow when planted on the least fertile natural soil + possible. + + + + + DefModExtension for use with + . Specifies the ThingComps, + by their CompProperties, which should be added to newly- + generated items made from the specified Stuff. + + + + + A list of s that will be attached to + anything that uses the comp's parent as stuff. + + + + + An extension meant for use alongside + , it is meant to be used on + buildings that link to other buildings. + + + + + If true, then the facility's link will not be active unless + its has fuel. + + + + + An extension used by . It contains a list + of s to run when the parent recipe is + complete. + + + + + A collection of output workers, whose mthods will be run to modify + the outputs of a crafting recipe. + + + + + A that allows modders to customize the + behaviors of any s attached to the + same . + + + + + If true, then whatever hatches out of the + hatcher will automatically be assigned to the player's faction. + + + + + A that contains methods which can be run whenever a + using the parent is initially created. This + applies to Things that have just been crafted/built, as well as things that have + been spawned in as loot or trade items. + + + + + A method that is run after a with the parent + has its method run. + + The that was just made. + + + + A method that is run after a with the parent + has its method run. + + The that was just made. + + + + A HediffComp used to create Hediffs that allow their + affected Pawn to pass over any terrain type while ignoring the + path cost. This HediffComp doesn't do much on its own, and only + exits to be detected by a Harmony patch. + + + Powered by . + + + + + Additional text displayed when the parent Hediff is + mouse-highlighted in-game. + + + + + This patche adds function to the CF_CaravanCapacity stat, allowing + equipment to modify the mass that a pawn ca carry in a caravan. + + + + + This patches the Hatch method so when no parent can be found (which is the case when a pawn is spawned from a crafted item), it is set so the player faction. + + + + + The properties class for . Used to + define which recipes are unlocked, and by what facilities. + + + + + Used to store a single facility that is able to unlock the listed + recipes, and the minimum quality of the facility required for the + recipe to be unlocked. + + + + + Thing of the facility that unlocks the + given list of recipes. + + + + + The minimum quality that must be + for it to be able to unlock the listed recipes. + + + + + The list of facilities that unlock the recipes defined in + , and the minimum + quality that the facility must be to do so. + + + + + The recipes that will become available when one of the facility + requirements defined by is met. + + + + + Constructor, automatically initializes compClass to + . + + + + + Patch of QualityUtility.QualityCreatedByPawn. Add to this patch + if you want to add conditions that affect the quality of crafted items. + + + + + Postfix to be run after the base method. + + + The orignal quality output by the base method. + + + The Pawn crafting the item in question. + + + + + Gizmo which displays the current energy state of the . Identical to the vanilla one, except references the aforementioned class since it's no longer a subclass. + + + + + ThingClass which acts like the vanilla ShieldBelt class but allows the user to fire ranged weapons while worn. + + + Used to be a pretty simple subclass of ShieldBelt, but that ran into compatibility problems: + + Some mods check whether ranged shots were allowed by seeing if the thingClass is a ShieldBelt, which returned true in this case, + causing errors including them being automatically, erroneously, unequipped on ranged pawns. + A growing number of patches were necessary to prevent the vanilla game treating ranged shield belts in the same way. + + + + + + The amount of energy that the shiled belt currently has. + + + + + If the shield has run out of energy, and needs time to recharge before blocking more shots. + + + + + The only meaningful change here, allowing ranged verb casts (or, more precisely, not disallowing them as the original ShieldBelt does). + + Disregarded. + True. + + + + Expose save/load data to the scribe. + + + + + Generates on-screen gizmos for when the pawn wearing the shield belt is selected. + + An enumerable containing the gizmos generated. + + + + The value offset provided by this specific shield belt, based on the maximum amount of energy it can store. + + + + + + Method run each game tick. Updates the shield belt's charge status. + + + + + Method run each time the pawn wearing the shield belt takes damage. Determines if the damage should be blocked, based on the current energy level of the shield belt, and the type of damage taken. + + Information about the damage taken by the pawn. + true if the shield belt has successfully blocked the damage taken by the pawn. false if the belt has insufficient energy to block the damage, or if the damage was an EMP attack. + + + + Notify the shield belt that it should start or continue displaying the shield overlay effect. + + + + + Draws the shield bubble over the pawn that is wearing the shield belt. + + + + + ModSettings class for Community Framework. Mainly handles which + Harmony patches should be applied and saves all specified settings. + + Static for convenience. + + + + This is manually prefixed onto every mod settings string key + that is defined in the framework's language XML, to avoid the + possibility of a translation key collision. + + + + + This is manually affixed onto every string key for a mod setting's + title, in the framework's language XML. + + + + + This is manually affixed onto every string key for a mod setting's + description, in the framework's language XML. + + + + + If true, then the framework is running in debug mode, and + debug logging and features are currently active. + + + + + If the framework should log which methods it has patched on + startup. + + + + + If the framework should log which methods it has patched on + startup. + + + + + A list of Harmony patches to apply on startup. + + + despite being public, please don't access these. Access patch + application settings with ShouldPatch. + They're only public so they can be used in the mod settings screen. + + + + + Represents a single one of the framework's Harmony patches, and + whether or not it should be applied. + + + + + If the patch should be applied. + + + + + Identifier used to associate this patch save with the specific + Harmony patch that it represents. + + + + + A no-arg constructor, required by the vanilla API. Does + nothing. + + + + + Constructor with parameters for initializing fields. + + + The save key, used to associate this patch save with the + specific Harmony patch that it represents. + + + If the patch should be applied. + + + + + Returns a string containing the saveKey of the patch, + and whether or not the patch should be applied. + + + + + + Saves and/or loads the fields of this PatchSave, so that + patch settings are persistent between game sessions. + + + + + Saves and/or loads the fields of each + stored, so that patch settings are persistent between game + sessions. + + + + + Determines whether or not the given patch should be run for this + session. + + + The identifier of the patch being checked. + + + true if the patch should be applied, false if the + player has chosen to disable it. + + + + + + + + + + + + + Mod class for Community Framework. Mainly handles the settings + screen. + + + + + Constructor for the Framework's mod data. Initializes the + framework's mod settings, and loads all of the patch data. + + Unused in this override. + + + + Draws the contents of the framework's mod settings window. + + + The to draw the settings window onto. + + + + + The name of the framework's listing in the game's list of available + mod settings menus. + + + + + + + + PlaceWorker requiring that the parent Thing be placed on + a cell adjacent to but facing away from a wall. + + + Originally by CuproPanda, for Additional Joy Objects. + + + + + + Ensures that the building is placed on a cell adjacent to but facing away from a wall. + + + The using the + + + The location that the building is being placed at. + + + The rotation that the building is being placed at. + + + The that the building is being placed in. + + Unused. + Unused. + + true if the cell behind the building being placed contains a wall, and is within + the map bounds. + + + + + PlaceWorker requiring that the parent Thing be placed on + a wall but not overlapping the same Thing in the same rotation. + + + + + + Ensure that the building being placed is placed on a wall but not overlapping the same + Thing in the same rotation. + + + The using the + + + The location that the building is being placed at. + + + The rotation that the building is being placed at. + + + The that the building is being placed in. + + Unused. + Unused. + + true if the cell at loc contains a wall, and does not contain an + identical building at the same rotation. + + + + + Always allows buildings using this to be placed over any + other building. + + The building being placed onto. + Always true + + + + PlaceWorker requiring that the parent Thing be placed + under a roof. + + + Originally by CuproPanda, for Additional Joy Objects. + + + + + Checks that the parent is placed under a roof. + + + + + + + + + + + + + + + + + + + + + false if the blueprint is being placed out in the open + without a roof over it. true if every cell of the blueprint + being placed is roofed, meaning that placement is permitted. + + + + + PlaceWorker requiring that the parent Thing be placed + under a roof and not over another Thing which is too tall. + + + + Originally by CuproPanda, for Additional Joy Objects. + + + + + Ensures that the parent is placed under a roof, + and not over any other that is too tall. + + + + + + + + + + + + + + + + + + + + + false if the blueprint's area is not fully roofed, or if + there are any other s occupying the same space + as the blueprint which are too tall. true if none of the + prior conditions are violated, meaning that placement is permitted. + + + + + This patches the method Notify_LinkRemoved so the CompUnlocksRecipe specific code is executed after the regular Notify_LinkRemoved code is run. + CompUnlocksRecipe in this case checks when link is removed, if the removed facility was the only one of that type, and if so, remove the recipes from the target workbench. + + + + + This patches the method Notify_NewLink so the CompUnlocksRecipe specific code is executed after the regular Notify_NewLink code is run. + CompUnlocksRecipe in this case checks when a new link is created. If this new link is one with a new unique facility, and the added recipes are also not yet added to the workbench, they will be added. + + + + + Recipe worker that can add and (optionally) remove Hediffs at + the same tame. Intended for recipes that install bionic implants. + + + + + This method is run when the recipe is performed on a pawn via + surgery. It functions almost identically to the base method, except + that it also removes the Hediff defined in + RecipeDef.removesHediff. + + The target of the surgery. + The body part that the operation is being + performed on. + The pawn performing the operation + The items (in this case, usually bionic + implants) that are being used to perform the surgery. + The def of the recipe for the operation + + + + + Utility Log. Convenient logging methods which automatically prefix + themselves for identifiability, plus debug-only messages. + + + + + The name of our mod, which will be prefixed to our log messages. + + + + + The prefix to start log messages with, so that end-users know which + messages are caused by us. + + + + + Calls Verse.Log.Message, but prefixes the name of the + framework for the benefit of the end-user. + + The message to write to the log. + + + + Calls Verse.Log.Warning, but prefixes the name of the + framework for the benefit of the end-user. + + The message to write to the log. + + + + Calls Verse.Log.Error, but prefixes the name of the + framework for the benefit of the end-user. + + The message to write to the log. + + + + Calls Verse.Log.Message, but only if the framework is set to + run in debug mode. Useful for displaying the current state of a + potentially-problematic system. Prefixes the name of the framework + for the benefit of the end-user, if addPrefix is + true. + + The message to write to the log. + + If true, the message displayed will be prefixed with the + name of the framework. + + + + + Used to make adding new Harmony patches internally easier. Not intended + for other mods' use. + + + + + Store the name translation key, Scribe save key, and description + translation key, respectively, of the annotated Harmony patch. + + + + + Store the name translation key, Scribe save key, and description + translation key, respectively, of the annotated Harmony patch. + + + + + Store the name translation key, Scribe save key, and description + translation key, respectively, of the annotated Harmony patch. + + + + + Constructor, takes a single string as an argument. Sets up + the values of NameKey, SaveKey, and DescKey. + + + The string used to refer to the annotated patch's respective mod + setting during Scribe reads and writes. Also used to generate the + translation keys for the mod setting. + + + + + Static utility that allows mod developers to change the quality of + Things with the CompQuality ThingComp in a + non-invasive way. + + + + + FieldInfo used to refer to the private qualityInt + field of the CompQuality class. + + + + + No-arg constructor, run when the game starts. Initializes the value + of QualityUtility.QualityInt. + + + + + Directly sets the QualityCategory of a CompQuality + without re-initializing any sibling CompArt that may exist. + + + The CompQuality to have its QualityCategory changed. + + + The target QualityCategory to set. + + + + + Static helper utility that contains methods pertaining to starting, + doing, and completing bills and recipes. + + + + + An empty delegate to define the method signature used by + Verse.GenRecipe.PostProcessProduct. + + + + + This delegate refers to the private method + Verse.GenRecipe.PostProcessProduct. + + + + + Sets up delegates refering to private methods. + + + + + Calls the vanilla private method used to finalize crafted items. + This method will set up CompQuality and CompArt, + apply any ideo styles, and will minify the product if possible. + + + This method doesn't do anything other than call a private method + from the vanilla API. Normally, we shouldn't be doing this. + However, this method has no reason to be private in the first + place; it is static and completely stateless. + + The crafting product to finalize + The recipe that created the product + The pawn doing the recipe + The pawn's ideo style precept + The style that will be applied to the product. + + Index override for the graphic. + + A reference to product. + + + + A class that, on startup, does any def modifications and caches any values neccessary. + + + + + A list of buildings that have , with + set to true. Cached here on + startup so that we don't have to go looking through the entire + database anytime a short circuit occurs. + + + + diff --git a/Common/Languages/English/Keyed/Settings.xml b/Common/Languages/English/Keyed/Settings.xml index 458ba2b..121d131 100644 --- a/Common/Languages/English/Keyed/Settings.xml +++ b/Common/Languages/English/Keyed/Settings.xml @@ -51,4 +51,16 @@ Recipe Output Patches allows modders to run additional scripts whenever certain recipes are complete. + + Blueprint Overlap Patches + allows modders to alter behaviors pertaining to placing blueprints onto existing buildings. + + Short circuit patches + allows modders to create buildings that react differently to short circuits. + + Thing post-make patches + runs additional behaviors whenever a thing is created. + + Battery charge patches + allows modders to further customize their modded batteries. \ No newline at end of file diff --git a/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffCompProperties_CraftedQualityOffset.cs b/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffCompProperties_CraftedQualityOffset.cs index eba8fbf..c838d25 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffCompProperties_CraftedQualityOffset.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffCompProperties_CraftedQualityOffset.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using Verse; -using RimWorld; namespace CF { diff --git a/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffComp_CraftedQualityOffset.cs b/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffComp_CraftedQualityOffset.cs index b9feeb8..f1fb561 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffComp_CraftedQualityOffset.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/CraftedQualityOffset/HediffComp_CraftedQualityOffset.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Verse; +using Verse; using RimWorld; namespace CF diff --git a/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_IgnorePathCost.cs b/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_IgnorePathCost.cs index 810d3cc..12c08b3 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_IgnorePathCost.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_IgnorePathCost.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using RimWorld; +using RimWorld; using Verse; namespace CF diff --git a/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_SeverityFromApparel.cs b/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_SeverityFromApparel.cs index 4052105..3525b99 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_SeverityFromApparel.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/HediffComp_SeverityFromApparel.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Comps/HediffComps/IHediffComp_OnHediffAdded.cs b/Source/communityframework/communityframework/Comps/HediffComps/IHediffComp_OnHediffAdded.cs index 9b71655..d41a7f0 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/IHediffComp_OnHediffAdded.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/IHediffComp_OnHediffAdded.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Verse; -using RimWorld; +using Verse; namespace CF { diff --git a/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffCompProperties_MultiplyOtherHediff.cs b/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffCompProperties_MultiplyOtherHediff.cs index 76d080d..4b89097 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffCompProperties_MultiplyOtherHediff.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffCompProperties_MultiplyOtherHediff.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using Verse; -using RimWorld; namespace CF { @@ -30,5 +25,17 @@ class HediffCompProperties_MultiplyOtherHediff : /// multiplied by. /// public float multiplier = 1.0f; + /// + /// If true, then the comp will affect newly-added + /// Hediffs. Does not affect conditions that are already + /// present. + /// + public bool affectsNewHediffs = true; + /// + /// If true, then the comp will affect Hediffs that were + /// already present when the parent condition was applied. Does not + /// affect other conditions that were added after the parent. + /// + public bool affectsExistingHediffs = false; } } diff --git a/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffDuration.cs b/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffDuration.cs index b1d686f..5be1a51 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffDuration.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffDuration.cs @@ -1,10 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Verse; -using RimWorld; namespace CF { @@ -28,23 +23,73 @@ class HediffComp_MultiplyOtherHediffDuration : /// Run when another Hediff is added to the parent's /// Pawn. Multiplies the other Hediff's duration by a set /// amount, if the other Hediff's Def is in - /// Props.affectedHediffs. + /// Props.affectedHediffs, and if Props.affectsNewHediffs + /// is true. /// /// The Hediff being added. public void OnHediffAdded(ref Hediff hediff) { - if (hediff == parent) + if (!Props.affectsNewHediffs) return; - if (Props.affectedHediffs.Contains(hediff.def)) - if (hediff is HediffWithComps withComps) + + TryAdjustOtherHediff(hediff); + } + + /// + /// Run when the parent is applied to a + /// . If Props.affectsExistingHediff is + /// true, then this override will go through each health + /// condition already present on the target Pawn, and, if the + /// condition's is in + /// Props.affectedHediffs, its duration will be multiplied by + /// Props.multiplier. + /// + /// + /// The that caused the parent condition to be + /// applied. Unused here. + /// + public override void CompPostPostAdd(DamageInfo? dinfo) + { + base.CompPostPostAdd(dinfo); + + if (!Props.affectsExistingHediffs) + return; + + foreach (Hediff otherHediff in Pawn.health.hediffSet.hediffs) + TryAdjustOtherHediff(otherHediff); + } + + /// + /// Internal helper method used to adjust the duration of other + /// s where applicable. This method ensures that + /// the targeted health condition is not the comp's parent condition, + /// and that the condition's is contained in + /// Props.affectedHediff before taking effect, as well as + /// ensring that it has the required + /// , so doing those comparisons + /// externally is unnecessary. + /// + /// + /// The to possibly adjust. + /// + private void TryAdjustOtherHediff(Hediff other) + { + if (other == parent) + return; + if (Props.affectedHediffs.Contains(other.def)) + { + if (other is HediffWithComps withComps) { HediffComp_Disappears comp = withComps.TryGetComp(); + if (comp != null) + { comp.ticksToDisappear = - (int)Math.Ceiling( - comp.ticksToDisappear * Props.multiplier); + (int)Math.Ceiling(comp.ticksToDisappear * Props.multiplier); + } } + } } } } diff --git a/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffSeverity.cs b/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffSeverity.cs index 007d876..2c8814b 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffSeverity.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/MultiplyOtherHediff/HediffComp_MultiplyOtherHediffSeverity.cs @@ -1,10 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Verse; -using RimWorld; namespace CF { @@ -28,16 +23,58 @@ class HediffComp_MultiplyOtherHediffSeverity : /// Run when another Hediff is added to the parent's /// Pawn. Multiplies the other Hediff's severity by a set /// amount, if the other Hediff's Def is in - /// Props.affectedHediffs. + /// Props.affectedHediffs, and if Props.affectsNewHediffs + /// is true. /// /// The Hediff being added. public void OnHediffAdded(ref Hediff hediff) { - if (hediff == parent) + if (Props.affectsNewHediffs) + TryAdjustOtherHediff(hediff); + } + + /// + /// Run when the parent is applied to a + /// . If Props.affectsExistingHediff is + /// true, then this override will go through each health + /// condition already present on the target Pawn, and, if the + /// condition's is in + /// Props.affectedHediffs, its severity will be multiplied by + /// Props.multiplier. + /// + /// + /// The that caused the parent condition to be + /// applied. Unused here. + /// + public override void CompPostPostAdd(DamageInfo? dinfo) + { + base.CompPostPostAdd(dinfo); + + if (!Props.affectsExistingHediffs) + return; + + foreach (Hediff otherHediff in Pawn.health.hediffSet.hediffs) + TryAdjustOtherHediff(otherHediff); + } + + /// + /// Internal helper method used to adjust the severity of other + /// s where applicable. This method ensures that + /// the targeted health condition is not the comp's parent condition, + /// and that the condition's is contained in + /// Props.affectedHediff before taking effect, so doing those + /// comparisons externally is unnecessary. + /// + /// + /// The to possibly adjust. + /// + private void TryAdjustOtherHediff(Hediff other) + { + if (other == parent) return; - if (Props.affectedHediffs.Contains(hediff.def)) - hediff.Severity = - (int)Math.Ceiling(hediff.Severity * Props.multiplier); + if (Props.affectedHediffs.Contains(other.def)) + other.Severity = + Math.Min(other.Severity * Props.multiplier, other.def.maxSeverity); } } } diff --git a/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromPain/HediffCompProperties_SeverityFromPain.cs b/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromPain/HediffCompProperties_SeverityFromPain.cs index e29c858..60420e5 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromPain/HediffCompProperties_SeverityFromPain.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromPain/HediffCompProperties_SeverityFromPain.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Verse; -using RimWorld; +using Verse; namespace CF { diff --git a/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffCompProperties_SeverityFromSkill.cs b/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffCompProperties_SeverityFromSkill.cs index 817097f..43ad3b8 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffCompProperties_SeverityFromSkill.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffCompProperties_SeverityFromSkill.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffComp_SeverityFromSkill.cs b/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffComp_SeverityFromSkill.cs index ac06a68..1140fd2 100644 --- a/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffComp_SeverityFromSkill.cs +++ b/Source/communityframework/communityframework/Comps/HediffComps/SeverityFromSkill/HediffComp_SeverityFromSkill.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Linq; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Comps/ThingComps/CompOnWearSound.cs b/Source/communityframework/communityframework/Comps/ThingComps/CompOnWearSound.cs index e186f32..26f9fa5 100644 --- a/Source/communityframework/communityframework/Comps/ThingComps/CompOnWearSound.cs +++ b/Source/communityframework/communityframework/Comps/ThingComps/CompOnWearSound.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Verse; using Verse.Sound; -using RimWorld; namespace CF { diff --git a/Source/communityframework/communityframework/Comps/ThingComps/CompRemoteTrigger.cs b/Source/communityframework/communityframework/Comps/ThingComps/CompRemoteTrigger.cs index baad61b..771747b 100644 --- a/Source/communityframework/communityframework/Comps/ThingComps/CompRemoteTrigger.cs +++ b/Source/communityframework/communityframework/Comps/ThingComps/CompRemoteTrigger.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using RimWorld; using Verse; using UnityEngine; diff --git a/Source/communityframework/communityframework/Comps/ThingComps/CompSelfRepair.cs b/Source/communityframework/communityframework/Comps/ThingComps/CompSelfRepair.cs index d500a2b..30bbede 100644 --- a/Source/communityframework/communityframework/Comps/ThingComps/CompSelfRepair.cs +++ b/Source/communityframework/communityframework/Comps/ThingComps/CompSelfRepair.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Comps/ThingComps/CompValidator.cs b/Source/communityframework/communityframework/Comps/ThingComps/CompValidator.cs index 659415c..b6b03ca 100644 --- a/Source/communityframework/communityframework/Comps/ThingComps/CompValidator.cs +++ b/Source/communityframework/communityframework/Comps/ThingComps/CompValidator.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Verse; -using RimWorld; namespace CF { /// @@ -82,6 +80,14 @@ public override string CompInspectStringExtra() /// public class CompProperties_Validator : CompProperties { + /// + /// The number of in-game ticks that pass before each time the + /// PlaceWorker validation check is run. A lower number will run + /// the check more frequently, but can cause slowdown if the parent + /// ThingWithComps has computationally-expensive + /// PlaceWorkers. For reference, at 1x speed, there are 60 ticks + /// in a single second. + /// public int tickInterval = 250; /// diff --git a/Source/communityframework/communityframework/Comps/ThingComps/CompWithCheapHashInterval.cs b/Source/communityframework/communityframework/Comps/ThingComps/CompWithCheapHashInterval.cs index 24983b2..c0959cf 100644 --- a/Source/communityframework/communityframework/Comps/ThingComps/CompWithCheapHashInterval.cs +++ b/Source/communityframework/communityframework/Comps/ThingComps/CompWithCheapHashInterval.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Verse; +using Verse; namespace CF { diff --git a/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompProperties_UnlocksRecipe.cs b/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompProperties_UnlocksRecipe.cs index fcd21e2..a77322d 100644 --- a/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompProperties_UnlocksRecipe.cs +++ b/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompProperties_UnlocksRecipe.cs @@ -1,22 +1,50 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using RimWorld; using Verse; namespace CF { + /// + /// The properties class for . Used to + /// define which recipes are unlocked, and by what facilities. + /// public class CompProperties_UnlocksRecipe : CompProperties { + /// + /// Used to store a single facility that is able to unlock the listed + /// recipes, and the minimum quality of the facility required for the + /// recipe to be unlocked. + /// public class LinkableFacilities { + /// + /// Thing of the facility that unlocks the + /// given list of recipes. + /// public ThingDef targetFacility; + /// + /// The minimum quality that must be + /// for it to be able to unlock the listed recipes. + /// public QualityCategory minQuality; } + /// + /// The list of facilities that unlock the recipes defined in + /// , and the minimum + /// quality that the facility must be to do so. + /// + public List linkableFacilities; + /// + /// The recipes that will become available when one of the facility + /// requirements defined by is met. + /// + public List recipes; + + /// + /// Constructor, automatically initializes compClass to + /// . + /// public CompProperties_UnlocksRecipe() => compClass = typeof(CompUnlocksRecipe); - public List linkableFacilities; // Which facilities should be targeted - public List recipes; // Which recipes should be added + } } diff --git a/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompUnlocksRecipe.cs b/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompUnlocksRecipe.cs index 39a2e16..b2c1e40 100644 --- a/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompUnlocksRecipe.cs +++ b/Source/communityframework/communityframework/Comps/ThingComps/UnlocksRecipe/CompUnlocksRecipe.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using RimWorld; using Verse; diff --git a/Source/communityframework/communityframework/DefModExtensions/BlocksPlacement.cs b/Source/communityframework/communityframework/DefModExtensions/BlocksPlacement.cs new file mode 100644 index 0000000..cfc4631 --- /dev/null +++ b/Source/communityframework/communityframework/DefModExtensions/BlocksPlacement.cs @@ -0,0 +1,63 @@ +using Verse; + +namespace CF +{ + /// + /// A that, when applied to a building's + /// , can allow that building to conditionally block + /// the placement of other buildings. + /// + public abstract class DefModExtension_CanBlockPlacement : DefModExtension + { + /// + /// Determines whether or not another building is blocked by the + /// presence of this building in the same tile. + /// + /// + /// This method does know which building stage the parent building is + /// in (blueprint, frame, or finished). For the other building, it can + /// be assumed that it always a blueprint. + /// + /// + /// The , most likely a + /// , of the building that the player is trying + /// to place over the parent building. + /// + /// + /// The building stage of the existing building, meaning the one that + /// has this extension attached to it. + /// It is not recommended to use this parameter without good reason, as + /// changing the acceptance of overlapping buildings based on building + /// phase can be very inconsistent. However, the ability exists, should + /// you need it. + /// + /// + /// true, if the placement is blocked, and the new building is + /// not allowed to be blaced over the existing one. false + /// if the building is not directly blocked, and is allowed to be + /// placed as long as all other external conditions for building + /// placement are met. + /// + public abstract bool BlocksPlacementOf( + BuildableDef otherThing, + CommunityBuildingUtility.EBuildableDefStage existingBuildingStage + ); + } + + /// + /// A that will prevent impassable structures + /// like walls, vents, and coolers from being manually placed on top of + /// whatever building has the extension, even if it would normally be + /// possible for such overlap to happen otherwise (i.e. with conduits and + /// floor coverings). + /// + public class BlocksImpassibleBuildings : DefModExtension_CanBlockPlacement + { + /// + public override bool BlocksPlacementOf( + BuildableDef otherThing, + CommunityBuildingUtility.EBuildableDefStage _ + ) => + otherThing.passability == Traversability.Impassable; + } +} diff --git a/Source/communityframework/communityframework/DefModExtensions/Misc.cs b/Source/communityframework/communityframework/DefModExtensions/Misc.cs index 9c7a21c..1f337f0 100644 --- a/Source/communityframework/communityframework/DefModExtensions/Misc.cs +++ b/Source/communityframework/communityframework/DefModExtensions/Misc.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using RimWorld; using Verse; @@ -19,6 +15,9 @@ namespace CF /// public class IgnoreNeed : DefModExtension { + /// + /// A list of s to be ignored by the pawn. + /// public List needs; } @@ -32,7 +31,18 @@ public class IgnoreNeed : DefModExtension /// public class UseNegativeFertility : DefModExtension { - public float minFertility = 0.05f, maxFertility = 1.4f; + /// + /// The lowest possible perceived fertility value. This is how quickly + /// the plant will grow when planted on the most fertile natural soil + /// available. + /// + public float minFertility = 0.05f; + /// + /// The highest possible perceived fertility value. This is how quikcly + /// the plant will grow when planted on the least fertile natural soil + /// possible. + /// + public float maxFertility = 1.4f; } /// @@ -43,6 +53,10 @@ public class UseNegativeFertility : DefModExtension /// public class CompsToAddWhenStuff : DefModExtension { + /// + /// A list of s that will be attached to + /// anything that uses the comp's parent as stuff. + /// public List comps; } @@ -54,6 +68,10 @@ public class CompsToAddWhenStuff : DefModExtension /// public class BuildingFacilityExtension : DefModExtension { + /// + /// If true, then the facility's link will not be active unless + /// its has fuel. + /// public bool facilityRequiresFuel = false; } @@ -65,45 +83,46 @@ public class BuildingFacilityExtension : DefModExtension class UseOutputWorkers : DefModExtension { /// - /// A collection of non-initiated s to run - /// when the parent recipe is completed. + /// A collection of output workers, whose mthods will be run to modify + /// the outputs of a crafting recipe. /// - public IEnumerable outputWorkers; - - /// - /// Instances of the s used by this - /// extension. Stored so that their methods can be easily called when - /// needed. - /// - [Unsaved(false)] - private IEnumerable activeWorkers = null; + public List outputWorkers; + } + /// + /// A that allows modders to customize the + /// behaviors of any s attached to the + /// same . + /// + public class HatcherExtension : DefModExtension + { /// - /// Returns a list of instances of used by - /// this extension. If the workers haven't been instanced yet, this - /// property will first create the necessary instances. + /// If true, then whatever hatches out of the + /// hatcher will automatically be assigned to the player's faction. /// - public IEnumerable ActiveWorkers - { - get - { - if (activeWorkers != null) - return activeWorkers; - - activeWorkers = new List(); - foreach (Type t in outputWorkers) - activeWorkers.Append( - (OutputWorker)Activator.CreateInstance(t) - ); - - return activeWorkers; - } - } + public bool hatcheeForcePlayerFaction = false; } - public class HatcherExtension : DefModExtension + /// + /// A that contains methods which can be run whenever a + /// using the parent is initially created. This + /// applies to Things that have just been crafted/built, as well as things that have + /// been spawned in as loot or trade items. + /// + public interface IExtensionPostMake { - public bool hatcheeForcePlayerFaction = false; + /// + /// A method that is run after a with the parent + /// has its method run. + /// + /// The that was just made. + void PostMake(Thing thing); + /// + /// A method that is run after a with the parent + /// has its method run. + /// + /// The that was just made. + void PostPostMake(Thing thing); } #pragma warning restore CS0649 } diff --git a/Source/communityframework/communityframework/DefModExtensions/PowerExtensions.cs b/Source/communityframework/communityframework/DefModExtensions/PowerExtensions.cs new file mode 100644 index 0000000..37f746d --- /dev/null +++ b/Source/communityframework/communityframework/DefModExtensions/PowerExtensions.cs @@ -0,0 +1,95 @@ +using Verse; +using RimWorld; + +namespace CF +{ + /// + /// A base class for s, used to define custom behaviors that + /// affect the maximum amount of energy that a sibling can + /// store. + /// + public abstract class DefModExtension_BatteryAmountCanAccept : DefModExtension + { + /// + /// Augments the amount of energy that can be stored by a + /// attached to any with the parent . + /// + /// + /// The whose that + /// is being adjusted for. + /// + /// + /// The vanilla value of from comp. + /// + /// The new amount of additional energy that the battery can accept. + public abstract float AmountCanAccept(CompPowerBattery comp, float original); + } + + /// + /// Any will never be able to recharge if its parent has this + /// extension in its . + /// + public class NeverRecharge : DefModExtension_BatteryAmountCanAccept + { + /// + public override float AmountCanAccept(CompPowerBattery comp, float original) => 0f; + } + + /// + /// A that provides more customization options for any + /// attached to s that use the extension's + /// parent . + /// + public class BatteryExtension : DefModExtension, IExtensionPostMake + { + /// + /// If true, batteries with this extension will not lose 5W of energy per day, as is + /// hardcoded in vanilla. + /// + public bool neverDischarge = false; + /// + /// If true, then the battery will start with a full charge when it is crafted, + /// built, or otherwise initially created. + /// + public bool startCharged = false; + /// + /// If true, batteries with this extension will not lose power during the short + /// circuit event, and will not contribute to the size of the short circuit explosion. + /// + public bool neverShortCircuit = false; + + /// + public void PostMake(Thing thing) { } + + /// + /// After a with the parent is initially + /// created, this method will fully charge it if is a battery and if + /// is true + /// + /// + public void PostPostMake(Thing thing) + { + if (!startCharged) + return; + + CompPowerBattery battery = thing.TryGetComp(); + if (battery == null) + return; + + battery.SetStoredEnergyPct(1f); + } + } + + /// + /// A that provides more customization options for + /// s that define electrical objects. + /// + public class PowerExtension : DefModExtension + { + /// + /// If true, this can be a culprit of short circuits, like + /// vanilla power conduits. + /// + public bool shortCircuitSource = false; + } +} diff --git a/Source/communityframework/communityframework/DefModExtensions/TraitRandomDiseasePool.cs b/Source/communityframework/communityframework/DefModExtensions/TraitRandomDiseasePool.cs index 18b6f85..2549dbc 100644 --- a/Source/communityframework/communityframework/DefModExtensions/TraitRandomDiseasePool.cs +++ b/Source/communityframework/communityframework/DefModExtensions/TraitRandomDiseasePool.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/DefOf/CF_StatDefOf.cs b/Source/communityframework/communityframework/DefOf/CF_StatDefOf.cs index 9fb35bb..0a361c8 100644 --- a/Source/communityframework/communityframework/DefOf/CF_StatDefOf.cs +++ b/Source/communityframework/communityframework/DefOf/CF_StatDefOf.cs @@ -1,17 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Verse; -using RimWorld; +using RimWorld; namespace CF { + /// + /// cache containing the framework's XML + /// s for easy reference in C# assemblies. + /// [DefOf] public static class CF_StatDefOf { +#pragma warning disable CS0649 + /// + /// The additional mass that this creature can carry when part of a + /// caravan. + /// public static StatDef CF_CaravanCapacity; +#pragma warning restore CS0649 static CF_StatDefOf() => DefOfHelper.EnsureInitializedInCtor(typeof(CF_StatDefOf)); diff --git a/Source/communityframework/communityframework/Harmony patches/AddHediff.cs b/Source/communityframework/communityframework/Harmony patches/AddHediff.cs index 1ea0a8a..e569f35 100644 --- a/Source/communityframework/communityframework/Harmony patches/AddHediff.cs +++ b/Source/communityframework/communityframework/Harmony patches/AddHediff.cs @@ -1,10 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Verse; -using RimWorld; using HarmonyLib; namespace CF diff --git a/Source/communityframework/communityframework/Harmony patches/BatteryChargePatches.cs b/Source/communityframework/communityframework/Harmony patches/BatteryChargePatches.cs new file mode 100644 index 0000000..44a9197 --- /dev/null +++ b/Source/communityframework/communityframework/Harmony patches/BatteryChargePatches.cs @@ -0,0 +1,191 @@ +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using RimWorld; +using HarmonyLib; + +namespace CF +{ + /// + /// A collection of patches that alter the behaviors of batteries, allowing for more control + /// over custom batteries. + /// + [ClassWithPatches("ApplyBatteryPatches")] + public static class BatteryChargePatches + { + private static readonly MethodInfo M_CanDischarge = + typeof(BatteryChargePatches).GetMethod(nameof(BatteryChargePatches.CanDischarge), + BindingFlags.Public | BindingFlags.Static); + + /// + /// Checks if the battery is allowed to discharge by . + /// + /// + /// The of the battery being checked. + /// + /// + /// true if the battery's does not have a + /// , or if its + /// is false. true otherwise. + /// + public static bool CanDischarge(CompPowerBattery battery) + { + BatteryExtension extension = battery.parent.def.GetModExtension(); + return extension == null || !extension.neverDischarge; + } + + /// + /// This patch modifies the amount of additional energy that a battery can accept. + /// + [HarmonyPatch(typeof(CompPowerBattery))] + [HarmonyPatch(nameof(CompPowerBattery.AmountCanAccept))] + [HarmonyPatch(MethodType.Getter)] + public static class AmountCanAccept + { + /// + /// Checks the battery's for any extension that derives + /// , then adjusts the return value of the method + /// accordingly. + /// + /// + /// The being checked. + /// + /// + /// The amount of additional energy that the battery will accept. + /// + [HarmonyPostfix] + public static void CheckForBatteryExtension(ref CompPowerBattery __instance, ref float __result) + { + DefModExtension_BatteryAmountCanAccept extenstion = __instance.parent.def.GetModExtension(); + if (extenstion == null) + return; + __result = extenstion.AmountCanAccept(__instance, __result); + } + } + + /// + /// This patch alters whether or not a battery self-discharges the hardcoded amount of 5W + /// per day. + /// + [HarmonyPatch(typeof(CompPowerBattery))] + [HarmonyPatch(nameof(CompPowerBattery.CompTick))] + public static class BatteryDischargeCheckExtension + { + /// + /// Injects a condition into that checks if the + /// parent's contains a , + /// then checks if is true. If the + /// battery has been configured never to discharge, then it will skip over the + /// instructions for self-discharge. + /// + /// The instructions given to the transpiler. + /// used for creating labels + /// A patched list of instructions + [HarmonyTranspiler] + public static IEnumerable DoNotDischargeIfExtension( + IEnumerable instructions, + ILGenerator generator + ) + { + // Flag: + // 0 - Looking for base.CompTick to inject patch + // 1 - Injected patch, waiting one instruction to inject label + // 2 = Patch done + int flag = 0; + Label label = generator.DefineLabel(); + + foreach (CodeInstruction instruction in instructions) + { + yield return instruction; + + if (flag == 2) + continue; + + if (flag == 1) + { + instruction.labels.Add(label); + flag = 2; + continue; + } + + if (flag != 0 || !(instruction.opcode == OpCodes.Call && instruction.operand as MethodInfo == HarmonyUtils.M_ThingComp_CompTick)) + continue; + + flag = 1; + // push this + yield return new CodeInstruction(OpCodes.Ldarg_0); + // pop this, push CanDischarge(this) + yield return new CodeInstruction(OpCodes.Call, M_CanDischarge); + // if true, jump over return + yield return new CodeInstruction(OpCodes.Brtrue_S, label); + // if false, return + yield return new CodeInstruction(OpCodes.Ret); + } + + if (flag < 2) + ULog.Error("Patch " + nameof(DoNotDischargeIfExtension) + " failed."); + } + } + + /// + /// This patch prevents batteries from showing the "self-discharging" line on the + /// inspection pane if the battery has been configured not to self-discharge. + /// + [HarmonyPatch(typeof(CompPowerBattery))] + [HarmonyPatch(nameof(CompPowerBattery.CompInspectStringExtra))] + public static class BatteryInspectStringCheckExtension + { + private static readonly FieldInfo F_StoredEnergy = // Private field named by string + AccessTools.Field(typeof(CompPowerBattery), "storedEnergy"); + + /// + /// Injects a condition into that + /// checks if the parent's contains a + /// , then checks if + /// is true. If the battery has + /// been configured never to discharge, then it will skip over the instructions to + /// include the string "Self-discharging: 5W". + /// + /// The instructions given to the transpiler. + [HarmonyTranspiler] + public static IEnumerable SkipDischargeLineIfExtension( + IEnumerable instructions + ) + { + // Flag: + // 0 - Waiting for CompPowerBattery.storedEnergy to make sure we're looking at the + // correct evaluation + // 1 - Looking for ble.un.s to inject our extra condition + // 2 - Patch done + int flag = 0; + + foreach (CodeInstruction instruction in instructions) + { + yield return instruction; + + switch (flag) { + case 0: + if (instruction.operand as FieldInfo == F_StoredEnergy) + flag = 1; + break; + case 1: + if (instruction.opcode == OpCodes.Ble_Un_S) + { + flag = 2; + // push this + yield return new CodeInstruction(OpCodes.Ldarg_0); + // pop this, push CanDischarge(this) + yield return new CodeInstruction(OpCodes.Call, M_CanDischarge); + // if false, use jump to the same label as the vanilla conditional + yield return new CodeInstruction(OpCodes.Brfalse_S, instruction.operand); + } + break; + } + } + + if (flag < 2) + ULog.Error("Patch " + nameof(SkipDischargeLineIfExtension) + " failed."); + } + } + } +} diff --git a/Source/communityframework/communityframework/Harmony patches/Capacity.cs b/Source/communityframework/communityframework/Harmony patches/Capacity.cs index d4ffa64..650a770 100644 --- a/Source/communityframework/communityframework/Harmony patches/Capacity.cs +++ b/Source/communityframework/communityframework/Harmony patches/Capacity.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Text; using RimWorld; using Verse; using HarmonyLib; diff --git a/Source/communityframework/communityframework/Harmony patches/CompAffectedByFacilities.cs b/Source/communityframework/communityframework/Harmony patches/CompAffectedByFacilities.cs index 485ca2f..d464571 100644 --- a/Source/communityframework/communityframework/Harmony patches/CompAffectedByFacilities.cs +++ b/Source/communityframework/communityframework/Harmony patches/CompAffectedByFacilities.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using RimWorld; +using RimWorld; using Verse; using HarmonyLib; diff --git a/Source/communityframework/communityframework/Harmony patches/CompFromStuffPatch.cs b/Source/communityframework/communityframework/Harmony patches/CompFromStuffPatch.cs index 286e823..f4406ca 100644 --- a/Source/communityframework/communityframework/Harmony patches/CompFromStuffPatch.cs +++ b/Source/communityframework/communityframework/Harmony patches/CompFromStuffPatch.cs @@ -1,12 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Verse; -using RimWorld; using HarmonyLib; -using System.Reflection; -using UnityEngine; namespace CF { diff --git a/Source/communityframework/communityframework/Harmony patches/CostToMoveIntoCell.cs b/Source/communityframework/communityframework/Harmony patches/CostToMoveIntoCell.cs index 4e9eb1a..199a7bd 100644 --- a/Source/communityframework/communityframework/Harmony patches/CostToMoveIntoCell.cs +++ b/Source/communityframework/communityframework/Harmony patches/CostToMoveIntoCell.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using RimWorld; using Verse; using Verse.AI; using HarmonyLib; diff --git a/Source/communityframework/communityframework/Harmony patches/FacilityRequireFuelPatch.cs b/Source/communityframework/communityframework/Harmony patches/FacilityRequireFuelPatch.cs index f67a32b..a050b71 100644 --- a/Source/communityframework/communityframework/Harmony patches/FacilityRequireFuelPatch.cs +++ b/Source/communityframework/communityframework/Harmony patches/FacilityRequireFuelPatch.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using HarmonyLib; +using HarmonyLib; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Harmony patches/GenerateQualityCreatedByPawn.cs b/Source/communityframework/communityframework/Harmony patches/GenerateQualityCreatedByPawn.cs index f465d2d..bc9c8e4 100644 --- a/Source/communityframework/communityframework/Harmony patches/GenerateQualityCreatedByPawn.cs +++ b/Source/communityframework/communityframework/Harmony patches/GenerateQualityCreatedByPawn.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Verse; using RimWorld; using HarmonyLib; diff --git a/Source/communityframework/communityframework/Harmony patches/HarmonyUtils.cs b/Source/communityframework/communityframework/Harmony patches/HarmonyUtils.cs new file mode 100644 index 0000000..9f153f3 --- /dev/null +++ b/Source/communityframework/communityframework/Harmony patches/HarmonyUtils.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using Verse; + +namespace CF +{ + class HarmonyUtils + { + public static readonly MethodInfo M_ThingComp_CompTick = + typeof(ThingComp).GetMethod(nameof(ThingComp.CompTick), + BindingFlags.Public | BindingFlags.Instance); + } +} diff --git a/Source/communityframework/communityframework/Harmony patches/Hatch.cs b/Source/communityframework/communityframework/Harmony patches/Hatch.cs index 4c32919..a9a484d 100644 --- a/Source/communityframework/communityframework/Harmony patches/Hatch.cs +++ b/Source/communityframework/communityframework/Harmony patches/Hatch.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using RimWorld; -using Verse; +using RimWorld; using HarmonyLib; namespace CF diff --git a/Source/communityframework/communityframework/Harmony patches/HealthTick.cs b/Source/communityframework/communityframework/Harmony patches/HealthTick.cs index b2302bb..7690ee0 100644 --- a/Source/communityframework/communityframework/Harmony patches/HealthTick.cs +++ b/Source/communityframework/communityframework/Harmony patches/HealthTick.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Verse; +using Verse; using RimWorld; using HarmonyLib; diff --git a/Source/communityframework/communityframework/Harmony patches/NegativeFertilityPatch.cs b/Source/communityframework/communityframework/Harmony patches/NegativeFertilityPatch.cs index 4dd993d..6ba83f0 100644 --- a/Source/communityframework/communityframework/Harmony patches/NegativeFertilityPatch.cs +++ b/Source/communityframework/communityframework/Harmony patches/NegativeFertilityPatch.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; using HarmonyLib; using Verse; diff --git a/Source/communityframework/communityframework/Harmony patches/OutputWorkerPatch.cs b/Source/communityframework/communityframework/Harmony patches/OutputWorkerPatch.cs index 7a29588..d3b6001 100644 --- a/Source/communityframework/communityframework/Harmony patches/OutputWorkerPatch.cs +++ b/Source/communityframework/communityframework/Harmony patches/OutputWorkerPatch.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Verse; using RimWorld; using HarmonyLib; @@ -27,26 +24,27 @@ public static void Prefix( Pawn worker, List ingredients, IBillGiver billGiver, - Precept_ThingStyle precept, - ThingStyleDef style, - int? overrideGraphicIndex + ref Precept_ThingStyle precept, + ref ThingStyleDef style, + ref int? overrideGraphicIndex ) { // Get the extension, quit if none found UseOutputWorkers ext = recipeDef.GetModExtension(); - if (ext == null) return; + if (ext == null || ext.outputWorkers.EnumerableNullOrEmpty()) + return; // Run every pre-craft method - foreach (OutputWorker o in ext.ActiveWorkers) + foreach (OutputWorker o in ext.outputWorkers) o.PreCraft( recipeDef, worker, ingredients, billGiver, - precept, - style, - overrideGraphicIndex + ref precept, + ref style, + ref overrideGraphicIndex ); } @@ -68,14 +66,42 @@ public static void Postfix( // Get the extension, quit if none found UseOutputWorkers ext = recipeDef.GetModExtension(); - if (ext == null) return; + if (ext == null || ext.outputWorkers.EnumerableNullOrEmpty()) + return; + + // Okay, so, LINQ is really weird. The contents of __result are things that were + // made with the method ThingMaker.MakeThing. MakeThing is called inside of the + // method we're patching - that's how all the Things got into __result to begin + // with. But MakeThing technically hasn't been *run* yet. It gets run when the + // contents of the list are first accessed, not when they are first appended. + // + // Because of some weird voodoo that I can't quite discern, that means we can't + // actually directly modify the Things inside of __result here. All of the MakeThings + // inside of __result get evaluated when we enumerate over it here, but then they + // get evaluated again after the patch when the crafter pawn gets the job to haul + // the crafted Things to storage. + // + // I have no idea what's going on, but I think that if we don't assign a value to + // __result, then any changes we make to its contents won't stick. So we copy the + // contents of __result to a new IEnumerable, specifically using ToList to force + // MakeThing to run. Then, at the end of the patch, we assign our copy of the + // original IEnumerable, to the original IEnumerable. This ensures that *our* + // MakeThing evaluations are the final ones. + // + // We're also doing this after checking that the RecipeDef is actually using + // OutputWorkers. Because even though I don't know if this behavior counts as + // invasive, I still feel safer this way. + // + // I don't know, and I give up on trying to understand or to care. just read this: + // https://stackoverflow.com/questions/1168944/how-to-tell-if-an-ienumerablet-is-subject-to-deferred-execution + IEnumerable products = __result.ToList(); // Run each post-craft method, then finalize any Things that // they produce before adding them to the list of products. - foreach (OutputWorker o in ext.ActiveWorkers) + foreach (OutputWorker o in ext.outputWorkers) { newProducts = o.PostCraft( - __result, + products, recipeDef, worker, ingredients, @@ -85,6 +111,10 @@ public static void Postfix( overrideGraphicIndex ); + // If no new products added, move on to the next worker. + if (newProducts.EnumerableNullOrEmpty()) + continue; + foreach (Thing t in newProducts) { CommunityRecipeUtility.PostProcessProduct( @@ -95,9 +125,11 @@ public static void Postfix( style, overrideGraphicIndex ); - __result.AddItem(t); + products.AddItem(t); } } + + __result = products; } } } diff --git a/Source/communityframework/communityframework/Harmony patches/ShortCircuitUtility/ShortCircuitPatches.cs b/Source/communityframework/communityframework/Harmony patches/ShortCircuitUtility/ShortCircuitPatches.cs new file mode 100644 index 0000000..c84f68a --- /dev/null +++ b/Source/communityframework/communityframework/Harmony patches/ShortCircuitUtility/ShortCircuitPatches.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using Verse; +using RimWorld; +using HarmonyLib; + +namespace CF +{ + /// + /// A collection of patches that affect the short circuit incident. + /// + [ClassWithPatches("ShortCircuitPatches")] + public static class ShortCircuitPatches + { + /// + /// This patch modifies the behaviors of batteries with + /// during a short circuit. + /// + [HarmonyPatch(typeof(ShortCircuitUtility))] + [HarmonyPatch("DrainBatteriesAndCauseExplosion")] // Private method named by string + public static class ShortCircuitPatches_Batteries + { + private static readonly MethodInfo M_CanShortCircuit = + typeof(ShortCircuitPatches_Batteries).GetMethod(nameof(ShortCircuitPatches_Batteries.CanShortCircuit), + BindingFlags.Public | BindingFlags.Static); + + [HarmonyTranspiler] + static IEnumerable CheckBatteryExtension( + IEnumerable instructions, + ILGenerator generator + ) + { + // Flag: + // 0 - Waiting for stloc.1, to make sure the local var batteryComp is initialized. + // Inject evaluation method. + // 1 - Looking for the next ldloc.0 (index) to inject label. + // 2 - patch done. + int flag = 0; + Label label = generator.DefineLabel(); + + foreach (CodeInstruction instruction in instructions) + { + yield return instruction; + if (flag == 2) + continue; + + if (flag == 0 && instruction.opcode == OpCodes.Stloc_1) + { + // Grab the local variable that stores the battery comp + yield return new CodeInstruction(OpCodes.Ldloc_1); + // Do the comparison, push result to buffer + yield return new CodeInstruction(OpCodes.Call, M_CanShortCircuit); + // If false, advance the foreach loop + yield return new CodeInstruction(OpCodes.Brfalse_S, label); + + flag = 1; + } + + if (flag == 1 && instruction.opcode == OpCodes.Ldloc_0) + { + instruction.labels.Add(label); + flag = 2; + } + } + + if (flag != 2) + ULog.Error("Patch " + nameof(CheckBatteryExtension) + " failed. Flag: " + flag.ToString()); + } + + /// + /// + /// + /// + /// + public static bool CanShortCircuit(CompPowerBattery comp) + { + BatteryExtension extension = comp?.parent.def.GetModExtension(); + return !extension?.neverShortCircuit ?? true; + } + } + + /// + /// This patch allows custom buildings to act as short circuit sources, like vanilla + /// conduits. + /// + [HarmonyPatch] + public static class ShortCircuitPatches_ConduitPatch + { + private static readonly MethodInfo M_AddExtraBuildings = + typeof(ShortCircuitPatches_ConduitPatch).GetMethod( + nameof(ShortCircuitPatches_ConduitPatch.AddExtraBuildings), BindingFlags.Static | BindingFlags.Public); + private static readonly MethodInfo M_ListerThings_ThingsOfDef = + typeof(ListerThings).GetMethod( + nameof(ListerThings.ThingsOfDef), BindingFlags.Public | BindingFlags.Instance); + + private static Type TargetInnerClass => AccessTools.FirstInner( + typeof(ShortCircuitUtility), + inner => inner.Name.Contains("")); + + static MethodBase TargetMethod() + { + return AccessTools.FirstMethod(TargetInnerClass, method => method.Name.Contains("MoveNext")); + } + + [HarmonyTranspiler] + static IEnumerable IncludeOtherShortSources( + IEnumerable instructions + ) + { + FieldInfo mapField = AccessTools.Field(TargetInnerClass, "map"); + + bool patched = false; + + foreach (CodeInstruction instruction in instructions) + { + yield return instruction; + + if (patched || instruction.operand as MethodInfo != M_ListerThings_ThingsOfDef) + continue; + + patched = true; + + // Currently on stack: a list of conduits on the map + + // Grab the map + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, mapField); + // Call the method. Pops the list of things and the map, then pushes the list + // back in. + yield return new CodeInstruction(OpCodes.Call, M_AddExtraBuildings); + } + + if (!patched) + ULog.Error("Patch " + nameof(ShortCircuitPatches_ConduitPatch.IncludeOtherShortSources) + " failed."); + } + + /// + /// Helper method for adding custom short circuit sources to the list of conduits found + /// inside of the incident worker for the short circuit incident. + /// + /// The original list of conduits. + /// The map that the short circuit is occuring on. + /// + /// A copy of list with additional short-circuitable buildings in map. + /// + public static List AddExtraBuildings(List list, Map map) + { + List resultList = new List(list); + + if (!StartupUtil.ExtraShortCircuitSources.Any()) + return resultList; + + foreach (ThingDef def in StartupUtil.ExtraShortCircuitSources) + { + List extraThings = map.listerThings.ThingsOfDef(def); + if (!extraThings.NullOrEmpty()) + resultList.AddRange(extraThings); + } + + return resultList; + } + } + } +} diff --git a/Source/communityframework/communityframework/Harmony patches/ShouldHaveNeed.cs b/Source/communityframework/communityframework/Harmony patches/ShouldHaveNeed.cs index 3f265a9..6945ada 100644 --- a/Source/communityframework/communityframework/Harmony patches/ShouldHaveNeed.cs +++ b/Source/communityframework/communityframework/Harmony patches/ShouldHaveNeed.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using RimWorld; +using RimWorld; using Verse; using HarmonyLib; diff --git a/Source/communityframework/communityframework/Harmony patches/Thing/Thing_PostMakePatches.cs b/Source/communityframework/communityframework/Harmony patches/Thing/Thing_PostMakePatches.cs new file mode 100644 index 0000000..eb38859 --- /dev/null +++ b/Source/communityframework/communityframework/Harmony patches/Thing/Thing_PostMakePatches.cs @@ -0,0 +1,46 @@ +using Verse; +using HarmonyLib; + +namespace CF +{ + /// + /// A collection of patches that run additional methods after a thing is made. + /// + [ClassWithPatches("PostMakePatch")] + public static class Thing_PostMakePatches + { + [HarmonyPatch(typeof(Thing))] + static class PostMakePatch + { + [HarmonyPatch(nameof(Thing.PostMake))] + [HarmonyPostfix] + public static void PostMakeThingPatch( + ref Thing __instance + ) + { + if (__instance.def.modExtensions.NullOrEmpty()) + return; + + foreach (DefModExtension extension in __instance.def.modExtensions) + if (extension is IExtensionPostMake postMake) + postMake.PostMake(__instance); + } + + [HarmonyPatch(nameof(Thing.PostPostMake))] + [HarmonyPostfix] + public static void PostPostMakeThingPatch( + ref Thing __instance + ) + { + if (__instance.def.modExtensions.NullOrEmpty()) + return; + + foreach (DefModExtension extension in __instance.def.modExtensions) + if (extension is IExtensionPostMake postMake) + postMake.PostPostMake(__instance); + } + } + + + } +} diff --git a/Source/communityframework/communityframework/Harmony patches/VerifyCanPlaceBlueprintOverPatch.cs b/Source/communityframework/communityframework/Harmony patches/VerifyCanPlaceBlueprintOverPatch.cs new file mode 100644 index 0000000..0250497 --- /dev/null +++ b/Source/communityframework/communityframework/Harmony patches/VerifyCanPlaceBlueprintOverPatch.cs @@ -0,0 +1,86 @@ +using Verse; +using RimWorld; +using HarmonyLib; + +namespace CF +{ + /// + /// This patch modifies the player's ability to place blueprints over other + /// s that occupy any of the same cells as the + /// blueprint. + /// + [ClassWithPatches("ApplyCanPlaceBlueprintOverPatch")] + static class VerifyCanPlaceBlueprintOverPatch + { + /// + /// This patch modifies the player's ability to place blueprints over + /// other s that occupy any of the same cells as the + /// blueprint. + /// + [HarmonyPatch(typeof(GenConstruct))] + [HarmonyPatch(nameof(GenConstruct.CanPlaceBlueprintOver))] + class CanPlaceBlueprintOver + { + /// + /// After all of the vanilla checks have passed successfully, this + /// postfix checks that any additional conditions added by the + /// framework have also been met. + /// + /// + /// Initially stores the result of the original method. If this + /// value is true, but the new conditions defined by the + /// framework are not met, then it will be changed to false. + /// + /// + /// The of the building that the player is + /// attempting to place. + /// + /// + /// The that the game is checking if + /// newDef can be placed on top of. + /// + [HarmonyPostfix] + public static void ApplyAdditionalConditions( + ref bool __result, + BuildableDef newDef, + ThingDef oldDef + ) + { + // If any value is null, stop + if (newDef == null || oldDef == null || newDef == oldDef) + return; + + // If the vanilla overlap checks failed, stop + if (__result == false) + return; + + + BuildableDef toBuild = + CommunityBuildingUtility.GetFullyConstructedDefOf( + newDef, + out CommunityBuildingUtility.EBuildableDefStage _); + + BuildableDef builtOn = + CommunityBuildingUtility.GetFullyConstructedDefOf( + oldDef, + out CommunityBuildingUtility + .EBuildableDefStage buildStage); + + if (builtOn.modExtensions.NullOrEmpty()) + return; + + foreach (DefModExtension ext in builtOn.modExtensions) + { + if ( + ext is DefModExtension_CanBlockPlacement blocker && + blocker.BlocksPlacementOf(toBuild, buildStage) + ) + { + __result = false; + break; + } + } + } + } + } +} diff --git a/Source/communityframework/communityframework/HarmonyLoader.cs b/Source/communityframework/communityframework/HarmonyLoader.cs index 9007674..5fb6557 100644 --- a/Source/communityframework/communityframework/HarmonyLoader.cs +++ b/Source/communityframework/communityframework/HarmonyLoader.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Reflection; using Verse; using HarmonyLib; diff --git a/Source/communityframework/communityframework/Misc/IngredientValueGetter_Mass.cs b/Source/communityframework/communityframework/Misc/IngredientValueGetter_Mass.cs index 5104717..af94ca1 100644 --- a/Source/communityframework/communityframework/Misc/IngredientValueGetter_Mass.cs +++ b/Source/communityframework/communityframework/Misc/IngredientValueGetter_Mass.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Verse; +using Verse; namespace CF { diff --git a/Source/communityframework/communityframework/Misc/Ranged Shield Belt/Gizmo_RangedShieldStatus.cs b/Source/communityframework/communityframework/Misc/Ranged Shield Belt/Gizmo_RangedShieldStatus.cs index e15237b..64c5a91 100644 --- a/Source/communityframework/communityframework/Misc/Ranged Shield Belt/Gizmo_RangedShieldStatus.cs +++ b/Source/communityframework/communityframework/Misc/Ranged Shield Belt/Gizmo_RangedShieldStatus.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEngine; +using UnityEngine; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Misc/Ranged Shield Belt/RangedShieldBelt.cs b/Source/communityframework/communityframework/Misc/Ranged Shield Belt/RangedShieldBelt.cs index 801a32c..531f158 100644 --- a/Source/communityframework/communityframework/Misc/Ranged Shield Belt/RangedShieldBelt.cs +++ b/Source/communityframework/communityframework/Misc/Ranged Shield Belt/RangedShieldBelt.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; using RimWorld; using Verse; using UnityEngine; @@ -43,11 +40,17 @@ public class RangedShieldBelt : Apparel private int KeepDisplayingTicks = 1000; private float ApparelScorePerEnergyMax = 0.25f; private static readonly Material BubbleMat = MaterialPool.MatFrom("Other/ShieldBubble", ShaderDatabase.Transparent); - #endregion fields - #region properties +#endregion fields +#region properties private float EnergyMax => this.GetStatValue(StatDefOf.EnergyShieldEnergyMax); private float EnergyGainPerTick => this.GetStatValue(StatDefOf.EnergyShieldRechargeRate) / 60f; + /// + /// The amount of energy that the shiled belt currently has. + /// public float Energy => energy; + /// + /// If the shield has run out of energy, and needs time to recharge before blocking more shots. + /// public bool ShieldIsResetting => ticksToReset > 0; private bool ShouldDisplay { @@ -68,6 +71,9 @@ private bool ShouldDisplay /// True. public override bool AllowVerbCast(Verb v) => true; + /// + /// Expose save/load data to the scribe. + /// public override void ExposeData() { base.ExposeData(); @@ -75,12 +81,23 @@ public override void ExposeData() Scribe_Values.Look(ref ticksToReset, nameof(ticksToReset), -1); Scribe_Values.Look(ref lastKeepDisplayTick, nameof(lastKeepDisplayTick)); } + /// + /// Generates on-screen gizmos for when the pawn wearing the shield belt is selected. + /// + /// An enumerable containing the gizmos generated. public override IEnumerable GetWornGizmos() { foreach (Gizmo wornGizmo in base.GetWornGizmos()) yield return wornGizmo; if(Find.Selector.SingleSelectedThing == base.Wearer) yield return new Gizmo_RangedShieldStatus() { shield = this }; } + /// + /// The value offset provided by this specific shield belt, based on the maximum amount of energy it can store. + /// + /// public override float GetSpecialApparelScoreOffset() => EnergyMax * ApparelScorePerEnergyMax; + /// + /// Method run each game tick. Updates the shield belt's charge status. + /// public override void Tick() { base.Tick(); @@ -97,6 +114,11 @@ public override void Tick() energy = EnergyMax; } } + /// + /// Method run each time the pawn wearing the shield belt takes damage. Determines if the damage should be blocked, based on the current energy level of the shield belt, and the type of damage taken. + /// + /// Information about the damage taken by the pawn. + /// true if the shield belt has successfully blocked the damage taken by the pawn. false if the belt has insufficient energy to block the damage, or if the damage was an EMP attack. public override bool CheckPreAbsorbDamage(DamageInfo dinfo) { if (ShieldIsResetting) return false; @@ -114,6 +136,9 @@ public override bool CheckPreAbsorbDamage(DamageInfo dinfo) } return false; } + /// + /// Notify the shield belt that it should start or continue displaying the shield overlay effect. + /// public void KeepDisplaying() { lastKeepDisplayTick = Find.TickManager.TicksGame; @@ -152,6 +177,9 @@ private void Reset() ticksToReset = -1; energy = EnergyOnReset; } + /// + /// Draws the shield bubble over the pawn that is wearing the shield belt. + /// public override void DrawWornExtras() { if(!ShieldIsResetting && ShouldDisplay) diff --git a/Source/communityframework/communityframework/ModSettings.cs b/Source/communityframework/communityframework/ModSettings.cs index 6012094..d5e2610 100644 --- a/Source/communityframework/communityframework/ModSettings.cs +++ b/Source/communityframework/communityframework/ModSettings.cs @@ -12,38 +12,101 @@ namespace CF /// Static for convenience. public class CFSettings : ModSettings { + /// + /// This is manually prefixed onto every mod settings string key + /// that is defined in the framework's language XML, to avoid the + /// possibility of a translation key collision. + /// public static readonly string KeyPrefix = "CFSettings_"; + /// + /// This is manually affixed onto every string key for a mod setting's + /// title, in the framework's language XML. + /// public static readonly string NamePostfix = "_Name"; + /// + /// This is manually affixed onto every string key for a mod setting's + /// description, in the framework's language XML. + /// public static readonly string DescPostfix = "_Desc"; + /// + /// If true, then the framework is running in debug mode, and + /// debug logging and features are currently active. + /// public static bool DEBUG = false; //for release set false by default + /// + /// If the framework should log which methods it has patched on + /// startup. + /// public static bool PrintPatchedMethods => DEBUG && printPatchedMethods; + /// + /// If the framework should log which methods it has patched on + /// startup. + /// public static bool printPatchedMethods = false; - // despite being public, please don't access these. Access patch - // application settings with ShouldPatch. - // They're only public so they can be used in the mod settings screen. + /// + /// A list of Harmony patches to apply on startup. + /// + /// + /// despite being public, please don't access these. Access patch + /// application settings with ShouldPatch. + /// They're only public so they can be used in the mod settings screen. + /// public static Dictionary Patches = new Dictionary(); + /// + /// Represents a single one of the framework's Harmony patches, and + /// whether or not it should be applied. + /// public class PatchSave : IExposable { + /// + /// If the patch should be applied. + /// public bool apply; + /// + /// Identifier used to associate this patch save with the specific + /// Harmony patch that it represents. + /// public string saveKey; - // The game requires a no-arg constructor + /// + /// A no-arg constructor, required by the vanilla API. Does + /// nothing. + /// public PatchSave() { } + /// + /// Constructor with parameters for initializing fields. + /// + /// + /// The save key, used to associate this patch save with the + /// specific Harmony patch that it represents. + /// + /// + /// If the patch should be applied. + /// public PatchSave(string s, bool a) { saveKey = s; apply = a; } + /// + /// Returns a string containing the saveKey of the patch, + /// and whether or not the patch should be applied. + /// + /// public override string ToString() { return "<{" + saveKey + ": " + apply + "}>"; } + /// + /// Saves and/or loads the fields of this PatchSave, so that + /// patch settings are persistent between game sessions. + /// public void ExposeData() { Scribe_Values.Look(ref saveKey, "saveKey"); @@ -51,6 +114,11 @@ public void ExposeData() } } + /// + /// Saves and/or loads the fields of each + /// stored, so that patch settings are persistent between game + /// sessions. + /// public override void ExposeData() { base.ExposeData(); @@ -68,6 +136,17 @@ public override void ExposeData() Scribe_Values.Look(ref printPatchedMethods, "printPatchedMethods"); } + /// + /// Determines whether or not the given patch should be run for this + /// session. + /// + /// + /// The identifier of the patch being checked. + /// + /// + /// true if the patch should be applied, false if the + /// player has chosen to disable it. + /// public static bool ShouldPatch(string patchkey) { if (!DEBUG) return true; @@ -80,6 +159,8 @@ public static bool ShouldPatch(string patchkey) return Patches[patchkey].apply; } + /// + /// public static List SerializePatches() { List ret = new List(); @@ -91,6 +172,8 @@ public static List SerializePatches() return ret; } + /// + /// public static void DeserializePatches(List list) { foreach (PatchSave pi in list) @@ -107,12 +190,23 @@ public static void DeserializePatches(List list) public class CFMod : Mod { CFSettings settings; + /// + /// Constructor for the Framework's mod data. Initializes the + /// framework's mod settings, and loads all of the patch data. + /// + /// Unused in this override. public CFMod(ModContentPack con) : base(con) { - this.settings = GetSettings(); + settings = GetSettings(); new HarmonyLoader(); } + /// + /// Draws the contents of the framework's mod settings window. + /// + /// + /// The to draw the settings window onto. + /// public override void DoSettingsWindowContents(Rect inRect) { Listing_Standard listing = new Listing_Standard(); @@ -155,6 +249,13 @@ public override void DoSettingsWindowContents(Rect inRect) base.DoSettingsWindowContents(inRect); } + /// + /// The name of the framework's listing in the game's list of available + /// mod settings menus. + /// + /// + /// + /// public override string SettingsCategory() { return "CFSettings_Category".Translate(); diff --git a/Source/communityframework/communityframework/OutputWorker/OutputWorker.cs b/Source/communityframework/communityframework/OutputWorker/OutputWorker.cs index 1435324..cf49de4 100644 --- a/Source/communityframework/communityframework/OutputWorker/OutputWorker.cs +++ b/Source/communityframework/communityframework/OutputWorker/OutputWorker.cs @@ -8,7 +8,7 @@ namespace CF /// Abstract base class containing methods to run upon completing certain /// recipes. /// - abstract class OutputWorker + public abstract class OutputWorker { /// /// Method to run when a recipe is completed, but before the products @@ -29,15 +29,17 @@ abstract class OutputWorker /// /// Index of the desired graphic override. /// - public abstract void PreCraft( + public virtual void PreCraft( RecipeDef recipeDef, Pawn worker, IEnumerable ingredients, IBillGiver billGiver, - Precept_ThingStyle precept=null, - ThingStyleDef style=null, - int? overrideGraphicIndex=null - ); + ref Precept_ThingStyle precept, + ref ThingStyleDef style, + ref int? overrideGraphicIndex + ) + { + } /// /// Method to run when a recipe is completed, after the products are @@ -69,7 +71,7 @@ public abstract void PreCraft( /// /// Any additional Things to be added to recipe products. /// - public abstract IEnumerable PostCraft( + public virtual IEnumerable PostCraft( IEnumerable products, RecipeDef recipeDef, Pawn worker, @@ -78,6 +80,9 @@ public abstract IEnumerable PostCraft( Precept_ThingStyle precept=null, ThingStyleDef style=null, int? overrideGraphicIndex=null - ); + ) + { + return new List(); + } } } diff --git a/Source/communityframework/communityframework/OutputWorker/OutputWorker_RandomStyle.cs b/Source/communityframework/communityframework/OutputWorker/OutputWorker_RandomStyle.cs new file mode 100644 index 0000000..ea551f1 --- /dev/null +++ b/Source/communityframework/communityframework/OutputWorker/OutputWorker_RandomStyle.cs @@ -0,0 +1,95 @@ +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using Verse; + +namespace CF +{ + /// + /// A base for making recipes that randomize the style of crafted + /// products. + /// + public abstract class OutputWorker_RandomStyle : OutputWorker + { +#pragma warning disable CS0649 + /// + /// If true, then any ideological styles that the crafter has will override the + /// randomly-assigned style, assuming that any such style exists for the crafted product. + /// + public bool ideoPreceptOverrides = false; + /// + /// A percent chance that the crafted product will have its default appearence, instead of + /// being given one randomly. + /// + public float noStyleChance = 0f; +#pragma warning restore CS0649 + + /// + /// A list of styles to be chosen from when randomly applying a style to the product of a + /// given recipe. + /// + /// + /// The recipe being performed. + /// + /// + /// A list of styles that may be randomly applied to the products of recipe + /// + public abstract IEnumerable StylesFor(RecipeDef recipe); + + /// + public override void PreCraft( + RecipeDef recipeDef, + Pawn worker, + IEnumerable ingredients, + IBillGiver billGiver, + ref Precept_ThingStyle precept, + ref ThingStyleDef style, + ref int? overrideGraphicIndex + ) + { + IEnumerable availableStyles = StylesFor(recipeDef); + + if (availableStyles.EnumerableNullOrEmpty()) + return; + + if (ideoPreceptOverrides && precept != null && style != null) + return; + + if (Rand.Chance(noStyleChance)) + return; + + precept = null; + style = availableStyles.RandomElementByWeight(s => s.Chance).StyleDef; + } + } + + /// + /// An that gives a recipe's products a random style from a + /// predefined list. + /// + public class OutputWorker_RandomStyleFromList : OutputWorker_RandomStyle + { +#pragma warning disable CS0649 + /// + /// A list of styles to be chosen from randomly. + /// + public IEnumerable randomStyles; +#pragma warning restore CS0649 + + /// + public override IEnumerable StylesFor(RecipeDef recipe) => randomStyles; + } + + /// + /// An that gives a recipe's products a random style the product's + /// own list of randomly-selected styles. + /// + public class OutputWorker_RandomStyleFromDef : OutputWorker_RandomStyle + { + /// + public override IEnumerable StylesFor(RecipeDef recipe) + { + return recipe?.ProducedThingDef?.randomStyle; + } + } +} diff --git a/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_AgainstWall.cs b/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_AgainstWall.cs index 8084020..9aeaaff 100644 --- a/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_AgainstWall.cs +++ b/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_AgainstWall.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using UnityEngine; -using Verse; +using Verse; using RimWorld; namespace CF @@ -15,6 +13,27 @@ namespace CF /// public class PlaceWorker_AgainstWall : PlaceWorker { + /// + /// Ensures that the building is placed on a cell adjacent to but facing away from a wall. + /// + /// + /// The using the + /// + /// + /// The location that the building is being placed at. + /// + /// + /// The rotation that the building is being placed at. + /// + /// + /// The that the building is being placed in. + /// + /// Unused. + /// Unused. + /// + /// true if the cell behind the building being placed contains a wall, and is within + /// the map bounds. + /// public override AcceptanceReport AllowsPlacing( BuildableDef checkingDef, IntVec3 loc, @@ -49,6 +68,28 @@ public override AcceptanceReport AllowsPlacing( /// public class PlaceWorker_OnWall : PlaceWorker { + /// + /// Ensure that the building being placed is placed on a wall but not overlapping the same + /// Thing in the same rotation. + /// + /// + /// The using the + /// + /// + /// The location that the building is being placed at. + /// + /// + /// The rotation that the building is being placed at. + /// + /// + /// The that the building is being placed in. + /// + /// Unused. + /// Unused. + /// + /// true if the cell at loc contains a wall, and does not contain an + /// identical building at the same rotation. + /// public override AcceptanceReport AllowsPlacing( BuildableDef checkingDef, IntVec3 loc, @@ -86,6 +127,12 @@ public override AcceptanceReport AllowsPlacing( return true; } + /// + /// Always allows buildings using this to be placed over any + /// other building. + /// + /// The building being placed onto. + /// Always true public override bool ForceAllowPlaceOver(BuildableDef other) { return true; diff --git a/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_NotImpassible.cs b/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_NotImpassible.cs new file mode 100644 index 0000000..8908a53 --- /dev/null +++ b/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_NotImpassible.cs @@ -0,0 +1,64 @@ +using Verse; + +namespace CF +{ + /// + /// that ensures that the parent + /// is not places on the same cell as any other + /// that has a + /// of . + /// + class PlaceWorker_NotImpassible : PlaceWorker + { + /// + /// Ensures that the parent is not places on the + /// same cell as any other that has a + /// . + /// + /// + /// The using the + /// + /// + /// The location that the building is being placed at. + /// + /// + /// The rotation that the building is being placed at. + /// + /// + /// The that the building is being placed in. + /// + /// Unused. + /// Unused. + /// + /// false if any impassible building exists in any cell occupied + /// by the blueprint being placed. true if no impassible + /// building exists, meaning that placement is permitted. + /// + public override AcceptanceReport AllowsPlacing( + BuildableDef checkingDef, + IntVec3 loc, + Rot4 rot, + Map map, + Thing thingToIgnore = null, + Thing thing = null + ) + { + BuildableDef otherThingFinished; + + foreach (IntVec3 c in GenAdj.CellsOccupiedBy(loc, rot, checkingDef.Size)) + { + foreach (Thing otherThing in c.GetThingList(map)) + { + otherThingFinished = CommunityBuildingUtility + .GetFullyConstructedDefOf(otherThing.def, + out CommunityBuildingUtility.EBuildableDefStage _); + + if (otherThingFinished.passability == Traversability.Impassable) + return false; + } + } + + return true; + } + } +} diff --git a/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_Roofed.cs b/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_Roofed.cs index eaa7190..383b951 100644 --- a/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_Roofed.cs +++ b/Source/communityframework/communityframework/PlaceWorkers/PlaceWorker_Roofed.cs @@ -1,7 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; using Verse; namespace CF @@ -15,6 +13,38 @@ namespace CF /// public class PlaceWorker_Roofed : PlaceWorker { + /// + /// Checks that the parent is placed under a roof. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// false if the blueprint is being placed out in the open + /// without a roof over it. true if every cell of the blueprint + /// being placed is roofed, meaning that placement is permitted. + /// public override AcceptanceReport AllowsPlacing( BuildableDef checkingDef, IntVec3 loc, @@ -43,6 +73,40 @@ public override AcceptanceReport AllowsPlacing( /// public class PlaceWorker_RoofHanger : PlaceWorker_Roofed { + /// + /// Ensures that the parent is placed under a roof, + /// and not over any other that is too tall. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// false if the blueprint's area is not fully roofed, or if + /// there are any other s occupying the same space + /// as the blueprint which are too tall. true if none of the + /// prior conditions are violated, meaning that placement is permitted. + /// public override AcceptanceReport AllowsPlacing( BuildableDef checkingDef, IntVec3 loc, diff --git a/Source/communityframework/communityframework/Properties/AssemblyInfo.cs b/Source/communityframework/communityframework/Properties/AssemblyInfo.cs index f6a4ffd..5ee9e53 100644 --- a/Source/communityframework/communityframework/Properties/AssemblyInfo.cs +++ b/Source/communityframework/communityframework/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.4.0.0")] +[assembly: AssemblyFileVersion("1.4.0.0")] diff --git a/Source/communityframework/communityframework/RecipeWorker/Recipe_InstallOrReplaceImplant.cs b/Source/communityframework/communityframework/RecipeWorker/Recipe_InstallOrReplaceImplant.cs index 0f3dbba..dbcb260 100644 --- a/Source/communityframework/communityframework/RecipeWorker/Recipe_InstallOrReplaceImplant.cs +++ b/Source/communityframework/communityframework/RecipeWorker/Recipe_InstallOrReplaceImplant.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Ulog.cs b/Source/communityframework/communityframework/Ulog.cs index cddf397..9c044dd 100644 --- a/Source/communityframework/communityframework/Ulog.cs +++ b/Source/communityframework/communityframework/Ulog.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Verse; +using Verse; namespace CF { diff --git a/Source/communityframework/communityframework/Utilities/ClassWithPatchesAttribute.cs b/Source/communityframework/communityframework/Utilities/ClassWithPatchesAttribute.cs index a73ec9c..8278a84 100644 --- a/Source/communityframework/communityframework/Utilities/ClassWithPatchesAttribute.cs +++ b/Source/communityframework/communityframework/Utilities/ClassWithPatchesAttribute.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace CF { diff --git a/Source/communityframework/communityframework/Utilities/CommunityBuildingUtility.cs b/Source/communityframework/communityframework/Utilities/CommunityBuildingUtility.cs index 2a3185d..1f89291 100644 --- a/Source/communityframework/communityframework/Utilities/CommunityBuildingUtility.cs +++ b/Source/communityframework/communityframework/Utilities/CommunityBuildingUtility.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using Verse; using Verse.Sound; using RimWorld; @@ -99,5 +95,74 @@ Map map } return false; } + + /// + /// If the given defines an incomplete + /// building (a blueprint or building frame), then this method will + /// give the of the finished building. + /// + /// + /// The to be evaluated. + /// + /// + /// The construction stage that this + /// defines. + /// + /// + /// The of the building when it is fully + /// constructed. If the building is already fully constructed, then + /// the method will return the same reference as the building + /// parameter. + /// + public static BuildableDef GetFullyConstructedDefOf( + BuildableDef building, + out EBuildableDefStage stage + ) + { + if (!(building is ThingDef thingDef)) + { + stage = EBuildableDefStage.Building; + return building; + } + + if (thingDef.IsBlueprint) + { + stage = EBuildableDefStage.Blueprint; + return thingDef.entityDefToBuild; + } + if (thingDef.IsFrame) + { + stage = EBuildableDefStage.Frame; + return thingDef.entityDefToBuild; + } + stage = EBuildableDefStage.Building; + return building; + } + + /// + /// An enumerator that contains all of the stages of building + /// construction, including finished and unfinished stages. + /// + public enum EBuildableDefStage + { + /// + /// The building has been planned out by the player, but + /// construction has not yet begun, and no resources have been + /// delivered. + /// + Blueprint, + /// + /// Colonists have begun working on this building. This represents + /// any time between the first resource being delivered, and all of + /// the required work being completed. + /// + Frame, + /// + /// The building is fully completed. It requires no additional + /// resources or work, and is behaving exactly as is defined in its + /// . + /// + Building, + } } } diff --git a/Source/communityframework/communityframework/Utilities/CommunityQualityUtility.cs b/Source/communityframework/communityframework/Utilities/CommunityQualityUtility.cs index 5973836..52dfe13 100644 --- a/Source/communityframework/communityframework/Utilities/CommunityQualityUtility.cs +++ b/Source/communityframework/communityframework/Utilities/CommunityQualityUtility.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Reflection; +using System.Reflection; using Verse; using RimWorld; diff --git a/Source/communityframework/communityframework/Utilities/CommunityRecipeUtility.cs b/Source/communityframework/communityframework/Utilities/CommunityRecipeUtility.cs index 0dfad6b..6e25773 100644 --- a/Source/communityframework/communityframework/Utilities/CommunityRecipeUtility.cs +++ b/Source/communityframework/communityframework/Utilities/CommunityRecipeUtility.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Reflection; using Verse; using RimWorld; @@ -18,22 +14,21 @@ static class CommunityRecipeUtility { /// /// An empty delegate to define the method signature used by - /// . + /// Verse.GenRecipe.PostProcessProduct. /// - private delegate Thing PostProcessProductDelegate( + private delegate Thing PostProcessProductSignature( Thing product, RecipeDef recipeDef, Pawn worker, - Precept_ThingStyle - precept=null, + Precept_ThingStyle precept=null, ThingStyleDef style=null, int? overrideGraphicIndex=null); /// /// This delegate refers to the private method - /// . + /// Verse.GenRecipe.PostProcessProduct. /// - private static Delegate postProcessProductDelegate; + private readonly static Delegate postProcessProductDelegate; /// /// Sets up delegates refering to private methods. @@ -43,7 +38,7 @@ static CommunityRecipeUtility() postProcessProductDelegate = typeof(GenRecipe).GetMethod( "PostProcessProduct", BindingFlags.NonPublic | BindingFlags.Static - ).CreateDelegate(typeof(PostProcessProductDelegate)); + ).CreateDelegate(typeof(PostProcessProductSignature)); } /// @@ -61,6 +56,10 @@ static CommunityRecipeUtility() /// The recipe that created the product /// The pawn doing the recipe /// The pawn's ideo style precept + /// The style that will be applied to the product. + /// + /// Index override for the graphic. + /// /// A reference to product. public static Thing PostProcessProduct( Thing product, diff --git a/Source/communityframework/communityframework/Utilities/StartupUtil.cs b/Source/communityframework/communityframework/Utilities/StartupUtil.cs new file mode 100644 index 0000000..a6714eb --- /dev/null +++ b/Source/communityframework/communityframework/Utilities/StartupUtil.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using Verse; + +namespace CF +{ + /// + /// A class that, on startup, does any def modifications and caches any values neccessary. + /// + [StaticConstructorOnStartup] + public class StartupUtil + { + /// + /// A list of buildings that have , with + /// set to true. Cached here on + /// startup so that we don't have to go looking through the entire + /// database anytime a short circuit occurs. + /// + public static readonly List ExtraShortCircuitSources = new List(); + + static StartupUtil() + { + foreach (ThingDef thingDef in DefDatabase.AllDefsListForReading) + { + PowerExtension powerExtension = thingDef.GetModExtension(); + + if (powerExtension != null) + { + if (powerExtension.shortCircuitSource) + ExtraShortCircuitSources.Add(thingDef); + } + } + } + } +} diff --git a/Source/communityframework/communityframework/communityframework.csproj b/Source/communityframework/communityframework/communityframework.csproj index 603bad1..ea4b777 100644 --- a/Source/communityframework/communityframework/communityframework.csproj +++ b/Source/communityframework/communityframework/communityframework.csproj @@ -29,10 +29,11 @@ TRACE prompt 4 + ..\..\..\Common\Assemblies\communityframework.xml - - ..\packages\Lib.Harmony.2.2.0\lib\net472\0Harmony.dll + + ..\..\..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll False @@ -80,9 +81,18 @@ + + + + + + + + + @@ -119,6 +129,7 @@ +