Forum Announcement, Click Here to Read More From EA_Cade.

Why do injections work fine for some objects and weirdly (or not at all) for others?

TriplisTriplis Posts: 3,048 Member
edited March 5 in Nominated Threads
So common practice is to, when possible, inject new super affordances into objects when possible, as opposed to adding them manually (the latter having compatibility problems with other modders and possible changes to the object from Maxis down the road).

But what I don't understand is for some objects, there's just a central file you can inject to and that's it. For example, object_toddler_pottyChair. There are two different potty objects in-game, but only object_toddler_pottyChair shows up in the game files (that I've seen) and if you inject a new super affordance to it, it'll show up on both potty chairs.

Then there's stuff like bed. Bed has a file for single bed, a file for double bed, and files for the individual different beds themselves. If I inject to the single bed and/or double bed file, it doesn't show up at all. Presumably it'll show up if I inject to the individual bed files, but that means injecting to every single bed there is and that means a little forward compatibility problems, as if new beds get added, you now have to take them into account. And I'm not sure about it possibly causing problems if you attempt to inject to an object id that doesn't exist... might throw an error, so if that's the case, you'd need to make a different script for each combinations of packs that involve beds (living nightmare).

Does anyone know a way to get around this problem?

I'd also like to understand, for the sheer curiosity of it, why it is that some objects operate differently in this way. The potty chair did come later, so maybe the practice was changed down the line? Or there's something different about it that removes the need for a unique object XML file for each different chair?
Mods moved from MTS, now hosted at: https://triplis.github.io
Post edited by EA_Cade on

