PDA

View Full Version : CachedAnonymousMethodDelegate5 ???


MDM
28th Jun 2012, 04:16 PM
Ok, I'm encountering a problem here, I'm trying to override WorkFromHome definition with my definition but ILSpy reports this :

[CompilerGenerated]
private static GreyedOutTooltipCallback <>9__CachedAnonymousMethodDelegate5;
protected override bool Test ........

The definition doesn't even have a GetInteractionName, in fact when I run the game with my mod, there is no Interaction Name and UntranslatedKey reports the empty string coming from the new interaction, of course.

I could create a new InteractionName to overcome this problem but I'd rather solve this apparent issue and do not touch the original InteractionName which is misteriously missing from my assemblies. I even reextracted it again from the gameplay.package but it's still there.

What's this all about?

Odistant
28th Jun 2012, 08:54 PM
Checked in in Reflector really quick. Is this what you're looking for?

public class Definition : InteractionDefinition<Sim, Computer, Computer.WorkFromHome>
{
// Methods
public override bool Test(Sim s, Computer c, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
{
Career occupationAsCareer = s.OccupationAsCareer;
if (((occupationAsCareer != null) && occupationAsCareer.WorkaholicInteractionLocked) && (c.IsComputerUsable(s, true, false, isAutonomous) && s.HasTrait((TraitNames) (0xb82d0015b9294690L))))
{
if (!occupationAsCareer.IsAllowedToWork())
{
return true;
}
greyedOutTooltipCallback = delegate {
return Computer.WorkFromHome.LocalizeString("Unavailable", new object[0x0]);
};
}
return false;
}
}

MDM
28th Jun 2012, 09:42 PM
Nope, Test is there, the problem is the InteractionName, there's no GetInteractionName in WorkFromHome so I assume that the delegate has a role in this and that's right above Test, the code I pasted, this is the complete Definition I see in ILSpy :

private sealed class Definition : InteractionDefinition<Sim, Computer, Computer.WorkFromHome>
{
[CompilerGenerated]
private static GreyedOutTooltipCallback <>9__CachedAnonymousMethodDelegate5;
protected override bool Test(Sim s, Computer c, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
{
Career occupationAsCareer = s.OccupationAsCareer;
if (occupationAsCareer == null || !occupationAsCareer.WorkaholicInteractionLocked)
{
return false;
}
if (!c.IsComputerUsable(s, true, false, isAutonomous) || !s.HasTrait(TraitNames.Workaholic))
{
return false;
}
if (occupationAsCareer.IsAllowedToWork())
{
greyedOutTooltipCallback = (() => Computer.WorkFromHome.LocalizeString("Unavailable", new object[0]));
return false;
}
return true;
}
}

The difference with yours is "delegate" but it should be the same as ()) =>, as far as I know. So I'm thinking that those first 2 lines before Test, have something to do with it...

EDIT :

Well, at least I found the reference for the interaction name, which is "Gameplay/Objects/Electronics/Computer/WorkFromHome:InteractionName".
Overriding GetInteractionName and returning the one from the base did not work, so I'm going to try making a new one that will return the localization from the string I found. It might solve it, I hope, but it still puzzles me what's going on here....

EDIT 2 : Nope, no luck, it's not working....I have no clue....the interaction works fine btw, it's just the name in the pie menu not showing, it keeps looking for it in my new definition, even with only Test in it, something's definitely not right here :(

nonamena
29th Jun 2012, 07:34 AM
As far as I know, there is not an easy way around anonymous delegates. I've had many a fight with them myself. You could rewrite the interaction, add it to the computer and use RemoveInteractions to hide EA's interaction.

MDM
29th Jun 2012, 11:22 AM
As far as I know, there is not an easy way around anonymous delegates. I've had many a fight with them myself. You could rewrite the interaction, add it to the computer and use RemoveInteractions to hide EA's interaction.

Aha, that's what they are then...I wonder why though, was an anonymous delegate necessary here? I was hoping for a way around but it's fine, I will recreate it, thanks for the tip :)

EDIT: Replacing it works like a charm ;)

Buzzler
2nd Jul 2012, 10:38 PM
MDM, EA uses an automagic to fetch the localized interaction name for InteractionDefinitions that don't have a GetInteractionName() method. It's based on the full class name of the definition, so obviously that doesn't work for custom interactions that are supposed to use EAxian strings. Just add your GetInteractionName method and use Localization.LocalizeString in there. You already have the localization key, so that should be simple enough.

The anonymous method call is unrelated. When you use an anonymous method call, the compiler will create an actual method. That's what the <>9__CachedAnonymousMethodDelegate5; stuff is for. Reflector and ILSpy recognize that and try to rebuild the code the coder actually wrote. Successfully in this case, as you won't see any of the [CompilerGenerated] stuff being used in the decompiled code. ;)

MDM
3rd Jul 2012, 12:38 AM
MDM, EA uses an automagic to fetch the localized interaction name for InteractionDefinitions that don't have a GetInteractionName() method. It's based on the full class name of the definition, so obviously that doesn't work for custom interactions that are supposed to use EAxian strings. Just add your GetInteractionName method and use Localization.LocalizeString in there. You already have the localization key, so that should be simple enough.

The anonymous method call is unrelated. When you use an anonymous method call, the compiler will create an actual method. That's what the <>9__CachedAnonymousMethodDelegate5; stuff is for. Reflector and ILSpy recognize that and try to rebuild the code the coder actually wrote. Successfully in this case, as you won't see any of the [CompilerGenerated] stuff being used in the decompiled code. ;)

I imagined it was something like that, still adding GetInteractionName() did not work. At first I tried with the classic "Public Override String", still no string ingame. So I thought, ok, maybe this cached thing makes it think that there's no GetInteractionName() in the base to start with, so I went with "Public New String" and still no luck.
As soon as I changed approach, instead of overriding the definition I removed EA interaction and added a "clone" of that one, the string was there at the first shot.
Maybe I did something wrong or maybe not, I kept it with the second approach anyway, it's just one interaction and it's not even big, so no big deal (it's the EveryoneWorkFromHome mod).

Thanks for the explanation, next time I encounter it I'll try more. I'll be doing the same thing I already did with no success, but with knowledge of what it is, which may look the same but to me it will be totally different ;)