Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - ilikegoodfood

#1
Releases / [1.0] Verb Expansion Framework (v1.1.5)
July 30, 2019, 06:22:37 AM
Verb Expansion Framework

Public Service Announcement
Work on a completely refactored Verb Expansion Framework 2.0 is likely to commence soon(TM).
Soon looks like some time next month Please remember thatit will take considerable time to developel this release, especially with the new changes Tynana has implemented in the code-base.
It will  not be released by myself as I am handing VEF off Erdelf, an increadibly skilled and dedicated RimWorld modder.

About:

The Verb Expansion Framework was initially conceived of as a complete re-implementation of the Range Animal Framework. This initial release has succeeded in that goal, along with a handful of other enhancements.
The long term goal is to provide a broadly increased combat scope, making violence on the Rim more varied, tactical and exotic, than ever before.

Features:

  • All types of Pawn, be they animals, colonists, humanoids or mechanoids, will recognise and use Ranged Verbs from Equipment, Hediffs and Race Definitions.
  • If they have any, animals will use Ranged Verbs preferentially when manhunting (as will manhunting humanoids) or when defending their master.
  • AI with multiple ranged verbs will approximate their usefulness and select the most useful ranged verb to use.
  • Colonists that have Ranged Verbs that are not from their Equipment or that have multiple Ranged Verbs will show an additional Gizmo that allows the player to set which ranged verb they should use in combat (colonists must be drafted to make the selection).
  • Colonists that have Ranged Verbs but do not have any Equipment will display and respect the Toggle Fire-at-Will gizmo.
  • Ranged Verbs from Hediffs display all of the appropriate interactions with the Brawler Trait (unhappy thought, 'Brawler has Ranged Weapon' warning in sidebar, and the Operations 'Add Bill' Menu will display the 'Brawler will be unhappy' warning for appropriate operations).
  • All bleeding-capable pawns have their total bleed rate multiplied by the new Bleed Rate Capacity.
  • Implements Verb_ShootBody, which modifies the damage dealt based on the body size of the pawn using the verb.
  • Implemented VEF_Verb_Explode, VEF_Verb_ExplodeSafe and VEF_Verb_SelfDestruct.
  • Implemented VEF_VerbProperties_Explode to support VEF_Verb_Explode, VEF_Verb_ExplodeSafe and VEF_Verb_SelfDestruct verb classes.
  • Implements versions of Explosions, Extinguishers, and Flames that do not trigger camera shake. Provided by Ogliss.
  • Implements HediffComp and ThingComp versions of Smokepop Belt.
  • Implements HediffComp HealthModifier (Legacy), HealthModifier Capacity and HealthModifierFactor Capacity.
  • Implements HediffSets, allowing you to lock powerful bonuses or penalties behind multiple prerequisite hediffs.

Details:
For full information and documentation, please use the github wiki.

Installation and Compatibility:
The Verb Expansion Framework does not come with any additional content, only utilities for other mods to add content. You will only need to load VEF as a dependancy for another mod.
If you do need to load VEF as a dependancy, it must be loaded between Core and the all mods that are dependant on it. I would recommend placing it high up in the load order, among the other frameworks, such as HugsLibs and JecsTools.


This mod should be compatible with any mod, so long as it doesn't alter the way that equipment, hediffs or ranged verbs work.
Before installing this mod into your precious saved game, load it into your mod-list and attempt to create a new game. Run some basic combat tests and if it produces errors that you do not normally see, report them and discontinue use of the framework with that mod-list.

Downloads:
For RimWorld 1.0
SteamWorkshop
GitHub (Direct Download)
#2
Help / Harmony Transpiler Help
October 11, 2018, 02:08:33 PM
Continuing on from my other, more general help thread, I need specific help with the creation of two transpiler patches.

I could very easily place a high-priority patch in-front of the other patch and function in such a way that it mimics both functions, plus what I need, and always returns false, however, this would make it incompatible with pretty much everything.

What I need to do is implement a variant of the following  code snippet from GetUpdatedAvailableVerbsList into ARA_VerbCheck_Patch and TryGetAttackVerb. Both versions of the code will need to be different, doing different things.

foreach (Verb verb in this.pawn.health.hediffSet.GetHediffsVerbs())
{
if (verb.IsStillUsableBy(this.pawn))
{
Pawn_MeleeVerbs.meleeVerbs.Add(new VerbEntry(verb, this.pawn));
}
}


So far, I have learned how to read IL Code, about Stacks and how to target a specific line of IL Code for the purposes of patching, all in half a day, but how to get the patch to return altered code to the target location and how best to write that code is still a bit of a mystery to me.

Right, lets start with the first and simplest of the two transpilers: ARA_VerbCheck_Patch.
The patch in question compiles a list of Verbs from the __instance (Pawn) and calls it allVerbs. To make it do what I need it to (enable ranged verbs from a hediffDef), I need to iterate through the hediffs from __instance (Pawn) and add any verbs from those hediffs to allVerbs before the next line of code runs.

Approximation of the additional C# code:
        foreach (Verb verb in __instance.health.hediffSet.GetHediffsVerbs())
{
if (verb.IsStillUsableBy(__instance))
{
allVerbs.Add(new VerbEntry(verb, this.pawn));
}
                }