Comments

  • TURBODRIVERTURBODRIVER Posts: 68 Member
    A lot of tuning files for objects exist in the game as "templates". They can be used as a functional tuning file, but you most likely want to give them more specific functions, so you copy that general file and change it. That's the case for beds, even if some might not have any differences.

    There is no point to make tuning files for each separate object if they do the same exact thing. That's the case for the potty chair.

    Injecting for specific objects is bad and you should not do it unless you really just want it for specific objects. You want to use tags.
    This is an example from my special affordance injector: https://pastebin.com/r5AVKm8F
    This example adds affordances to all mirrors in the game, even the CC ones (if they are tagged right, which they should be). You can do that with most objects in the game.

    You can find all of the tags in the game in this XML file: S4_03B33DDF_00000000_D89CB9186B79ACB7_tag.xml

    My affordance injector is not yet public if you're interested in that. Eventually, I will release a bunch of utilities to make scripting Sims 4 easy.
  • TriplisTriplis Posts: 3,048 Member
    Hey, thanks @TURBODRIVER

    I take it the code from the pastebin is only part of the injector?

    I would love to get my hands on the full thing, if you're willing to share it (as long as I have all the parts necessary, I can probably figure out on my own how to adapt it to what I need it to do... in other words, I'm not asking for you to make a tutorial, which I imagine is the more time-consuming aspect of considerations for sharing your code?... I can probably manage without one in this case).

    Being able to inject to any type of object would greatly increase the possibilities of what kind of interactions I can make. Previously, I've pretty much been limited to sims themselves and the odd singular object.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • TURBODRIVERTURBODRIVER Posts: 68 Member
    You're seeing the "front-end" of it. Your job is only to pick what is being injected and where (including the ground, relationship panel, and phone).

    There is no way I would release it right now. I need to not only read more about developing professional APIs to fine-tune it looks, but I haven't ported my mod fully on to it yet. Behind the scenes, besides a utility to manage game resources, there is the known code for injecting into objects and such. You already have what is needed.

    The reason I sent you my code is to look at the "is_valid" function. It contains everything you need. Get object tags and then check if they have that tag. In my case, I made an Enum using Maxis interface (which works pretty much like in Python 3.4) to list all of the tags in the game, but you can just compare a raw number from the tags list I've mentioned before.

    My code doesn't make anything work by magic, it's just to make it clean and easy. :D
  • TriplisTriplis Posts: 3,048 Member
    @TURBODRIVER Oh ok, thanks. It's really late here and I'm very tired, but surprisingly, despite my brain feeling immensely dulled, I think I get the gist of what you're saying nonetheless.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • TriplisTriplis Posts: 3,048 Member
    edited August 2017
    Edit: On second thought, I may not need the injection to objects after all. More on this later, depending on where it goes.


    So I thought I was gonna grasp it, but there's something I'm missing the mark on here, no matter how I try to implement it. I'm having one of those days where I feel like a toddler attempting calculus.

    You mention the importance of the is_valid function as an example.

    What I'm missing the mark on is, how to actually check objects for the tag. There's at least one step I'm missing or misunderstanding in here somewhere.

    It seems like logically, the approach you're inferring in how the function is designed is that the function is made to be able to look at every object in the game, sees if it has the appropriate tag, and then if it does, you do some kind of "append super affordance" setup.

    I guess it gets the game objects from this part?
    if not TurboTypesUtil.Objects.is_game_object(script_object):
    
    But no, wait, that doesn't make sense. That's just validating it, right? I mean, the function parameter "script_object" implies feeding something into the function. But I don't see what you feed into it. Presumably game objects, which then get their tag checked. But how?


    Or maybe I'm completely misunderstanding this and the game objects don't need to be directly referenced at all. It just seems like logically, at some stage, it has to take input for a game object id, check what that game object's tags are, see if it matches, and then add the affordance to it if it matches the tag. But this seems really inefficient to me if it has to check every object in the game, so maybe I'm on the wrong tack.
    Post edited by Triplis on
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • TriplisTriplis Posts: 3,048 Member
    edited August 2017
    Edit3: Same thing worked for bed by putting in a posture_BedUndercovers constraint. So... issue resolved for now. I should pretty much be able to do what I was wanting to do when I made this thread. If I were wanting to add generic use interactions for any sim, that'd be another matter. But for the purpose of trait-based interactions, it's all coolio for now.

    Edit2: Well that's interesting. Just adding the following to the piano interaction fixed its issue.

    Which would seem to imply that if I'm adding custom interactions to objects, I can't rely on the animation constraints doing their job. Doesn't fully make sense, but it's progress!
    <L n="_constraints">
        <U>
          <L n="constraints">
            <U>
              <E n="key">HUMAN</E>
              <V n="value" t="posture">
                <U n="posture">
                  <L n="posture_manifest_tuning">
                    <U>
                      <V n="posture_type" t="enabled">
                        <T n="enabled">15535<!--Posture: posture_Sit--></T>
                      </V>
                    </U>
                  </L>
                </U>
              </V>
            </U>
          </L>
        </U>
      </L>
    

    Edit: Now I'm thinking maybe this is a problem that goes beyond the method of pushing it on the object. Just no idea how. What I do know is I tried it with a piano and ran into virtually the same issue:
    PianoPlayPractice: Virtual actors for sitTemplate do not include None
    So there's at least a common thing happening.

    The problem is, I recall having this problem in the past, even when I used a script injector to force an interaction on a single piano one time, just to see if I could get it to work at all. The only form of injecting I know how to do that I haven't tried is just straight up adding it to an XML file manually and using an override.

    I might have to try that, just to see if I can narrow this problem down more.

    Logically, it makes no sense with the information I have. All I'm doing is adding a new affordance to the list of affordances that the object has. Only thing I can think of at the moment that appeals to my sense of reason is if there's something more to object affordances than simply having them in a list (for some object types). This thought makes a kind of sense, as piano and bed both have _anim_overrides and telescope does not (will have to research on what those are exactly).

    Triplis wrote: »
    Edit: On second thought, I may not need the injection to objects after all. More on this later, depending on where it goes.
    So to follow up on what I meant by this...

    Someone reminded me of the functions in trait buffs, where you can add affordances specific to a trait, through super_affordances and target_super_affordances.

    I saw that and thought, maybe I can use target_super_affordances to make stuff appear on particular objects (since I'm primarily operating through traits right now anyway). The person was pointing out that you can specify by tags, which put me on the thought of objects through tag reference.

    So I used something like this in a trait buff:
    <L n="target_super_affordances">
        <U>
          <T n="affordance">13436945359271848694<!--SuperInteraction: My Interaction Name--></T>
          <V n="object_filter" t="filter_by_tags">
            <U n="filter_by_tags">
              <L n="tags">
                <E>Func_Bed</E>
              </L>
            </U>
          </V>
        </U>
    </L>
    

    Which sort of worked and sort of didn't.

    It worked for a telescope interaction just fine. The interaction showed up on the telescope and functioned the same as it was when I injected it.

    Had (and am still having) some problems with a bed interaction though. The interaction is mostly a carbon copy of Bed_Undercovers_Hide. I even tried a carbon copy of Bed_Undercovers_Hide to see if that would make a difference.

    It gives me the same ASM error every time when I try to use the interaction:
    Bed_Undercovers_InteractionIdle: Virtual actors for bedIKRef do not include None

    For some reason, it apparently thinks that the virtual actors for bedIKRef are none. Which I can only assume has something to do with the way the interaction is being pushed on the object because that's basically the only factor I haven't eliminated. Maybe target_super_affordances just isn't built to handle pushing interactions on objects that require a special posture change and the like. I'm also not sure about it's efficiency in loading... it may increase on_add load times, where injections can put most of the load pressure on startup. Not totally sure on that.

    Anyway, I'm digressing. And rambling. The point is, out of the frying pan and into the fire. One solution into another problem. Oh, modding...
    Post edited by Triplis on
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • TURBODRIVERTURBODRIVER Posts: 68 Member
    Well, I can't help you with animations, but from the error, it looks like you're mismatching data between the object and animation actors setup. Something that's expected is missing.

    For the injection, TurboTypesUtil is only to test for objects types, in this case, if it's a GameObject. It's the least important part.
    On your injection for ScriptObject/GameObject 'on_add', that injection will trigger for every loaded object. There you test for the tags. Look at the entire rest of the 'is_valid' function.

    I don't know how traits or buffs add affordences, but if it happens only once then it wouldn't be a performance issue.
  • TriplisTriplis Posts: 3,048 Member
    @TURBODRIVER Thanks for the insight!
    Mods moved from MTS, now hosted at: https://triplis.github.io

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file
Return to top