Jump to content

Recommended Posts

Posted

I'm making a mod to display how long an animal has been pregnant for in the infobox. I have the display part working fine, but my code uses the wrong variable. I believe I need to use the entity's PregnancyDays attribute, which is gotten within EntityBehaviorMultiply (which I'm patching). However, VS gives me the error "'EntityBehaviorMultiply' does not contain a definition for 'PregnancyDays' and no accessible extension method 'PregnancyDays' accepting a first argument of type 'EntityBehaviorMultiply' could be found".

I'm confused because I could use __instance.TotalDaysPregnancyStart just fine, but I can't use __instance.PregnancyDays. The only difference I see is that TotalDaysPregnancyStart has a get and a set, but PregnancyDays only has a get? I don't understand how that might matter, though.

Code:

static void Postfix(EntityBehaviorMultiply __instance, StringBuilder infotext)
{
    if (__instance.IsPregnant)
    {
        infotext.AppendLine(Lang.Get("Pregnant for " + __instance.PregnancyDays + " days", Array.Empty<object>()));
        return;
    }

Using ___PregnancyDays gives the same error, as does __instance.typeAttributes["pregnancyDays"].

This is my first code mod and my first time using Harmony, so I may be overlooking something basic. All help is appreciated.

Posted (edited)

Could it be because PregnancyDays is marked as internal where TotalDays is public? You can access internal and private things usually by asking Harmony for them as arguments, with three underscores before the name.

static void Postfix(EntityBehaviorMultiply __instance, StringBuilder infotext, float ___PregnancyDays)

From https://harmony.pardeike.net/articles/patching-injections.html

Edited by Diff
Posted

This worked to remove the errors in VS; however, it's now causing a hard freeze during world loading that prevents me from closing the game.

I believe this is the relevant exception:

Exception thrown: 'HarmonyLib.HarmonyException' in 0Harmony.dll
An exception of type 'HarmonyLib.HarmonyException' occurred in 0Harmony.dll but was not handled in user code
Patching exception in method virtual System.Void Vintagestory.GameContent.EntityBehaviorMultiply::GetInfoText(System.Text.StringBuilder infotext)

HarmonyLib.HarmonyException
  HResult=0x80131500
  Message=Patching exception in method virtual System.Void Vintagestory.GameContent.EntityBehaviorMultiply::GetInfoText(System.Text.StringBuilder infotext)
  Source=0Harmony
  StackTrace:
   at HarmonyLib.PatchClassProcessor.ReportException(Exception exception, MethodBase original)
   at HarmonyLib.PatchClassProcessor.Patch()
   at HarmonyLib.Harmony.<PatchAll>b__10_0(Type type)
   at HarmonyLib.CollectionExtensions.Do[T](IEnumerable`1 sequence, Action`1 action)
   at HarmonyLib.Harmony.PatchAll(Assembly assembly)
   at HarmonyLib.Harmony.PatchAll()
   at PrecisePregnancyTimers.PrecisePregnancyTimersModSystem.Start(ICoreAPI api) in C:\Users\flish\source\repos\PrecisePregnancyTimers\PrecisePregnancyTimers\PrecisePregnancyTimers\PrecisePregnancyTimersModSystem.cs:line 20
   at Vintagestory.Common.ModLoader.TryRunModPhase(Mod mod, ModSystem system, ICoreAPI api, ModRunPhase phase)

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
ArgumentException: No such field defined in class Vintagestory.GameContent.EntityBehaviorMultiply, VSEssentials, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null (Parameter 'PregnancyDays')

I think I understand what the exception is saying, but I don't understand why it's occuring.

Posted

Odd that it's freaking out that way. Usually when my Harmony patches fail the mod errors out and the rest of the game continues on as normal.

Maybe because it's a getter? I'm not super familiar with all of C#'s treachery, but I think getters get turned into something like a "get_PregnancyDays" method behind the scenes, so it might be saying that because there is no field named PregnancyDays, just a method named get_PregnancyDays. Maybe you could do the same thing it does and grab typeAttributes["pregnancyDays"].AsFloat(3f)? Or you could bite the bullet and do some reflection to get at PregnancyDays. I know Harmony has some handy utility functions that make reflection slightly less painful.

Posted (edited)
21 hours ago, purrpetualentropy said:

I'm making a mod to display how long an animal has been pregnant for in the infobox. I have the display part working fine, but my code uses the wrong variable. I believe I need to use the entity's PregnancyDays attribute, which is gotten within EntityBehaviorMultiply (which I'm patching). However, VS gives me the error "'EntityBehaviorMultiply' does not contain a definition for 'PregnancyDays' and no accessible extension method 'PregnancyDays' accepting a first argument of type 'EntityBehaviorMultiply' could be found".

I'm confused because I could use __instance.TotalDaysPregnancyStart just fine, but I can't use __instance.PregnancyDays. The only difference I see is that TotalDaysPregnancyStart has a get and a set, but PregnancyDays only has a get? I don't understand how that might matter, though.

Code:

static void Postfix(EntityBehaviorMultiply __instance, StringBuilder infotext)
{
    if (__instance.IsPregnant)
    {
        infotext.AppendLine(Lang.Get("Pregnant for " + __instance.PregnancyDays + " days", Array.Empty<object>()));
        return;
    }

Using ___PregnancyDays gives the same error, as does __instance.typeAttributes["pregnancyDays"].

This is my first code mod and my first time using Harmony, so I may be overlooking something basic. All help is appreciated.

As @Diff said, it's not an actual field but just a getter/setter method hence you cannot accept it using `___fieldname` as this is only a thing for fields. You'd have to either accept `___typeAttributes` and interface with it manually or use reflection:

var pregnancyDays = Traverse.Create(__instance).Property<float>("PregnancyDays").Value;

(I assume the utility method mentioned is referring to the `Traverse` class)
 

Edited by The Insanity God
  • Like 1
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.