How would I go about doing this?

Thanks for you help.
#3
Help / Looking for Artists
October 10, 2018, 07:18:57 AM
Hello fellow modders.
I'm not sure how this is normally done, so here goes:

Thus far I have been making all of my own artwork for my mod, MonsterMash (Steam Workshop) (Ludeon Forums).
Much as I might like to tinker with art, I have never been particularly good at it, nor dedicated in it's study.

I recently received a message from a subscriber to my mod saying that, while they like the mod, the graphics are a deal-breaker for them. I promised to go looking for an artist, so here I am.

The mod currently contains 2 buildings, 5 creatures, 3 projectiles and 3 sets of packs.
If anyone is willing to team up with me and provide improved textures for my mod, either as a one-off or continuous support, I would be very grateful, as would my subscribers.

Obviously you would be credited fully for the artwork.

Thank you very much for considering this request.
#4
Help / Ranged Verb from hediffDef
October 10, 2018, 04:55:18 AM
To try and keep this minimal, I'm going to explain only my most immediate issue.

I am attempting to make a hediffDef that grants a ranged verb to pawns, both animals and colonists alike. In order to facilitate the use of ranged verbs in animals I am using the RangeAnimalFramework (Steam Workshop) (Forum) by BrokenValkyrie.

I have created a hediffDef, see below, that uses the standard HediffCompProperties_VerbGiver, which does not flag any errors. As far as I can tell by reading the C#, it isn't limited to tools.

<HediffDef ParentName="AddedBodyPartBase">
<defName>MM_ThermalLanceAssembly</defName>
<label>thermal lance assembly</label>
<labelNoun>a thermal lance assembly</labelNoun>
<!--<spawnThingOnRemoved>ArchotechArm</spawnThingOnRemoved>-->
<comps>
    <li Class="HediffCompProperties_VerbGiver">
<verbs>
<li>
<verbClass>Verb_Shoot</verbClass>
<accuracyTouch>0.7</accuracyTouch>
<accuracyShort>0.8</accuracyShort>
<accuracyMedium>0.9</accuracyMedium>
<accuracyLong>0.85</accuracyLong>
<hasStandardCommand>true</hasStandardCommand>
<defaultProjectile>MM_PolarColossusProjectile</defaultProjectile>
<warmupTime>3</warmupTime>
<burstShotCount>0</burstShotCount>
<minRange>6</minRange>
<range>27</range>
<soundCast>ChargeLance_Fire</soundCast>
<soundCastTail>GunTail_Light</soundCastTail>
<muzzleFlashScale>12</muzzleFlashScale>
</li>
</verbs>
    </li>
</comps>
<stages>
<li>
<statOffsets>
<ComfyTemperatureMin>-40</ComfyTemperatureMin>
<ComfyTemperatureMax>-10</ComfyTemperatureMax>
</statOffsets>
</li>
</stages>
<addedPartProps>
<solid>true</solid>
<partEfficiency>1.1</partEfficiency>
<betterThanNatural>true</betterThanNatural>
</addedPartProps>
    </HediffDef>


Now, once the hediff is added to the pawn, it should add the Verb to their list of verbs. This is where the RangeAnimalFramework comes in. It contains a function, ARA_VerbChecker_Patch, that checks non-colonists for ranged verbs and adds them to the pawn's verb list. It also contains various functions that enable animal behaviors associated with ranged weapons.

Since ARA_VerbChecker_Patch is a prefix to the core TryGetAttackVerb, it should be called each time TryGetAttackVerb is called. If I understand the code correctly, TryGetAttackVerb is called each time a pawn tries to attack a target, therefore the new verb should be added to the animal's verb list and it should use the new verb.
This appears to not be the case.

Furthermore, once I can work out that the verb is correctly being added to the pawn and how to make sure that AnimalRangeFramework allows it to be used in animals, I will then need to override the core TryGetAttackVerb in order to make colonists recognize and use it.

Is my understanding of the code, as described above, correct so far?
If not, what am I getting wrong?

I also need help with why the verb isn't being added or detected by the AnimalRangeFramework.
And then I'll need help with creating a safe, functional override for TryGetAttackVerb, assuming that is the correct thing after all, or whatever else needs to be changed.

Thank you all very much in advance.

P.S.
On a slight side-note, I noticed while poking around inside of EPOE's files that they also had an addedBodyPart hediffDef that granted a ranged verb, but it was commented out. I suspect they tried to do the same at some point and abandoned the idea for some reason.
#5
Help / Corpse.CalculateMarketValue Exceptoion (SOLVED)
September 29, 2018, 01:43:40 PM
I've spent the day systematically fixing bugs and updating my Monster Mash mod from b18 to b19 and have found a yellow error that I have no clue how to tackle.

Caught exception while loading play data but there are active mods other than Core. Resetting mods config and trying again.
The exception was: System.NullReferenceException: Object reference not set to an instance of an object
  at RimWorld.ThingDefGenerator_Corpses.CalculateMarketValue (Verse.ThingDef raceDef) [0x00000] in <filename unknown>:0
  at RimWorld.ThingDefGenerator_Corpses+<ImpliedCorpseDefs>c__Iterator0.MoveNext () [0x00000] in <filename unknown>:0
  at System.Linq.Enumerable+<CreateConcatIterator>c__Iterator1`1[Verse.ThingDef].MoveNext () [0x00000] in <filename unknown>:0
  at RimWorld.DefGenerator.GenerateImpliedDefs_PreResolve () [0x00000] in <filename unknown>:0
  at Verse.PlayDataLoader.DoPlayLoad () [0x00000] in <filename unknown>:0
  at Verse.PlayDataLoader.LoadAllPlayData (Boolean recovering) [0x00000] in <filename unknown>:0
Verse.Log:Warning(String, Boolean)
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__1()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__1()


All of the body plans have been correctly updated and the dessicated graphics implemented. All in all, I have no clue what's causing it or how to go about fixing it.

As far as I can tell, this should be the last bug, assuming compatibility updates go smoothly, so fixing it will take me a major step closer to release. Any help would be very much appreciated.
Thanks in advance.

#6
Releases / [1.0] Variable Bleed Rate Framework
September 26, 2018, 05:24:52 AM
This is a very simple framework (a single line injection) that enables manipulation of the Total Bleed Rate of a pawn through the introduction of the BleedRate Capacity.

The Total Bleed Rate is now determined as the sum of all injuries' bleed rates multiplied by the BleedRate Capacity.
The BleedRate Capacity can be effected by hediffDefs, such as medicines, poisons, injuries, etc., just like all other pawn Capacities.

LICENSE:
This mod was made to be a standalone framework for the use of other mods. Credit would be appreciated, but there's only so much room for credits, so it's not a must.

DOWNLOADS:
1.0
Steam Workshop
Direct Download (Dropbox)

B19
Steam Workshop
Direct Download (Dropbox)

USE:
To enable this mod either:
1) Make your mod dependant on this one, which will require your user to make sure that they have downloaded this mod and loaded it before your own.
2) Copy the Variable Bleed Rate.dll into your mod's assembly folder and merge the included Defs with your own.
2a) If your mod doesn't already have the 0Harmony.dll assembly, copy that over too. It will not work without it.

FREQUENTLY ASKED QUESTIONS:
Q) Why make a Framework mod for something so small?
A) While it is an extremely small and extremely simple mod, it provides a much needed base functionality to those who are not familiar with the C# side of RimWorld modding, and prevents potential conflicts between mods that create the same effect in different ways.
If we all use the framework from the get-go, then all of our mods will work together.
#7
Help / Variable Bleed Rate Framework (SOLVED)
September 03, 2018, 07:00:43 AM
As part of my MonsterMash [B18] mod I created a small harmony patch and some defs so that I could manipulate the total bleed rate of a pawn.

Now that I have to update my mod to B19 anyway, I would like to separate out the Variable Bleed Rate as a standalone framework that other modders can use. This should reduce the likelihood of conflicts in future when other mods start to use similar methods, as well as make it easier for everyone. I know that another mod is already using my code, and will inform them of the change if I get it working.

It works by creating a hidden Capacity and Stat on organic pawns, both called BleedRate, and then multiplying the final BleedRate value by that modifier. The stat can then be freely manipulated by hediffDefs to get the desired result.

Ultimately I would like to update it into a .dll only mod for more general use. Please help!
As far as I can tell, the harmony patch works perfectly, but I have no idea how to add the PawnCapacity and Stat through the assembly.


Here is the current [B18] code for the mod:
PawmCapacity.xml
<?xml version="1.0" encoding="utf-8" ?>

<Defs>

<PawnCapacityDef>
<defName>BleedRate</defName>
<label>bleed rate</label>
<listOrder>9</listOrder>
<showOnHumanlikes>false</showOnHumanlikes>
<showOnAnimals>false</showOnAnimals>
<showOnMechanoids>false</showOnMechanoids>
</PawnCapacityDef>

</Defs>


Stats_Pawns_General.xml
<?xml version="1.0" encoding="utf-8" ?>

<Defs>

<StatDef>
<defName>BleedRate</defName>
<label>bleed rate</label>
<description>Multiplier on bleed rate.</description>
<category>BasicsPawn</category>
<defaultBaseValue>1</defaultBaseValue>
<toStringStyle>PercentZero</toStringStyle>
<hideAtValue>1</hideAtValue>
<minValue>0.1</minValue>
<showOnMechanoids>false</showOnMechanoids>
<capacityFactors>
<li>
<capacity>BleedRate</capacity>
<weight>1</weight>
</li>
<li>
<capacity>BloodPumping</capacity>
<weight>0.5</weight>
</li>
</capacityFactors>
</StatDef>
 
</Defs>


HarmonyPatches.cs
using System;
using System.Reflection;
using Harmony;
using RimWorld;
using Verse;

namespace MonsterMash
{
    [StaticConstructorOnStartup]
    class Main
    {
        static Main()
        {
            var harmony = HarmonyInstance.Create("com.mash.monster");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }
    }

    [HarmonyPatch(typeof(HediffSet), "CalculateBleedRate")]
    static class bleedRatePatch
    {
        public static void bleedRatePostfix(ref float __result, HediffSet __instance)
        {
            __result *= StatExtension.GetStatValue(__instance.pawn, StatDef.Named("BleedRate"), true);
        }
    }

    [HarmonyPatch(typeof(CompArt), "JustCreatedBy", new Type[] { typeof(Pawn) })]
    static class artNamePatch
    {
        public static bool checkNamePrefix(ref Pawn pawn)
        {
            Log.Message("Checking for Pawn Name");
            bool result;
            if (pawn.Name == null)
            {
                Log.Message("No Pawn Name Found");
                Traverse.Create<CompArt>().Property("authorNameInt", null).SetValue("None");
                result = false;
            }
            else
            {
                Log.Message("Pawn Name Found");
                result = true;
            }
            return result;
        }
    }
}


Thank you all very much for your help.
#8
Help / Help with CompProperties_Art
March 08, 2018, 10:45:42 AM
I have created a new animal for my Monster Mash mod that, upon butchering, provides its shell as a statue.

Copying over the various required parts from the core statues and other buildings, I created what I hoped would be a working piece of art, and it sort of is.
The problem is that I need it to enjoyable as art, using the following code, but it shouldn't have a random name and description.

<comps>
<li Class="CompProperties_Art">
<canBeEnjoyedAsArt>true</canBeEnjoyedAsArt>
</li>
</comps>


Using this code creates several errors.

These include the following:
Upon first selecting the minified shell:
Inspect string for MinifiedSculpture14104 contains empty lines.

And upon trying to butcher the creature:
JobDriver threw exception in initAction. Pawn=Blue, Job=DoBill (Job_241) A=Thing_TableButcher14118 B=Thing_CarrionCrawler_Corpse14117 C=(75, 0, 73), Exception: System.NullReferenceException: Object reference not set to an instance of an object

Now, I think this is because the CompProperties_Art requires a nameMaker and descriptionMaker, which I don't want, but even when I do add them, it not only fails to generate them, but produces other errors. Furthermore, both with a without the name and description makers, the inspect tab for art fails to show up, even though I am calling it. I think this may be because it's empty, but I'm not sure.

Please help.

Here is the complete code for the item, in case it's of use:
<?xml version="1.0" encoding="utf-8" ?>

<Defs>

<ThingDef ParentName="BuildingBase">
<defName>MM_CarrionCrawlerShell</defName>
<label>carrion crawler shell</label>
<description>The calcium carbonate shell of a carrion crawler. The spiral pattern and earthy colors are quite beautiful.</description>
<thingClass>Building_Art</thingClass>
<graphicData>
<graphicClass>Graphic_Single</graphicClass>
<texPath>Things/Building/Art/CarrionCrawlerShell</texPath>
<drawRotated>false</drawRotated>
<allowFlip>false</allowFlip>
</graphicData>
<minifiedDef>MinifiedSculpture</minifiedDef>
<altitudeLayer>Building</altitudeLayer>
<passability>PassThroughOnly</passability>
<pathCost>70</pathCost>
<useHitPoints>true</useHitPoints>
<fillPercent>0.5</fillPercent>
<rotatable>false</rotatable>
<size>(1,1)</size>
<canOverlapZones>false</canOverlapZones>
<drawDamagedOverlay>false</drawDamagedOverlay>
<statBases>
<MaxHitPoints>200</MaxHitPoints>
<WorkToBuild>20000</WorkToBuild>
<Flammability>0</Flammability>
<Beauty>340</Beauty>
<Mass>100</Mass>
<SellPriceFactor>1.10</SellPriceFactor>
</statBases>
<comps>
<li Class="CompProperties_Art">
<canBeEnjoyedAsArt>true</canBeEnjoyedAsArt>
</li>
</comps>
<selectable>true</selectable>
<costList>
<Gold>50</Gold>
</costList>
<leaveResourcesWhenKilled>false</leaveResourcesWhenKilled>
<inspectorTabs>
  <li>ITab_Art</li>
</inspectorTabs>
<forceDebugSpawnable>true</forceDebugSpawnable>
<building>
<expandHomeArea>false</expandHomeArea>
<repairable>false</repairable>
<isInert>true</isInert>
</building>
    </ThingDef>

</Defs>
#9
Help / Bleeding Rate Multiplier (C#) (Solved)
February 11, 2018, 06:10:10 PM
I'm trying to create a venom for my newest monster for my Monster Mash mod that acts as an anticoagulant (increases bleeding rate).

To do that I need to create a HediffDef that modifies the bleedingRateMultiplier, which is set as 1f in the game's code (BodyPartDef, line 95).
// Token: 0x04002469 RID: 9321
public float bleedingRateMultiplier = 1f;


By expanding my limited assembly, is it possible to implement a bleedingRateMultiplier that is defined by the creature, default of 1, and add a HediffDef stage to allow a HediffDef to modify it?

If yes, how hard is it likely to be and what would be required (this is my first mod)?

Thanks.
#10
Help / Custom Event (SOLVED)
February 09, 2018, 10:03:30 AM
I have been looking into creating a custom event for my new Monster Mash mod and could do with some help/advice.
Most of the information I was able to find on building events dated back to alphas 3 and 4!

As far as I know, I have my C# project set up correctly, and, using dnSpy, I have copied over the event code for the Rare Thrumbo event.

The event I'm trying to create is called a "Monster Sighting" and will randomly spawn a small group of one of the monster species that my mod adds (currently only two). These monsters will hang around for a few days and then leave, allowing them to be interacted with outside of their normal biomes.

This works exactly like the Rare Thrumbo event, except that I need the event to randomly pick one species from a list.
I'm very much a novice in C# and haven't done anything with it in years, so I'm understandably stuck.

I need to create the list, populate the list with my monsters and create a system to randomly pick one species and spawn them in.
How would I do that?
How do I reference the xml-defined creatures?

Also, if I just substitute that selection system into a duplicate of the Rare Thrumbo event, will that work, or is there more that I will need to learn and do?

Thank you for your help.
#11
xml-Only Dynamic Definitions
What are dynamic definitions and why should I (the reader) care?
Currently, using ModCheck and the xpath operations that it provides and expands upon, it is possible to perform simple patches to a mod's definitions at run-time, in response to the presence or absence of certain other mods.

Elements of this conversation will be easier to explain using an example. This example will be persistent throughout this guide:
Let's say that you have made a mod that adds a new fruit to RimWorld and that you want it to be compatible with a wildly popular mod that adds Jam.
This hypothetical Jam mod adds a new workstation, a recipe to turn each fruit (there are only three in vanilla RimWorld) into its very own jam, and one additional recipe for mixed-fruit jam.

Using normal patching techniques, it is fairly easy to detect the Jam mod and add your fruit to the list of allowed ingredients for the mixed jam.

This guide is for an advanced and experimental mod-patching method. There are many good guides and decent examples of patches using ModCheck already available.

The limitations with standard patching don't start to emerge until you try to add a recipe for the jam made from your own fruit.
You might first encounter the issue that you can't patch in root definitions, such as a RecipeDef, from scratch. A targetable Def with an appropriate name is required first.
You might then try adding a the RecipeDef (to make the jam) and ThingDef (to have the jam item) to your own mod, that uses the Jam mod's baseJam definition.

This is all very well and good until you then run a test without the Jam mod installed and find that your new definitions are throwing up cross-referencing errors, such as: Cannot find ParentName.

This error occurs because the Parent is a file from another mod, one which isn't currently installed. Many modders may be tempted to copy its base definitions into their own mod (which is very bad practice and hasn't been required since a16), or to create their own version of the parent (which is also bad practice).
While this might solve the immediate problem, the game still won't be able to cross reference the workstation that is supposed to receive the recipeDef or find the graphic that is added by the Jam mod.

This is where "dynamic definitions" come in.
What I mean by a dynamic definition, is a definition that is selectively edited down to remove all cross-referencing issues with other mods and then patched at run-time to a working state only when the other mod is detected.

How to Make a Dynamic Definition
First off, a word of warning: Working with dynamic definitions is by no means a trivial task, requiring more work than creating a compatibility sub-mod. There are a number of unknown behaviors, mechanisms and errors at play, which are all solvable, that I will attempt to explain and justify as we work through this guide.

Your first Dynamic Definition
The first step is to create the definition, exactly as you normally would and assuming that the Jam mod (or other compatibility target) is installed.
It might look something like this:
<RecipeDef ParentName="makeJamBase">
<defName>makeBlackberryJam</defName>
<label>make blackberry jam</label>
<description>Make a delicious blackberry jam.</description>
<jobString>Making delicious blackberry jam.</jobString>
<ingredients>
<li>
<filter>
<thingDefs>
<li>blackberry</li>
</thingDefs>
</filter>
<count>25</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>blackberry</li>
</thingDefs>
</fixedIngredientFilter>
<products>
<BlackberryJam>1</BlackberryJam>
</products>
<skillRequirements>
<Cooking>5</Cooking>
</skillRequirements>
<workSkill>Cooking</workSkill>
</RecipeDef>


If you tried to run your mod at this stage, it would cause several errors. makeJamBase is from a mod that isn't necessarily installed and we haven't made the item BlackberryJam yet (We will ignore this error in this guide, since you should be able to comment it out for testing and create the ThingDef for BlackberryJam).

To prevent the recipe from causing errors, you will need to remove the ParentName attribute (don't forget what the parent should be! You will need it soon). This will lead to the RecipeDef being incomplete, since it is no longer inheriting properties from its parent.

The game already has a method for handling incomplete data, but it is primarily used for the base definitions themselves; Abstract = "True"

Abstract = "True"
Abstract definitions are a bit of a special case. These definitions are loaded while the game is loading, but they are not error-checked nearly as rigorously, they do not need to be complete and, most importantly of all, they are discarded when loading completes.

Once the game is loaded, that definition essentially doesn't exist within the game.
You won't get errors from it, unless the error is passed on to its children, you won't be able to use it and you won't find it in the developer-mode tools.

This is key to the implementation of Dynamic Definitions.
If the Jam Mod isn't installed, the BlackberryJam simply doesn't exist.

At this stage, your RecipeDef would look like this:
<RecipeDef Abstract="True">
<defName>makeBlackberryJam</defName>
<label>make blackberry jam</label>
<description>Make a delicious blackberry jam.</description>
<jobString>Making delicious blackberry jam.</jobString>
<ingredients>
<li>
<filter>
<thingDefs>
<li>blackberry</li>
</thingDefs>
</filter>
<count>25</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>blackberry</li>
</thingDefs>
</fixedIngredientFilter>
<!--<products>
<BlackberryJam>1</BlackberryJam>
</products>-->
<skillRequirements>
<Cooking>5</Cooking>
</skillRequirements>
<workSkill>Cooking</workSkill>
</RecipeDef>


The Patch
I'm assuming here that you have followed other people's guides and already know how to patch.
If this is not the case, there are several good resources, including A quick tutorial of xpathing and patching and [A17] A warning to modders: xpath performance, which are both pinned at the top of the Help sub-section of the modding forum, and Introduction to PatchOperation by Zhentar.

Any mod-dependent patch should contain a basic test to make sure that the target mod is installed and is above this one in the loading order. The opening section of a patch file usually looks something like this:
<?xml version="1.0" encoding="utf-8" ?>

<Patch>

<Operation Class="PatchOperationSequence">
<success>Always</success>
<operations>
<!-- Continue if Yummy Jams exists -->
<li Class="ModCheck.isModLoaded">
<modName>Yummy Jams</modName>
<yourMod>Blackberry Bonanza</yourMod>
<customMessageSuccess>Blackberry Bonanza :: Yummy Jams detected: Patching...</customMessageSuccess>
</li>

<li Class="ModCheck.loadOrder">
<modName>Yummy Jams</modName>
<yourMod>Blackberry Bonanza</yourMod>
<errorOnFail>true</errorOnFail>
</li>


There are several things here that need explaining:
Quote<success>Always</success>
In a PatchOperationSequence, it will usually run until there is an error, report it, and then stop. That would be if <success>Normal</success> was used. However, when set to <success>Normal</success>, errors are logged that don't appear to do any harm or prevent the patch from working and the PatchOperationSequence is stopped unnecessarily.
This is why most mod patches unquestioningly use <success>Always</success>.

Quote<customMessageSuccess>Blackberry Bonanza :: Yummy Jams detected: Patching...</customMessageSuccess>
ModCheck.isModLoaded is used to test if the required mod is installed, but it also allows you to send a custom message to the Debug Log.
It can be very useful to add duplicates, each with different custom messages, for testing purposes. If the message doesn't reach the Debug Log, then you know that there is a serious error between the last message that was sent and the one that wasn't sent.
Be aware though, that these messages do not appear in the Debug Log in the order that they are written in the patch. Check carefully.
There may be a solution for this (Combat Extended seems to have a strict message order), but I do not know what it is.

Next, we create two sub-sequences.

Wait, but can't it be done in a single sequence?
Well, the answer to that is "Sometimes".
In some patches and in some combinations it seems to work just fine, but at other times it will fail if there are different PatchOperations in the same sequence. The behavior appears highly inconsistent, so its best to make sure that each PatchOperationSequence only contains one type of PatchOperation.
The primary PatchOperationSequence, the one that spans the entire page, is therefore a sequence of PatchOperationSequence(s), and each sub-sequence handles a specific task.

So, back to our two sub-sequences.
The 1st sub-sequence is there to add the ParentName attribute back in to our definitions, and will look like this:
<li Class="PatchOperationSequence">
<success>Always</success>
<operations>
<li Class="PatchOperationAttributeAdd">
<xpath>Defs/RecipeDef[defName = "makeBlackberryJam"]</xpath>
<attribute>ParentName</attribute>
<value>makeJamBase</value>
</li>
</operations>
</li>


The 2nd sub-sequence then removes the Abstract="True" attribute from the definition, allowing it to be loaded into the game, and will look like this:
<li Class="PatchOperationSequence">
<success>Always</success>
<operations>
<li Class="PatchOperationAttributeRemove">
<xpath>Defs/RecipeDef[defName = "makeBlackberryJam"]</xpath>
<attribute>Abstract</attribute>
</li>
</operations>
</li>


We remove the Abstract attribute after defining the ParentName to avoid receiving errors from the error-check that is performed on a non-abstract definition as a result of the definition still being incomplete
When removing the Abstract attribute, it is important to select the definitions specifically. If you have created your own base definition in that file, it should remain Abstract, otherwise it will cause you a whole new set of errors.

Repetition, repetition, repetition...
From this point forward, you test, develop the remaining required definitions, the patches for them and re-test.
Make sure to un-comment any incomplete cross-references as you complete the definitions, since we still have BlackberryJam as the product commented-out in our example.

Closing Information and Notes
You will also, the exact reasons are unknown, but I believe that it is related to the order by which PatchOperations are performed, occasionally get a persistent cross-reference error with regards to one of your other dynamic definitions. In the case of our example, the ThingDef for BlackberryJam would be a likely error-point.
When that happens, remove the offending reference from the definition and patch them back into the definition using a final PatchOperation sub-sequence at the bottom of your Patch.
It might look like this:
<li Class="PatchOperationSequence">
<success>Always</success>
<operations>
<li Class="PatchOperationAdd">
<xpath>Defs/RecipeDefDef[defName = "makeBlackberryJam"]</xpath>
<value>
<products>
<BlackberryJam>1</BlackberryJam>
</products>
</value>
</li>
</operations>
</li>


Some additional unknowns are associated with the order of file-patching.
The custom messages sent to the Debug Log from different mods do not necessarily appear in the order that the mods are loaded (listed in the mod menu, top-bottom) and sometimes messages from other patch files within your own mod will appear in-between message that are half-way through an ongoing sequence.
While this could be a result of the message order only, it may also be that different patches from mods, different files or possibly even different sequences are performed out of order in some way.

To avoid this unknown operation order from impacting your dynamic definitions, they should all be patched inside of the Primary PathOperationSequence and all in the same file.

Further xpath resources available to you include online xpath checkers and xpath plugins for popular text editors such as Notepad++ and SublimeText.
You can also use my Monster Mash mod as an example framework (Steam Workshop) (Forum). It is the mod that I, ilikegoodfood, along with significant time and assistance from wwWraith, developed this patching system for and it uses the system to dynamically implement new artificial animal organs and prosthetics for A Dog Said... compatibility with my Land Kraken.
If you do you use this system, a reference would be highly appreciated, but it is not necessary.
#12
Help / New Damage Deff (Solved)
February 03, 2018, 01:35:55 PM
I have been trying to finalize the vanilla properties for a new creature I'm creating.
The creature has a powerful venom in its Bite attack, so I have gone through all of the, as far as I can find, required XMLs and made my own to add the appropriate fields. The game is no longer providing any errors, but the creature won't use the attack either.

I made a new Damage Def, using "Bite" as the parent, that applies the poison to the target, just like Toxic Bite does, created a new hediff for the poison, added a Tool Capacity so that the creature could reference the attack and a maneuver for it to use and log the attack.

Are there any XMLs that I am missing, or does this require C# and an assembly?

Thank you for your help.

EDIT: Stupid me, the error wasn't that it didn't use the attack, but that it only uses it rarely, and my test colonists are dying too quickly.
I just ran it though a whole bunch of one-on-one battles and it did eventually use it.
I'm locking this thread, if I can, so as to prevent people trying to fix what is already fixed.
#13
Help / BodyPartDef Tags
February 01, 2018, 05:33:43 PM
I am planning on creating a new body type for my new Monster Mash mod, which also needs some new bodyparts, but have a question about the Tags connected to the BodyPartDefs.

Tags like Eating Source, Talking Source and ManipulationLimbCore make enough sense to me, and it is fairly clear that I'll need them, but there are some others that may be optional, depending on the body parts, such as the Breathing Pathway, Eating Pathway and Talking Pathway.

Are these always needed, or are they only needed to connect the lungs and stomach to the head?
Would a creature without a neck still need them?

What is the minimum list of tags that the body-plan must contain in order to have all working options?
And if anyone knows, where are the tags defined or explained?

Thank you for the help.
#14
Monster Mash


Description:
The RimWorlds contain a broad variety of Earthly and artificial animals, ranging from tiny squirrels to the extinct megasloth (megatherium), from chemically useful boomalopes to rogue bioweapons.
Yet, here in the lawless Rim, far beyond the reach of the shining cities and ethics review boards of the GlitterWorlds, many a mad scientist or budding entrepreneur has attempted to establish themselves as a new giant in the field of genetic manipulation. Regardless of how well their creations were received in the journals back home, the beasts they forged still roam, wild and untamed, in the wildernesses of the RimWorlds.

This mod aims to implement a (hopefully) large number of interesting, dangerous and exotic creatures to the game; some serious, some fanciful.

Currently implemented:
Carrion Crawler - A huge land snail that roams the arid shrublands in an unending quest for prey. This acid spitting, flesh eating beast is a beautiful native creature of some RimWorld's. It's shell makes for a fine furnishing to any room.

Inferno Beetle - A giant dendrevour (tree eater) that converts timber into chemfuel. Originally developed as a means of industrial espionage in the timber industry, the creature was abandoned due to its powerful flaming spit.

Land Kraken - A small, soft bodied, and lethal predator. Reasonably easy to kill but extremely dangerous in melee combat, the land kraken is armed with eight bladed tentacles and a poisonous bite. It sprays a cloud of ink to defend itself when shot.

Polar Colossus - An immense bear-like cyborg, the result of illegal experimentation with Mechanoid technologies. This monstrous beast is armed with an integrated power-core and thermal lance assembly. This assembly can be sergically extracted and transfered to human colonists, providing significant bonuses.

Sanguine Drake - A large predatory lizard developed for military operations on arid and desert-like worlds. Tough to kill, ride-able (with Giddy-Up!), capable of transporting goods and a fierce fighter, they far surpass camels or horses. In addition to their formidable capabilities, they are able to fire blood from the capillaries around their eyes at ballistic speeds, inflicting a powerful anti-coagulant venom, both from the blood-spray and their bite.

Other Features:
Full prosthetics suite for the Land Kraken while A Dog Said... is installed.
Monster Sighting (Event) - A random event that spawns a small number on Monsters on your colony map, regardless of normal biome-locking. They'll hang around for a few days and then leave again.
Thermal Core (Building) - The thermal core of a polar colossus, modified and mounted into an external casing. This structure functions as a powerful heating unit, but it dies after a quadrum of use.
Thermal Lance Assembly - The thermal Lance Assembly is a set of three archo-tech equivelent prosthetic parts that can occasionally be purchased from tarders, or harvested sergically form the Polar Colossus. All three provide significant bonuses in their own right, and when all are installed on a paw. the pawn gains full use of the Thermal Lance Assembly, granting them a ranged attack option (scales according to body size). The parts are:
Thermal Core: Comfotable Temperature Min - 40, Max -10 (results on a human is a comfortable temperature range of -24 to +16)
Optical Firing Assembly: +2 Accuracy and Aiming Time reduced by 10%.
Thermal Lance Firing Assembly: Provides a powerful bite attack that does both bite and burn damage.

In Progress:
Due to circumstances i will not discuss, I am taking a long break from RimWorld modding. I still have so much I would like to do with this mod in the future, but that may be delayed indefinitely. I'll let you all when I resume.

Installation and Compatibility:
This mod is Dependant on the Verb Expansion Framework (Steam Workshop) (Forum). Make sure that you have downloaded the latest version of VEF and placed it in the load order before MonsterMash.
This mod automatically detects and adjusts for the presence of the following other mods:
A Dog Said... (Steam Workshop) (Forum)
Giddy Up (Steam Workshop) (Forum)

Monster Mash should be loaded after all of the mods that it depends on. So, if you have A Dog Said... installed, the load order for those mods should be Core, Verb Expansion Framework, A Dog Said..., Monster Mash.
It should be safe to add this mod to existing save files, but changing mods mid game is always risky.
In theory, if no pawn, component, or resource from this mod is anywhere on your map, it should be possible to remove it from an active game, but I wouldn't recommend risking it.

Downloads:
For RimWorld 1.0
SteamWorkshop
DirectDownload (Dropbox)

For RimWorld B19 (Final Version)
Direct Download (Dropbox)
Steam Workshop

For RimWorld B18 (Final Version)
Direct Download (Dropbox)
Steam Workshop

This mod is intended to work alongside such great mods as the Animal Collab Project (Steam Workshop) (Forum) and the Megafauna mod (Steam Workshop) (Forum). Similarity in creatures should be minimal.
B18 also has combatibility for Combat Extended. Versions after B18 do not, nor will likely ever have CE compatibility.

Bugs and Localizations:
German: Monster Mash has been generously translated to German by Trunken.
Due to limitations in RimWorld core, the translations for the conditional A Dog Said prosthetics cannot be released yet. I'm working on a solution.

Please report any bugs that you find to me, so that I may try and solve them. When reporting a bug, please provide the error log and mod list.
I only speak English, so I cannot make localizations for other languages. If you know how and speak those languages, please feel free to create localizations and I can incorporate them into the core mod (Credits will be given).

Credits
A Dog Said... Animal Surgery (Steam Workshop) (Forum), created and maintained by spoonshortage. A mod that provides Animal Prosthetics and operations systems. Some A Dog Said... definitions are used in my mod for compatibility purposes.
Megafauna (Steam Workshop) (Forum), created and maintained by Spino. A fantastic animal addition mod that acted both as the inspiration for my mod and an excellent template from which to learn.
Verb Expansion Framework (Steam Workshop) (Forum), created by myself. A brand new framework designed to facilitate the various new features that I wish to implement in this mod.

License:
If you're a modpack maker and want to include Monster Mash or if you are a modder and want to use it as the basis of a derivative or similar mod, please feel free to do so. I only ask that you let me know about it and credit me where appropriate.
#15
Help / Monsters Mod - New to Modding
January 30, 2018, 08:44:45 AM
I have long wanted to make a mod for RimWorld, but have struggled to decide what to make.
I have recently decided to and started to make a mod called Monster Mash, with the aim to add a number of exotic and dangerous creatures to RimWorld.

I've been searching around in tutorials and on the forums to determine exactly what it is I need in order to make the mod and to make it compatible with other mods (I know, that can mostly be left for later).

So far, I have a copy of the Megascarab, which I am converting into the Inferno Beetle, a large fire-breathing insect that eats trees and can be milked for chemfuel.
I'm trying to work out what all of the various files and other bits and pieces that I'll need to make it work. So far, I think I need the following:

  • Races_Animal_Insect - currently what I'm working in/on.
  • a definition for its Egg
  • the animal range unlocker mod (LINK). I have created an Assemblies folder and transfered the AnimalRangeUnlocker.dll and Harmony library dll, but don't yet know how to use them.
  • the ModCheck for compatibility (LINK) - I have it in, but will get to that later.
  • Core graphics and sound collection for reference. - Got.

So:
Is there anything else that I'm going to need that I have missed?
Does anyone here know how to define a ranged creature tool using Animal Range Unlocker?
What key steps will I always need to go through to consistently create an animal?

That you all for humoring and helping a new modder.